Skip to content

Commit 7c1bd9a

Browse files
authored
feat(base-cluster/tracing): add gateway to enable tail sampling (#1736)
That way traces with errors are always stored, traces that are >200ms and with a random chance of 0.1%. Adjust your clients to just sample 100% of the spans/traces. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a telemetry gateway for distributed tracing with tail-sampling policies and OTLP endpoints. * Enabled JSON-formatted logs in the telemetry collector. * Added a load‑balanced OTLP exporter with Kubernetes service discovery and zstd compression. * **Refactor** * Simplified telemetry enablement across components (no longer tied to Prometheus). * Standardized OTLP endpoint handling to explicit host:port. * Moved descheduler tracing options to a unified telemetry command-options block. * Enriched Kubernetes metadata on traces and increased default trace sampling to 100%. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 303b0b6 commit 7c1bd9a

7 files changed

Lines changed: 184 additions & 27 deletions

File tree

charts/base-cluster/templates/descheduler/descheduler.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ spec:
3838
additionalLabels:
3939
monitoring/provisioned-by: base-cluster
4040
{{- end }}
41-
deschedulerPolicy: {{- $telemetryConf := include "common.telemetry.conf" (dict "protocol" "otlp") | fromYaml }}
42-
{{- if and $telemetryConf.enabled .Values.monitoring.prometheus.enabled }}
43-
tracing:
44-
collectorEndpoint: {{ printf "%s:%d" $telemetryConf.host (int64 $telemetryConf.port) | quote }}
45-
serviceName: descheduler
46-
serviceNamespace: kube-system
47-
sampleRate: 1.0
48-
fallbackToNoOpProviderOnError: true
49-
{{- end }}
41+
{{- $telemetryConf := include "common.telemetry.conf" (dict "protocol" "otlp") | fromYaml }}
42+
{{- if $telemetryConf.enabled }}
43+
cmdOptions:
44+
otel-collector-endpoint: {{ printf "%s:%d" $telemetryConf.host (int64 $telemetryConf.port) | quote }}
45+
otel-service-name: descheduler
46+
otel-trace-namespace: kube-system
47+
otel-sample-rate: 1.0
48+
{{- end }}
49+
deschedulerPolicy:
5050
profiles:
5151
- name: default
5252
{{- toYaml .Values.descheduler.profile | nindent 10 }}

charts/base-cluster/templates/ingress/nginx.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ spec:
2929
additionalLabels:
3030
monitoring/provisioned-by: base-cluster
3131
{{- $telemetryConf := include "common.telemetry.conf" (dict "protocol" "otlp") | fromYaml }}
32-
{{- if and $telemetryConf.enabled .Values.monitoring.prometheus.enabled }}
32+
{{- if $telemetryConf.enabled }}
3333
opentelemetry:
3434
enabled: true
3535
{{- if and .Values.global.imageRegistry false }}

charts/base-cluster/templates/ingress/traefik.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ spec:
8585
otlp:
8686
enabled: true
8787
grpc:
88-
endpoint: {{ $telemetryConf.endpoint }}
88+
enabled: true
89+
endpoint: {{ printf "%s:%d" $telemetryConf.host (int64 $telemetryConf.port) | quote }}
8990
{{- if $telemetryConf.insecure }}
9091
insecure: true
9192
{{- end }}

charts/base-cluster/templates/kyverno/kyverno.yaml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,26 +64,25 @@ spec:
6464
admissionController:
6565
replicas: 3
6666
{{- $telemetryConf := include "common.telemetry.conf" (dict "protocol" "jaeger" "serviceProtocol" "grpc") | fromYaml -}}
67-
{{- $telemetryEnabled := and $telemetryConf.enabled .Values.monitoring.prometheus.enabled -}}
68-
{{- if $telemetryEnabled }}
67+
{{- if $telemetryConf.enabled }}
6968
tracing: &tracingConfig
7069
enabled: true
7170
address: {{ $telemetryConf.host }}
7271
port: {{ int64 $telemetryConf.port }}
7372
{{- end }}
7473
backgroundController:
7574
replicas: 2
76-
{{- if $telemetryEnabled }}
75+
{{- if $telemetryConf.enabled }}
7776
tracing: *tracingConfig
7877
{{- end }}
7978
reportsController:
8079
replicas: 2
81-
{{- if $telemetryEnabled }}
80+
{{- if $telemetryConf.enabled }}
8281
tracing: *tracingConfig
8382
{{- end }}
8483
cleanupController:
8584
replicas: 2
86-
{{- if $telemetryEnabled }}
85+
{{- if $telemetryConf.enabled }}
8786
tracing: *tracingConfig
8887
{{- end }}
8988
podDisruptionBudget:

charts/base-cluster/templates/monitoring/alloy.yaml renamed to charts/base-cluster/templates/monitoring/alloy-collector.yaml

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ spec:
4141
type: RuntimeDefault
4242
configMap:
4343
content: |
44+
logging {
45+
format = "json"
46+
}
47+
4448
{{- if .Values.monitoring.loki.enabled }}
4549
discovery.kubernetes "pods" {
4650
role = "pod"
@@ -189,11 +193,26 @@ spec:
189193
}
190194
}
191195
192-
otelcol.processor.k8sattributes "default" {
193-
auth_type = "serviceAccount"
196+
tracing {
197+
sampling_fraction = 1.0
198+
write_to = [otelcol.processor.k8sattributes.default.input]
199+
}
194200
201+
otelcol.processor.k8sattributes "default" {
195202
extract {
196-
metadata = ["k8s.namespace.name", "k8s.deployment.name", "k8s.statefulset.name", "k8s.daemonset.name", "k8s.cronjob.name", "k8s.job.name", "k8s.node.name", "k8s.pod.name", "k8s.pod.uid", "k8s.pod.start_time"]
203+
metadata = [
204+
"k8s.namespace.name",
205+
"k8s.deployment.name",
206+
"k8s.replicaset.name", "k8s.replicaset.uid",
207+
"k8s.statefulset.name", "k8s.statefulset.uid",
208+
"k8s.daemonset.name", "k8s.daemonset.uid",
209+
"k8s.cronjob.name",
210+
"k8s.job.name", "k8s.job.uid",
211+
"k8s.node.name",
212+
"k8s.pod.name", "k8s.pod.uid", "k8s.pod.start_time",
213+
"k8s.container.name", "container.id",
214+
"container.image.name", "container.image.tag",
215+
]
197216
}
198217
199218
pod_association {
@@ -223,16 +242,24 @@ spec:
223242
224243
otelcol.processor.batch "default" {
225244
output {
226-
traces = [otelcol.connector.servicegraph.default.input, otelcol.exporter.otlp.tempo.input]
245+
traces = [otelcol.connector.servicegraph.default.input, otelcol.exporter.loadbalancing.gateway.input]
227246
}
228247
}
229248
230-
otelcol.exporter.otlp "tempo" {
231-
client {
232-
endpoint = "grafana-tempo-distributor:4317"
233-
234-
tls {
235-
insecure = true
249+
otelcol.exporter.loadbalancing "gateway" {
250+
resolver {
251+
kubernetes {
252+
service = "telemetry-gateway"
253+
}
254+
}
255+
protocol {
256+
otlp {
257+
client {
258+
compression = "zstd"
259+
tls {
260+
insecure = true
261+
}
262+
}
236263
}
237264
}
238265
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
{{- if and .Values.monitoring.prometheus.enabled .Values.monitoring.tracing.enabled -}}
2+
apiVersion: helm.toolkit.fluxcd.io/v2
3+
kind: HelmRelease
4+
metadata:
5+
name: telemetry-gateway
6+
namespace: monitoring
7+
labels: {{- include "common.labels.standard" $ | nindent 4 }}
8+
app.kubernetes.io/component: alloy
9+
app.kubernetes.io/part-of: monitoring
10+
spec:
11+
chart:
12+
spec: {{- include "base-cluster.helm.chartSpec" (dict "repo" "grafana" "chart" "alloy" "context" $) | nindent 6 }}
13+
interval: 1h
14+
driftDetection:
15+
mode: enabled
16+
install:
17+
timeout: 10m0s
18+
crds: Skip
19+
upgrade:
20+
timeout: 10m0s
21+
crds: Skip
22+
dependsOn:
23+
- name: kube-prometheus-stack
24+
namespace: monitoring
25+
values:
26+
fullnameOverride: telemetry-gateway
27+
{{- if .Values.global.imageRegistry }}
28+
global:
29+
image:
30+
registry: {{ $.Values.global.imageRegistry }}
31+
{{- end }}
32+
alloy:
33+
enableReporting: false
34+
resources: {{- include "common.resources" .Values.monitoring.loki.promtail | nindent 8 }}
35+
{{- if .Values.monitoring.loki.enabled }}
36+
mounts:
37+
varlog: true
38+
{{- end }}
39+
securityContext:
40+
seccompProfile:
41+
type: RuntimeDefault
42+
configMap:
43+
content: |
44+
logging {
45+
format = "json"
46+
}
47+
48+
otelcol.receiver.otlp "default" {
49+
grpc {}
50+
51+
output {
52+
traces = [otelcol.processor.tail_sampling.policies.input]
53+
}
54+
}
55+
56+
tracing {
57+
sampling_fraction = 1.0
58+
write_to = [otelcol.processor.tail_sampling.policies.input]
59+
}
60+
61+
otelcol.processor.tail_sampling "policies" {
62+
decision_wait = "30s"
63+
64+
policy {
65+
name = "sample-erroring-traces"
66+
type = "status_code"
67+
status_code {
68+
status_codes = [ "ERROR" ]
69+
}
70+
}
71+
72+
policy {
73+
name = "sample-long-traces"
74+
type = "latency"
75+
latency {
76+
threshold_ms = 200
77+
}
78+
}
79+
80+
policy {
81+
name = "sample-random"
82+
type = "probabilistic"
83+
probabilistic {
84+
sampling_percentage = 0.1
85+
}
86+
}
87+
88+
output {
89+
traces = [otelcol.processor.batch.default.input]
90+
}
91+
}
92+
93+
otelcol.processor.batch "default" {
94+
output {
95+
traces = [otelcol.exporter.otlp.tempo.input]
96+
}
97+
}
98+
99+
otelcol.exporter.otlp "tempo" {
100+
client {
101+
endpoint = "grafana-tempo-distributor:4317"
102+
103+
tls {
104+
insecure = true
105+
}
106+
}
107+
}
108+
extraPorts:
109+
- name: metrics
110+
port: 8888
111+
protocol: TCP
112+
targetPort: 8888
113+
- name: otlp
114+
port: 4317
115+
appProtocol: grpc
116+
protocol: TCP
117+
targetPort: 4317
118+
crds:
119+
create: false
120+
controller:
121+
type: deployment
122+
autoscaling:
123+
enabled: true
124+
minReplicas: 2
125+
priorityClassName: monitoring-components
126+
serviceMonitor:
127+
enabled: true
128+
additionalLabels:
129+
monitoring/provisioned-by: base-cluster
130+
{{- end -}}

charts/base-cluster/templates/monitoring/kube-prometheus-stack/_prometheus_config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ prometheusSpec:
6262
{{- if $telemetryConf.enabled }}
6363
tracingConfig:
6464
clientType: grpc
65-
samplingFraction: "0.1"
65+
samplingFraction: "1.0"
6666
insecure: true
6767
endpoint: {{ printf "%s:%d" $telemetryConf.host (int64 $telemetryConf.port) | quote }}
6868
{{- end }}

0 commit comments

Comments
 (0)