-
Notifications
You must be signed in to change notification settings - Fork 158
feat(otelcollector): render OTel Collector #5106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,15 @@ type LogCollectorSpec struct { | |
| // EKSLogForwarderDeployment configures the EKSLogForwarderDeployment Deployment. | ||
| // +optional | ||
| EKSLogForwarderDeployment *EKSLogForwarderDeployment `json:"eksLogForwarderDeployment,omitempty"` | ||
|
|
||
| // OTelCollector configures the OpenTelemetry Collector for exporting logs | ||
| // and metrics via OTLP. Unlike AdditionalStores entries (S3, Syslog, | ||
| // Splunk), which point at external systems, the OTel Collector is | ||
| // operator-managed infrastructure (StatefulSet, ConfigMap, RBAC, certs) | ||
| // with its own lifecycle, so it lives at the top level rather than under | ||
| // AdditionalStores. | ||
| // +optional | ||
| OTelCollector *OTelCollectorSpec `json:"otelCollector,omitempty"` | ||
| } | ||
|
|
||
| type CollectProcessPathOption string | ||
|
|
@@ -260,6 +269,38 @@ type LogCollectorList struct { | |
| Items []LogCollector `json:"items"` | ||
| } | ||
|
|
||
| // OTelCollectorSpec defines the desired state of the OpenTelemetry Collector. | ||
| type OTelCollectorSpec struct { | ||
| // Logs configures which log types are exported via OTLP. | ||
| // +optional | ||
| Logs *OTelLogs `json:"logs,omitempty"` | ||
|
|
||
| // Metrics configures whether Calico component metrics are exported via OTLP. | ||
| // +optional | ||
| Metrics *OTelMetrics `json:"metrics,omitempty"` | ||
|
|
||
| // Exporters configures the OTLP export endpoints. | ||
| // +optional | ||
| Exporters []OTelExporter `json:"exporters,omitempty"` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude: A few kubebuilder-marker gaps on the new API surface, grouping them here:
|
||
|
|
||
| // OTelCollectorStatefulSet configures the OTel Collector StatefulSet. | ||
| // +optional | ||
| OTelCollectorStatefulSet *OTelCollectorStatefulSet `json:"openTelemetryCollectorStatefulSet,omitempty"` | ||
| } | ||
|
|
||
| func (s *OTelCollectorSpec) HasLogs() bool { | ||
| return s != nil && s.Logs != nil && len(s.Logs.Types) > 0 | ||
| } | ||
|
|
||
| func (s *OTelCollectorSpec) MetricsEnabled() bool { | ||
| return s != nil && s.Metrics != nil && s.Metrics.Enabled != nil && | ||
| *s.Metrics.Enabled == OTelMetricsEnable | ||
| } | ||
|
|
||
| func (s *OTelCollectorSpec) HasDataSources() bool { | ||
| return s.HasLogs() || s.MetricsEnabled() | ||
| } | ||
|
|
||
| func init() { | ||
| SchemeBuilder.Register(&LogCollector{}, &LogCollectorList{}) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| // Copyright (c) 2026 Tigera, Inc. All rights reserved. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package v1 | ||
|
|
||
| import ( | ||
| corev1 "k8s.io/api/core/v1" | ||
| ) | ||
|
|
||
| // OTelLogType represents the allowable log types for OTel export. | ||
| // +kubebuilder:validation:Enum=Audit;DNS;Flows | ||
| type OTelLogType string | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think my preference is to replace the naming convention of OTel with OpenTelemetry so that we don't rely on shorthand and have a bit better searchability, WDYT? |
||
|
|
||
| const ( | ||
| OTelAuditLog OTelLogType = "Audit" | ||
| OTelDNSLog OTelLogType = "DNS" | ||
| OTelFlowLog OTelLogType = "Flows" | ||
| ) | ||
|
|
||
| // OTelLogs configures log export. | ||
| type OTelLogs struct { | ||
| // Types specifies which log types to export. Supported values: Audit, DNS, Flows. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we only support these 3 types? |
||
| // +optional | ||
| Types []OTelLogType `json:"types,omitempty"` | ||
| } | ||
|
|
||
| // OTelMetricsEnabled is the option to enable or disable metrics export. | ||
| // +kubebuilder:validation:Enum=Enabled;Disabled | ||
| type OTelMetricsEnabled string | ||
|
|
||
| const ( | ||
| OTelMetricsEnable OTelMetricsEnabled = "Enabled" | ||
| OTelMetricsDisable OTelMetricsEnabled = "Disabled" | ||
| ) | ||
|
|
||
| // OTelMetrics configures metrics export. | ||
| type OTelMetrics struct { | ||
| // Enabled specifies whether to scrape and export Calico component metrics via OTLP. | ||
| // Default: Disabled | ||
| // +optional | ||
| Enabled *OTelMetricsEnabled `json:"enabled,omitempty"` | ||
| } | ||
|
|
||
| // OTelExporterProtocol specifies the OTLP transport protocol. | ||
| // +kubebuilder:validation:Enum=grpc;http | ||
| type OTelExporterProtocol string | ||
|
|
||
| const ( | ||
| OTelProtocolGRPC OTelExporterProtocol = "grpc" | ||
| OTelProtocolHTTP OTelExporterProtocol = "http" | ||
| ) | ||
|
|
||
| // OTelExporter defines an OTLP export endpoint. | ||
| type OTelExporter struct { | ||
| // Name is a unique identifier for this exporter. | ||
| Name string `json:"name"` | ||
|
|
||
| // Endpoint is the OTLP endpoint URL. | ||
| Endpoint string `json:"endpoint"` | ||
|
|
||
| // Protocol specifies the OTLP transport protocol. Default: grpc. | ||
| // +optional | ||
| // +kubebuilder:default=grpc | ||
| Protocol OTelExporterProtocol `json:"protocol,omitempty"` | ||
|
|
||
| // TLSInsecure disables TLS verification for this exporter. Only use for trusted in-cluster targets. | ||
| // Default: false | ||
| // +optional | ||
| TLSInsecure *bool `json:"tlsInsecure,omitempty"` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is our overall TLS strategy here? Do we need to support a destination that requires mTLS? Do we need to support a user having a custom CA? There is precedent for this in other components (e.g. syslog forwarding, guardian connection) |
||
| } | ||
|
|
||
| // OTelCollectorStatefulSet is the configuration for the OTel Collector StatefulSet. | ||
| type OTelCollectorStatefulSet struct { | ||
| // Metadata is a subset of a Kubernetes object's metadata that is added to the StatefulSet. | ||
| // +optional | ||
| Metadata *Metadata `json:"metadata,omitempty"` | ||
| // Spec is the specification of the OTel Collector StatefulSet. | ||
| // +optional | ||
| Spec *OTelCollectorStatefulSetSpec `json:"spec,omitempty"` | ||
| } | ||
|
|
||
| // OTelCollectorStatefulSetSpec defines configuration for the OTel Collector StatefulSet. | ||
| type OTelCollectorStatefulSetSpec struct { | ||
| // MinReadySeconds is the minimum number of seconds for which a newly created StatefulSet pod should | ||
| // be ready without any of its container crashing, for it to be considered available. | ||
| // If specified, this overrides any minReadySeconds value that may be set on the OTel Collector StatefulSet. | ||
| // If omitted, the OTel Collector StatefulSet will use its default value for minReadySeconds. | ||
| // +optional | ||
| // +kubebuilder:validation:Minimum=0 | ||
| // +kubebuilder:validation:Maximum=2147483647 | ||
| MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` | ||
|
|
||
| // Template describes the OTel Collector StatefulSet pod that will be created. | ||
| // +optional | ||
| Template *OTelCollectorStatefulSetPodTemplateSpec `json:"template,omitempty"` | ||
| } | ||
|
|
||
| // OTelCollectorStatefulSetPodTemplateSpec is the OTel Collector StatefulSet's PodTemplateSpec. | ||
| type OTelCollectorStatefulSetPodTemplateSpec struct { | ||
| // Metadata is a subset of a Kubernetes object's metadata that is added to the pod's metadata. | ||
| // +optional | ||
| Metadata *Metadata `json:"metadata,omitempty"` | ||
| // Spec is the OTel Collector StatefulSet's PodSpec. | ||
| // +optional | ||
| Spec *OTelCollectorStatefulSetPodSpec `json:"spec,omitempty"` | ||
| } | ||
|
|
||
| // OTelCollectorStatefulSetPodSpec is the OTel Collector StatefulSet's PodSpec. | ||
| type OTelCollectorStatefulSetPodSpec struct { | ||
| // Affinity is a group of affinity scheduling rules for the OTel Collector pods. | ||
| // +optional | ||
| Affinity *corev1.Affinity `json:"affinity"` | ||
| // Containers is a list of OTel Collector containers. | ||
| // If specified, this overrides the specified OTel Collector StatefulSet containers. | ||
| // If omitted, the OTel Collector StatefulSet will use its default values for its containers. | ||
| // +optional | ||
| Containers []OTelCollectorStatefulSetContainer `json:"containers,omitempty"` | ||
| // NodeSelector gives more control over the nodes where the OTel Collector pods will run on. | ||
| // +optional | ||
| NodeSelector map[string]string `json:"nodeSelector,omitempty"` | ||
| // TopologySpreadConstraints describes how a group of pods ought to spread across topology | ||
| // domains. Scheduler will schedule pods in a way which abides by the constraints. | ||
| // All topologySpreadConstraints are ANDed. | ||
| // +optional | ||
| TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` | ||
| // Tolerations is the OTel Collector pod's tolerations. | ||
| // If specified, this overrides any tolerations that may be set on the OTel Collector StatefulSet. | ||
| // If omitted, the OTel Collector StatefulSet will use its default value for tolerations. | ||
| // +optional | ||
| Tolerations []corev1.Toleration `json:"tolerations"` | ||
| // PriorityClassName allows to specify a PriorityClass resource to be used. | ||
| // +optional | ||
| PriorityClassName string `json:"priorityClassName,omitempty"` | ||
| } | ||
|
|
||
| // OTelCollectorStatefulSetContainer is an OTel Collector StatefulSet container. | ||
| type OTelCollectorStatefulSetContainer struct { | ||
| // Name is an enum which identifies the OTel Collector StatefulSet container by name. | ||
| // Supported values are: otel-collector | ||
| // +kubebuilder:validation:Enum=otel-collector | ||
| Name string `json:"name"` | ||
|
|
||
| // Resources allows customization of limits and requests for compute resources such as cpu and memory. | ||
| // If specified, this overrides the named OTel Collector StatefulSet container's resources. | ||
| // If omitted, the OTel Collector StatefulSet will use its default value for this container's resources. | ||
| // +optional | ||
| Resources *corev1.ResourceRequirements `json:"resources,omitempty"` | ||
|
|
||
| // ReadinessProbe allows customization of the readiness probe timing parameters. | ||
| // The probe handler is set by the operator and cannot be overridden. | ||
| // +optional | ||
| ReadinessProbe *ProbeOverride `json:"readinessProbe,omitempty"` | ||
|
|
||
| // LivenessProbe allows customization of the liveness probe timing parameters. | ||
| // The probe handler is set by the operator and cannot be overridden. | ||
| // +optional | ||
| LivenessProbe *ProbeOverride `json:"livenessProbe,omitempty"` | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the naming here is a bit off. To me, it implies that this field is configuring the OTel Collector. With that framing, I would expect the config in this struct to match the standard OTel Collector config fields - which it doesn't.
To me this field is configuring OpenTelemetry export in Calico Enterprise/Cloud, which we of course translate into a deployment of an OTel Collector.
I would personally prefer a field/struct name like OpenTelemetry, and leave the comment to explain that it is used to configure OpenTelemetry export, which is powered by a deployment of the OTel Collector