Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .chloggen/feat_allow-hostpid-support-collector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
component: collector

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: adds a feature to allow setting the `spec.hostPID` field for the collector.

# One or more tracking issues related to the change
issues: [4214]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
The allowing of the operator hostPID support can be enabled with `--feature-gates=+operator.security.hostpid`.
The feature gate is disabled by default and it will be enabled in the future releases.
3 changes: 3 additions & 0 deletions apis/v1alpha1/opentelemetrycollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ type OpenTelemetryCollectorSpec struct {
// HostNetwork indicates if the pod should run in the host networking namespace.
// +optional
HostNetwork bool `json:"hostNetwork,omitempty"`
// HostPID indicates if the pod should have access to the host process ID namespace.
// +optional
HostPID bool `json:"hostPID,omitempty"`
// ShareProcessNamespace indicates if the pod's containers should share process namespace.
// +optional
ShareProcessNamespace bool `json:"shareProcessNamespace,omitempty"`
Expand Down
7 changes: 7 additions & 0 deletions apis/v1beta1/opentelemetrycollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ type OpenTelemetryCollectorSpec struct {
// This is only applicable to Deployment mode.
// +optional
DeploymentUpdateStrategy appsv1.DeploymentStrategy `json:"deploymentUpdateStrategy,omitempty"`
// ServiceName is the name of the Service to be used.
// If not specified, it will default to "<name>-headless".
// +optional
ServiceName string `json:"serviceName,omitempty"`
// HostPID indicates if the pod should have access to the host process ID namespace.
// +optional
HostPID bool `json:"hostPID,omitempty"`
}

// TargetAllocatorEmbedded defines the configuration for the Prometheus target allocator, embedded in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
createdAt: "2025-09-29T13:00:18Z"
createdAt: "2025-10-24T13:19:55Z"
description: Provides the OpenTelemetry components, including the Collector
operators.operatorframework.io/builder: operator-sdk-v1.29.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down Expand Up @@ -6067,6 +6069,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
createdAt: "2025-09-29T13:00:19Z"
createdAt: "2025-10-24T13:19:55Z"
description: Provides the OpenTelemetry components, including the Collector
operators.operatorframework.io/builder: operator-sdk-v1.29.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down Expand Up @@ -6066,6 +6068,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down Expand Up @@ -6053,6 +6055,8 @@ spec:
type: array
hostNetwork:
type: boolean
hostPID:
type: boolean
image:
type: string
imagePullPolicy:
Expand Down
6 changes: 6 additions & 0 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
resources:
- manager.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: controller
newName: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
newTag: 0.136.0-9-g247d92bf
14 changes: 14 additions & 0 deletions docs/api/opentelemetrycollectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ These can then in certain cases be consumed in the config file for the Collector
HostNetwork indicates if the pod should run in the host networking namespace.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>hostPID</b></td>
<td>boolean</td>
<td>
HostPID indicates if the pod should have access to the host process ID namespace.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>image</b></td>
<td>string</td>
Expand Down Expand Up @@ -19552,6 +19559,13 @@ This is only applicable to Deployment mode.<br/>
HostNetwork indicates if the pod should run in the host networking namespace.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>hostPID</b></td>
<td>boolean</td>
<td>
HostPID indicates if the pod should have access to the host process ID namespace.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>image</b></td>
<td>string</td>
Expand Down
1 change: 1 addition & 0 deletions internal/manifests/collector/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func DaemonSet(params manifests.Params) (*appsv1.DaemonSet, error) {
Tolerations: params.OtelCol.Spec.Tolerations,
NodeSelector: params.OtelCol.Spec.NodeSelector,
HostNetwork: params.OtelCol.Spec.HostNetwork,
HostPID: params.OtelCol.Spec.HostPID,
ShareProcessNamespace: &params.OtelCol.Spec.ShareProcessNamespace,
DNSPolicy: manifestutils.GetDNSPolicy(params.OtelCol.Spec.HostNetwork, params.OtelCol.Spec.PodDNSConfig),
DNSConfig: &params.OtelCol.Spec.PodDNSConfig,
Expand Down
45 changes: 45 additions & 0 deletions internal/manifests/collector/daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,3 +660,48 @@ func TestDaemonSetTerminationGracePeriodSeconds(t *testing.T) {
assert.NotNil(t, d2.Spec.Template.Spec.TerminationGracePeriodSeconds)
assert.Equal(t, gracePeriodSec, *d2.Spec.Template.Spec.TerminationGracePeriodSeconds)
}

func TestDaemonSetHostPIDCanBeSet(t *testing.T) {

// Test the case where hostPID is not set, should default to false
otelcol1 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
}

cfg := config.New()

params1 := manifests.Params{
Config: cfg,
OtelCol: otelcol1,
Log: testLogger,
}

d1, err := DaemonSet(params1)
require.NoError(t, err)
assert.False(t, d1.Spec.Template.Spec.HostPID)

// Test the case where hostPID is set to true
otelcol2 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance-terminationGracePeriodSeconds",
},
Spec: v1beta1.OpenTelemetryCollectorSpec{
HostPID: true,
},
}

