Skip to content
Draft
9 changes: 9 additions & 0 deletions api/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,15 @@ type OtelCollectorFeatureConfig struct {
// OTelCollector Config Relevant to the Core agent
// +optional
CoreConfig *CoreConfig `json:"coreConfig,omitempty"`

// UseStandaloneImage configures the otel-agent container to use the standalone image.
// Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
// Requires agent version 7.67.0 or higher.
// If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
// Default: true
// +optional
// +kubebuilder:default=true
UseStandaloneImage *bool `json:"useStandaloneImage,omitempty"`
}

// CoreConfig exposes the otel collector configs relevant to the core agent.
Expand Down
5 changes: 5 additions & 0 deletions api/datadoghq/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions api/datadoghq/v2alpha1/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,15 @@ spec:
type: object
type: array
x-kubernetes-list-type: atomic
useStandaloneImage:
default: true
description: |-
UseStandaloneImage configures the otel-agent container to use the standalone image.
Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
Requires agent version 7.67.0 or higher.
If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
Default: true
type: boolean
type: object
otlp:
description: OTLP ingest configuration
Expand Down Expand Up @@ -9453,6 +9462,15 @@ spec:
type: object
type: array
x-kubernetes-list-type: atomic
useStandaloneImage:
default: true
description: |-
UseStandaloneImage configures the otel-agent container to use the standalone image.
Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
Requires agent version 7.67.0 or higher.
If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
Default: true
type: boolean
type: object
otlp:
description: OTLP ingest configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,11 @@
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useStandaloneImage": {
"default": true,
"description": "UseStandaloneImage configures the otel-agent container to use the standalone image.\nEnsure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.\nRequires agent version 7.67.0 or higher.\nIf false, the otel-agent container will use the `full` flavor of the datadog/agent image.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9246,6 +9251,11 @@
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useStandaloneImage": {
"default": true,
"description": "UseStandaloneImage configures the otel-agent container to use the standalone image.\nEnsure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.\nRequires agent version 7.67.0 or higher.\nIf false, the otel-agent container will use the `full` flavor of the datadog/agent image.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
9 changes: 9 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,15 @@ spec:
type: object
type: array
x-kubernetes-list-type: atomic
useStandaloneImage:
default: true
description: |-
UseStandaloneImage configures the otel-agent container to use the standalone image.
Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
Requires agent version 7.67.0 or higher.
If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
Default: true
type: boolean
type: object
otlp:
description: OTLP ingest configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,11 @@
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useStandaloneImage": {
"default": true,
"description": "UseStandaloneImage configures the otel-agent container to use the standalone image.\nEnsure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.\nRequires agent version 7.67.0 or higher.\nIf false, the otel-agent container will use the `full` flavor of the datadog/agent image.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
18 changes: 18 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,15 @@ spec:
type: object
type: array
x-kubernetes-list-type: atomic
useStandaloneImage:
default: true
description: |-
UseStandaloneImage configures the otel-agent container to use the standalone image.
Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
Requires agent version 7.67.0 or higher.
If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
Default: true
type: boolean
type: object
otlp:
description: OTLP ingest configuration
Expand Down Expand Up @@ -9503,6 +9512,15 @@ spec:
type: object
type: array
x-kubernetes-list-type: atomic
useStandaloneImage:
default: true
description: |-
UseStandaloneImage configures the otel-agent container to use the standalone image.
Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.
Requires agent version 7.67.0 or higher.
If false, the otel-agent container will use the `full` flavor of the datadog/agent image.
Default: true
type: boolean
type: object
otlp:
description: OTLP ingest configuration
Expand Down
10 changes: 10 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,11 @@
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useStandaloneImage": {
"default": true,
"description": "UseStandaloneImage configures the otel-agent container to use the standalone image.\nEnsure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.\nRequires agent version 7.67.0 or higher.\nIf false, the otel-agent container will use the `full` flavor of the datadog/agent image.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9311,6 +9316,11 @@
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"useStandaloneImage": {
"default": true,
"description": "UseStandaloneImage configures the otel-agent container to use the standalone image.\nEnsure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true.\nRequires agent version 7.67.0 or higher.\nIf false, the otel-agent container will use the `full` flavor of the datadog/agent image.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.v2alpha1.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ spec:
| features.otelCollector.coreConfig.extensionURL | Extension URL provides the URL of the ddflareextension to the core agent. |
| features.otelCollector.enabled | Enables the OTel Agent. Default: false |
| features.otelCollector.ports | Contains the ports for the otel-agent. Defaults: otel-grpc:4317 / otel-http:4318. Note: setting 4317 or 4318 manually is *only* supported if name match default names (otel-grpc, otel-http). If not, this will lead to a port conflict. This limitation will be lifted once annotations support is removed. |
| features.otelCollector.useStandaloneImage | UseStandaloneImage configures the otel-agent container to use the standalone image. Ensure you can pull the ddot-collector image (gcr.io/datadoghq/ddot-collector:7.67.0) if this is set to true. Requires agent version 7.67.0 or higher. If false, the otel-agent container will use the `full` flavor of the datadog/agent image. Default: true |
| features.otlp.receiver.protocols.grpc.enabled | Enable the OTLP/gRPC endpoint. Host port is enabled by default and can be disabled. |
| features.otlp.receiver.protocols.grpc.endpoint | For OTLP/gRPC. gRPC supports several naming schemes: https://github.com/grpc/grpc/blob/master/doc/naming.md The Datadog Operator supports only 'host:port' (usually `0.0.0.0:port`). Default: `0.0.0.0:4317`. |
| features.otlp.receiver.protocols.grpc.hostPortConfig.enabled | Enables host port configuration |
Expand Down
7 changes: 3 additions & 4 deletions internal/controller/datadogagent/component/agent/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,8 @@ func agentImage() string {
return images.GetLatestAgentImage()
}

func fullAgentImage() string {
return images.GetLatestAgentImageWithSuffix(false, false, true)

func ddotCollectorImage() string {
return images.GetLatestDdotCollectorImage()
}

func initContainers(dda metav1.Object, requiredContainers []apicommon.AgentContainerName) []corev1.Container {
Expand Down Expand Up @@ -438,7 +437,7 @@ func processAgentContainer(dda metav1.Object) corev1.Container {
func otelAgentContainer(_ metav1.Object) corev1.Container {
return corev1.Container{
Name: string(apicommon.OtelAgent),
Image: fullAgentImage(),
Image: ddotCollectorImage(),
Command: []string{
"otel-agent",
"--core-config=" + agentCustomConfigVolumePath,
Expand Down
98 changes: 80 additions & 18 deletions internal/controller/datadogagent/feature/otelcollector/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
"github.com/DataDog/datadog-operator/pkg/images"
"github.com/DataDog/datadog-operator/pkg/kubernetes"
"github.com/DataDog/datadog-operator/pkg/utils"
)

func init() {
Expand All @@ -41,11 +42,13 @@ func buildOtelCollectorFeature(options *feature.Options) feature.Feature {
}

type otelCollectorFeature struct {
customConfig *v2alpha1.CustomConfig
owner metav1.Object
configMapName string
ports []*corev1.ContainerPort
coreAgentConfig coreAgentConfig
customConfig *v2alpha1.CustomConfig
owner metav1.Object
configMapName string
ports []*corev1.ContainerPort
coreAgentConfig coreAgentConfig
useStandaloneImage *bool
nodeAgentImageOverride *v2alpha1.AgentImageConfig

customConfigAnnotationKey string
customConfigAnnotationValue string
Expand All @@ -70,6 +73,34 @@ func (o *otelCollectorFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.Da
}
o.configMapName = constants.GetConfName(dda, o.customConfig, defaultOTelAgentConf)

// For supported versions, use the user's setting if explicitly set, otherwise default to true
if ddaSpec.Features.OtelCollector.UseStandaloneImage != nil {
o.useStandaloneImage = ddaSpec.Features.OtelCollector.UseStandaloneImage
} else {
// Default to true for supported versions when not explicitly set
o.useStandaloneImage = apiutils.NewBoolPointer(true)
}

// Check agent version for UseStandaloneImage feature support (7.67.0+)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems redundant. This change will be built with default version of 7.67 or later, agentVersion will be earlier than 7.67 iff version from image override is earlier than 7.67. In such case we set useStandaloneImage = false.
Then we go through these conditionals where version retrieved from Override leads to no-op block

	if apiutils.BoolValue(o.useStandaloneImage) {
	} else {
		if o.nodeAgentImageOverride != nil {
			// [no-op] User has provided an explicit image override, respect it as-is
		} else {
			// No explicit override, apply the -full suffix logic
                         // only reachable when `useStandaloneImage` is set to false in DDA. 
                }

This can be simplified and cleaned up.

agentVersion := images.AgentLatestVersion
if nodeAgent, ok := ddaSpec.Override[v2alpha1.NodeAgentComponentName]; ok {
if nodeAgent.Image != nil {
agentVersion = common.GetAgentVersionFromImage(*nodeAgent.Image)
o.nodeAgentImageOverride = nodeAgent.Image
}
}

// Default to UseStandaloneImage=true for 7.67.0+, but allow explicit override
supportedVersion := utils.IsAboveMinVersion(agentVersion, "7.67.0-0")
if !supportedVersion {
// For unsupported versions, force UseStandaloneImage=false and log warning
if apiutils.BoolValue(ddaSpec.Features.OtelCollector.Enabled) && apiutils.BoolValue(ddaSpec.Features.OtelCollector.UseStandaloneImage) {
o.logger.Info("UseStandaloneImage feature requires agent version 7.67.0 or higher",
"current_version", agentVersion, "switching_to_full_image", true)
}
o.useStandaloneImage = apiutils.NewBoolPointer(false)
}

if ddaSpec.Features.OtelCollector.CoreConfig != nil {
o.coreAgentConfig.enabled = ddaSpec.Features.OtelCollector.CoreConfig.Enabled
o.coreAgentConfig.extension_timeout = ddaSpec.Features.OtelCollector.CoreConfig.ExtensionTimeout
Expand Down Expand Up @@ -172,20 +203,51 @@ func (o *otelCollectorFeature) ManageClusterAgent(managers feature.PodTemplateMa
}

func (o *otelCollectorFeature) ManageNodeAgent(managers feature.PodTemplateManagers, provider string) error {
// // Use -full image for all containers
image := &images.Image{}
for i, container := range managers.PodTemplateSpec().Spec.Containers {
image = images.FromString(container.Image).
WithFull(true)
// Note: if an image tag override is configured, this image tag will be overwritten
managers.PodTemplateSpec().Spec.Containers[i].Image = image.ToString()
}
if apiutils.BoolValue(o.useStandaloneImage) {
// When UseStandaloneImage is true, use the ddot-collector image for the otel-agent container
// and ensure other containers don't use -full image. Ignore any image overrides.
for i, container := range managers.PodTemplateSpec().Spec.Containers {
if container.Name == string(apicommon.OtelAgent) {
image := images.FromString(container.Image).
WithName(images.DefaultDdotCollectorImageName)
managers.PodTemplateSpec().Spec.Containers[i].Image = image.ToString()
} else {
// Ensure non-OTel containers don't use -full image when UseStandaloneImage is true
image := images.FromString(container.Image).
WithFull(false)
managers.PodTemplateSpec().Spec.Containers[i].Image = image.ToString()
}
}
} else {
// When UseStandaloneImage is false, all containers (including OTel agent) should use the regular agent image with -full suffix
// However, if there's an explicit image override, respect it and don't modify it
if o.nodeAgentImageOverride != nil {
// User has provided an explicit image override, respect it as-is
o.logger.Info("Respecting explicit image override, skipping -full suffix modification",
"override_image", o.nodeAgentImageOverride.Name+":"+o.nodeAgentImageOverride.Tag)
} else {
// No explicit override, apply the -full suffix logic
image := &images.Image{}
for i, container := range managers.PodTemplateSpec().Spec.Containers {
if container.Name == string(apicommon.OtelAgent) {
// For OTel agent container, keep the custom registry and tag but use the ddot-collector image name
image = images.FromString(container.Image).
WithName(images.DefaultAgentImageName).
WithFull(true)
} else {
// For other containers, just add -full suffix
image = images.FromString(container.Image).
WithFull(true)
}
managers.PodTemplateSpec().Spec.Containers[i].Image = image.ToString()
}

for i, container := range managers.PodTemplateSpec().Spec.InitContainers {
image = images.FromString(container.Image).
WithFull(true)
// Note: if an image tag override is configured, this image tag will be overwritten
managers.PodTemplateSpec().Spec.InitContainers[i].Image = image.ToString()
for i, container := range managers.PodTemplateSpec().Spec.InitContainers {
image = images.FromString(container.Image).
WithFull(true)
managers.PodTemplateSpec().Spec.InitContainers[i].Image = image.ToString()
}
}
}

var vol corev1.Volume
Expand Down
Loading
Loading