Skip to content
Draft
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
19 changes: 19 additions & 0 deletions .chloggen/ta_col_selector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# 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: target allocator

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add collectorSelector field to standalone TargetAllocator CR to prevent all pods in the namespace from being treated as collectors.

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

# (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: |
When using the standalone TargetAllocator CR without a linked OpenTelemetryCollector, the collector_selector
was set to nil, causing all pods in the namespace to be treated as collectors. The new collectorSelector field
allows users to specify which pods should receive target assignments.
6 changes: 6 additions & 0 deletions apis/v1alpha1/targetallocator_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ type TargetAllocatorSpec struct {
// NetworkPolicy defines the network policy to be applied to the Target Allocator pods.
// +optional
NetworkPolicy v1beta1.NetworkPolicy `json:"networkPolicy,omitempty"`
// CollectorSelector defines the label selector for collector pods that the TargetAllocator should
// assign targets to. This is required when using the standalone TargetAllocator CR without an
// associated OpenTelemetryCollector CR. If not set and no collector is linked, all pods in the
// namespace will be treated as collectors.
// +optional
CollectorSelector *metav1.LabelSelector `json:"collectorSelector,omitempty"`
// CollectorNotReadyGracePeriod defines the grace period after which a TargetAllocator stops considering a collector is target assignable.
// The default is 30s, which means that if a collector becomes not Ready, the target allocator will wait for 30 seconds before reassigning its targets. The assumption is that the state is temporary, and an expensive target reallocation should be avoided if possible.
//
Expand Down
5 changes: 5 additions & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring,Observability
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
createdAt: "2026-03-04T12:42:01Z"
createdAt: "2026-03-08T23:17:33Z"
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 @@ -1215,6 +1215,32 @@ spec:
default: 30s
format: duration
type: string
collectorSelector:
properties:
matchExpressions:
items:
properties:
key:
type: string
operator:
type: string
values:
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
type: object
type: object
x-kubernetes-map-type: atomic
dnsPolicy:
type: string
env:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring,Observability
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
createdAt: "2026-03-04T12:42:01Z"
createdAt: "2026-03-08T23:17:34Z"
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 @@ -1215,6 +1215,32 @@ spec:
default: 30s
format: duration
type: string
collectorSelector:
properties:
matchExpressions:
items:
properties:
key:
type: string
operator:
type: string
values:
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
type: object
type: object
x-kubernetes-map-type: atomic
dnsPolicy:
type: string
env:
Expand Down
26 changes: 26 additions & 0 deletions config/crd/bases/opentelemetry.io_targetallocators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,32 @@ spec:
default: 30s
format: duration
type: string
collectorSelector:
properties:
matchExpressions:
items:
properties:
key:
type: string
operator:
type: string
values:
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
type: object
type: object
x-kubernetes-map-type: atomic
dnsPolicy:
type: string
env:
Expand Down
95 changes: 95 additions & 0 deletions docs/api/targetallocators.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ The default is 30s, which means that if a collector becomes not Ready, the targe
<i>Default</i>: 30s<br/>
</td>
<td>false</td>
</tr><tr>
<td><b><a href="#targetallocatorspeccollectorselector">collectorSelector</a></b></td>
<td>object</td>
<td>
CollectorSelector defines the label selector for collector pods that the TargetAllocator should
assign targets to. This is required when using the standalone TargetAllocator CR without an
associated OpenTelemetryCollector CR. If not set and no collector is linked, all pods in the
namespace will be treated as collectors.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>dnsPolicy</b></td>
<td>string</td>
Expand Down Expand Up @@ -5108,6 +5118,91 @@ operator is "In", and the values array contains only "value". The requirements a



A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.

<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody><tr>
<td><b>key</b></td>
<td>string</td>
<td>
key is the label key that the selector applies to.<br/>
</td>
<td>true</td>
</tr><tr>
<td><b>operator</b></td>
<td>string</td>
<td>
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.<br/>
</td>
<td>true</td>
</tr><tr>
<td><b>values</b></td>
<td>[]string</td>
<td>
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.<br/>
</td>
<td>false</td>
</tr></tbody>
</table>


### TargetAllocator.spec.collectorSelector
<sup><sup>[↩ Parent](#targetallocatorspec)</sup></sup>



CollectorSelector defines the label selector for collector pods that the TargetAllocator should
assign targets to. This is required when using the standalone TargetAllocator CR without an
associated OpenTelemetryCollector CR. If not set and no collector is linked, all pods in the
namespace will be treated as collectors.

<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody><tr>
<td><b><a href="#targetallocatorspeccollectorselectormatchexpressionsindex">matchExpressions</a></b></td>
<td>[]object</td>
<td>
matchExpressions is a list of label selector requirements. The requirements are ANDed.<br/>
</td>
<td>false</td>
</tr><tr>
<td><b>matchLabels</b></td>
<td>map[string]string</td>
<td>
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.<br/>
</td>
<td>false</td>
</tr></tbody>
</table>


### TargetAllocator.spec.collectorSelector.matchExpressions[index]
<sup><sup>[↩ Parent](#targetallocatorspeccollectorselector)</sup></sup>



A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.

Expand Down
2 changes: 1 addition & 1 deletion internal/manifests/targetallocator/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func ConfigMap(params Params) (*corev1.ConfigMap, error) {
return nil, err
}
} else { // if there's no collector, just use what's in the TargetAllocator CR
collectorSelector = nil
collectorSelector = taSpec.CollectorSelector
globalConfig = taSpec.GlobalConfig.Object
scrapeConfigs = taSpec.ScrapeConfigs
}
Expand Down
31 changes: 29 additions & 2 deletions internal/manifests/targetallocator/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ collector_selector: null
filter_strategy: relabel-config
`,
}
targetAllocator := targetAllocatorInstance()
targetAllocator.Spec.ScrapeConfigs = []v1beta1.AnyConfig{}
testParams := Params{
Collector: nil,
TargetAllocator: targetAllocatorInstance(),
Expand All @@ -83,6 +81,35 @@ filter_strategy: relabel-config
assert.Equal(t, expectedLabels, actual.Labels)
assert.Equal(t, expectedData[targetAllocatorFilename], actual.Data[targetAllocatorFilename])
})
t.Run("should return target allocator config map without collector but with collectorSelector", func(t *testing.T) {
expectedData := map[string]string{
targetAllocatorFilename: `allocation_strategy: consistent-hashing
collector_selector:
matchlabels:
app.kubernetes.io/component: opentelemetry-collector
app.kubernetes.io/instance: my-collector
matchexpressions: []
filter_strategy: relabel-config
`,
}
ta := targetAllocatorInstance()
ta.Spec.CollectorSelector = &metav1.LabelSelector{
MatchLabels: map[string]string{
"app.kubernetes.io/component": "opentelemetry-collector",
"app.kubernetes.io/instance": "my-collector",
},
}
testParams := Params{
Collector: nil,
TargetAllocator: ta,
}
actual, err := ConfigMap(testParams)
require.NoError(t, err)

assert.Equal(t, "my-instance-targetallocator", actual.Name)
assert.Equal(t, expectedLabels, actual.Labels)
assert.Equal(t, expectedData[targetAllocatorFilename], actual.Data[targetAllocatorFilename])
})
t.Run("should return target allocator config map without scrape configs", func(t *testing.T) {
expectedData := map[string]string{
targetAllocatorFilename: `allocation_strategy: consistent-hashing
Expand Down
Loading