cfg = config.New()

params2 := manifests.Params{
Config: cfg,
OtelCol: otelcol2,
Log: testLogger,
}

d2, err := DaemonSet(params2)
require.NoError(t, err)
assert.NotNil(t, d2.Spec.Template.Spec.HostPID)
assert.True(t, d2.Spec.Template.Spec.HostPID)
}
1 change: 1 addition & 0 deletions internal/manifests/collector/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func Deployment(params manifests.Params) (*appsv1.Deployment, error) {
DNSPolicy: manifestutils.GetDNSPolicy(params.OtelCol.Spec.HostNetwork, params.OtelCol.Spec.PodDNSConfig),
DNSConfig: &params.OtelCol.Spec.PodDNSConfig,
HostNetwork: params.OtelCol.Spec.HostNetwork,
HostPID: params.OtelCol.Spec.HostPID,
ShareProcessNamespace: &params.OtelCol.Spec.ShareProcessNamespace,
Tolerations: params.OtelCol.Spec.Tolerations,
NodeSelector: params.OtelCol.Spec.NodeSelector,
Expand Down
45 changes: 45 additions & 0 deletions internal/manifests/collector/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -808,3 +808,48 @@ func TestGetInitialReplicas(t *testing.T) {
func int32Ptr(i int32) *int32 {
return &i
}

func TestDeploymentHostPIDCanBeSet(t *testing.T) {

// Test default
otelcol1 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
}

cfg := config.New()

params1 := manifests.Params{
Config: cfg,
OtelCol: otelcol1,
Log: testLogger,
}

d1, err := Deployment(params1)
require.NoError(t, err)

assert.False(t, d1.Spec.Template.Spec.HostPID)

// Test hostPID=true
otelcol2 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance-hostnetwork",
},
Spec: v1beta1.OpenTelemetryCollectorSpec{
HostPID: true,
},
}

cfg = config.New()

params2 := manifests.Params{
Config: cfg,
OtelCol: otelcol2,
Log: testLogger,
}

d2, err := Deployment(params2)
require.NoError(t, err)
assert.True(t, d2.Spec.Template.Spec.HostPID)
}
1 change: 1 addition & 0 deletions internal/manifests/collector/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func StatefulSet(params manifests.Params) (*appsv1.StatefulSet, error) {
DNSPolicy: manifestutils.GetDNSPolicy(params.OtelCol.Spec.HostNetwork, params.OtelCol.Spec.PodDNSConfig),
DNSConfig: &params.OtelCol.Spec.PodDNSConfig,
HostNetwork: params.OtelCol.Spec.HostNetwork,
HostPID: params.OtelCol.Spec.HostPID,
ShareProcessNamespace: &params.OtelCol.Spec.ShareProcessNamespace,
Tolerations: params.OtelCol.Spec.Tolerations,
NodeSelector: params.OtelCol.Spec.NodeSelector,
Expand Down
45 changes: 45 additions & 0 deletions internal/manifests/collector/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,3 +828,48 @@ func TestStatefulSetServiceName(t *testing.T) {
})
}
}

func TestStatefulSetHostPIDCanBeSet(t *testing.T) {

// Test default
otelcol1 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
}

cfg := config.New()

params1 := manifests.Params{
OtelCol: otelcol1,
Config: cfg,
Log: testLogger,
}

d1, err := StatefulSet(params1)
require.NoError(t, err)

assert.False(t, d1.Spec.Template.Spec.HostPID)

// Test HostPID=true
otelcol2 := v1beta1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance-HostPID",
},
Spec: v1beta1.OpenTelemetryCollectorSpec{
HostPID: true,
},
}

cfg = config.New()

params2 := manifests.Params{
OtelCol: otelcol2,
Config: cfg,
Log: testLogger,
}

d2, err := StatefulSet(params2)
require.NoError(t, err)
assert.True(t, d2.Spec.Template.Spec.HostPID)
}
40 changes: 40 additions & 0 deletions tests/e2e/smoke-collector-hostpid/00-assert-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-collector
spec:
updateStrategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
status:
numberMisscheduled: 0
(desiredNumberScheduled == numberReady): true

---
apiVersion: v1
kind: Pod
metadata:
labels:
app.kubernetes.io/component: opentelemetry-collector
app.kubernetes.io/managed-by: opentelemetry-operator
app.kubernetes.io/name: daemonset-collector
status:
containerStatuses:
- ready: true
started: true
phase: Running
spec:
hostPID: true
---
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: daemonset
status:
(starts_with(image, 'ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector')): true
scale:
(replicas >= `1`): true
(statusReplicas != ''): true
(version != ''): true
24 changes: 24 additions & 0 deletions tests/e2e/smoke-collector-hostpid/00-install-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: daemonset
spec:
hostPID: true
mode: daemonset
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
config: |
receivers:
jaeger:
protocols:
grpc:
processors:
exporters:
debug:
service:
pipelines:
traces:
receivers: [jaeger]
exporters: [debug]
Loading