This guide explains how to install the K8s Infra collection agent on a Kubernetes cluster, with the k8s-infra Helm chart, or with Foundry through Helm or Kustomize.
Prerequisites
- A Kubernetes cluster.
kubectlconfigured to reach the cluster.- For a Helm-based setup, Helm 3 installed on the same machine.
- A SigNoz to send data to: SigNoz Cloud or a self-hosted SigNoz.
Install with the Helm CLI
Step 1: Add the Helm repository
Run this on the machine where you use kubectl:
helm repo add signoz https://charts.signoz.io
helm repo updateStep 2: Create override-values.yaml
Create a file named override-values.yaml with the values for your Kubernetes platform:
global:
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every chart value, see the k8s-infra chart.
global:
cloud: aws
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every chart value, see the k8s-infra chart.
global:
cloud: gcp
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every chart value, see the k8s-infra chart.
global:
cloud: gcp/autogke
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every chart value, see the k8s-infra chart.
global:
cloud: azure
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every chart value, see the k8s-infra chart.
global:
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: https://ingest.<region>.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>
presets:
hostMetrics:
# Root path configuration is only required for Linux environments.
# On Windows, this must be set to empty string to prevent installation failures.
rootPath: ""
otelAgent:
# Use Windows-compatible OpenTelemetry Collector Contrib images for Windows hosts
image:
tag: 0.139.0-windows-2022-amd64
otelDeployment:
# Use Windows-compatible OpenTelemetry Collector Contrib images for Windows hosts
image:
tag: 0.139.0-windows-2022-amd64Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.0.139.0-windows-2022-amd64: The image tag must match the Windows Server version of your nodes.0.139.0-windows-2022-amd64is for Windows Server 2022; use0.139.0-windows-2019-amd64for Windows Server 2019.
For every chart value, see the k8s-infra chart.
Step 3: Install the chart
Run this from the directory that contains override-values.yaml:
helm install my-release signoz/k8s-infra -f override-values.yamlHelm installs the release my-release into the namespace of your current kubectl context, default unless you set another.
Step 4: Verify the Collection Agent
Run this on the machine where you use kubectl to check that the pods are running:
kubectl get podsThe output should look similar to the following, with one my-release-k8s-infra-otel-agent pod per node. Pod suffixes vary, and if SigNoz runs in the same namespace its pods are listed too:
NAME READY STATUS RESTARTS AGE
my-release-k8s-infra-otel-agent-7xk2p 1/1 Running 0 2m
my-release-k8s-infra-otel-agent-q9m4d 1/1 Running 0 2m
my-release-k8s-infra-otel-deployment-6d9c7b8f5c-k2x9p 1/1 Running 0 2mIn SigNoz, open the Kubernetes Monitoring views under Infrastructure Monitoring. The Clusters view lists your cluster under the name you set as <CLUSTER_NAME>, and the Pods and Nodes views fill in as data arrives. Check Logs Explorer to confirm container logs and Kubernetes events are flowing.
Customize the Collection Agent
Every change follows the same loop: edit override-values.yaml, then run this from the directory that contains it:
helm upgrade my-release signoz/k8s-infra -f override-values.yaml- Collector config (presets, receivers, pipelines): see Configure K8s Infra.
- Chart values: see the k8s-infra chart for every setting.
- Chart version: add
--version <chart-version>tohelm installandhelm upgrade. Versions are listed in the SigNoz charts releases.
Verify these values:
<chart-version>: Ak8s-infrachart version from the SigNoz charts releases, for example0.17.1.
Troubleshooting
helm install fails with cannot re-use a name that is still in use
Run this on the machine where you use kubectl to list the releases in the current namespace:
helm listCause: the release my-release already exists.
Fix: apply your changes with helm upgrade, as shown under Customize the Collection Agent.
After the fix, kubectl get pods shows the agent pods as Running.
Agent pod stays Pending
Run this on the machine where you use kubectl to see why the pod is unscheduled:
kubectl describe pod <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods.
Cause: another collector holds host ports 4317, 4318, 8888, and 13133 on the node, for example an agent installed with Foundry. This happens on every platform except GKE Autopilot, where the agent binds no host ports.
Fix: keep one of the two agents and remove the other.
After the fix, kubectl get pods shows one agent pod per node as Running.
On GKE Autopilot the agent DaemonSet has no pods
Run this on the machine where you use kubectl to see the DaemonSet's events:
kubectl describe daemonset my-release-k8s-infra-otel-agentThe events show the pods denied by an Autopilot policy (denied by autogke-).
Cause: the values ask for host ports and host paths that GKE Autopilot denies.
Fix: use the GKE (Autopilot) values from Step 2, which set global.cloud: gcp/autogke, and run the helm upgrade command under Customize the Collection Agent.
After the fix, kubectl get pods shows one agent pod per node.
Agent logs a root_path warning on GKE Autopilot
Run this on the machine where you use kubectl to see the agent's logs:
kubectl logs <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods. The logs show a warning that starts with No `root_path` config set when running in docker environment.
Cause: on GKE Autopilot the agent has no host root to read, so the hostmetrics receiver runs without root_path and reports the agent container's filesystem.
Fix: none needed. Node disk and network metrics come from the kubeletstats receiver as k8s.node.filesystem.* and k8s.node.network.*.
The agent keeps running: kubectl get pods shows its pods as Running.
Agent pods stay in ErrImagePull
Run this on the machine where you use kubectl to see the pull error:
kubectl describe pod <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods. The events show ErrImagePull or ImagePullBackOff with no match for platform in manifest.
Cause: the collector image's OS does not match the node's OS, for example the Windows image on a Linux node.
Fix: keep each agent on nodes of its OS: set nodeSelector under otelAgent and otelDeployment in override-values.yaml, for example kubernetes.io/os: windows for the Windows agent, then run the helm upgrade command under Customize the Collection Agent.
After the fix, kubectl get pods shows the agent pods as Running.
Install with Foundry and Helm
Step 1: Install foundryctl
Run this on the machine where you use kubectl:
curl -fsSL https://signoz.io/foundry.sh | bashFor manual install (Windows PowerShell, air-gapped, etc.) or PATH setup, see the foundry getting-started guide.
Step 2: Create casting.yaml
Create a file named casting.yaml for your Kubernetes platform, with one document for each collector described in How it works:
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: helm
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: helm
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the Kubernetes Helm example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: aws
mode: kubernetes
flavor: helm
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: aws
mode: kubernetes
flavor: helm
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the AWS EKS Helm example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes
flavor: helm
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes
flavor: helm
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the GKE Helm example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes-auto
flavor: helm
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes-auto
flavor: helm
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the GKE Autopilot Helm example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: azure
mode: kubernetes
flavor: helm
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: azure
mode: kubernetes
flavor: helm
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the AKS Helm example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: helm
collector:
spec:
image: otel/opentelemetry-collector-contrib:0.139.0-windows-2022-amd64
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
receivers:
hostmetrics:
root_path: ""
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: helm
collector:
kind: deployment
spec:
image: otel/opentelemetry-collector-contrib:0.139.0-windows-2022-amd64
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.0.139.0-windows-2022-amd64: The image tag must match the Windows Server version of your nodes.0.139.0-windows-2022-amd64is for Windows Server 2022; use0.139.0-windows-2019-amd64for Windows Server 2019.
For every option of this casting, see the Kubernetes Helm example.
Step 3: Deploy
Run this from the directory that contains casting.yaml:
foundryctl cast -f casting.yamlThis installs the k8s-infra chart into the signoz namespace as two releases, signoz-collector-agent and signoz-collector-deployment, and creates the namespace when it is missing. Run the same command again after editing casting.yaml to apply the change.
Step 4: Verify the Collection Agent
Run this on the machine where you use kubectl to check that the pods are running:
kubectl get pods -n signozThe output should look similar to the following, with one signoz-collector-agent pod per node. Pod suffixes vary, and if SigNoz runs in the same namespace its pods are listed too:
NAME READY STATUS RESTARTS AGE
signoz-collector-agent-7xk2p 1/1 Running 0 2m
signoz-collector-agent-q9m4d 1/1 Running 0 2m
signoz-collector-deployment-6d9c7b8f5c-k2x9p 1/1 Running 0 2mIn SigNoz, open the Kubernetes Monitoring views under Infrastructure Monitoring. The Clusters view lists your cluster under the name you set as <CLUSTER_NAME>, and the Pods and Nodes views fill in as data arrives. Check Logs Explorer to confirm container logs and Kubernetes events are flowing.
Customize the Collection Agent
Every change follows the same loop: edit casting.yaml, then run foundryctl cast -f casting.yaml again.
-
Collector settings (image, environment): set them in the collector's
spec(see spec fields). For example, to pin the collector image:spec: collector: spec: image: otel/opentelemetry-collector-contrib:0.139.0 -
Collector config (receivers, processors, pipelines): add it under
spec.collector.spec.config.data, keyedcollector/agent/agent.yamlorcollector/deployment/deployment.yaml. It merges into the generated config (see custom config files). For example, to scrape kubelet metrics every 60s:spec: collector: spec: config: data: collector/agent/agent.yaml: | receivers: kubeletstats: collection_interval: 60s -
Chart values (resources, tolerations, node selector): add patches under
spec.patchesagainstcollectionagent/collector/agent/values.yamlorcollectionagent/collector/deployment/values.yaml. For example, to set the agent's resource requests:spec: patches: - target: collectionagent/collector/agent/values.yaml operations: - op: add path: /otelAgent/resources value: requests: cpu: 200m memory: 256MiEach run regenerates the files under
pours/, so keep every change incasting.yaml.
Troubleshooting
Agent pod stays Pending
Run this on the machine where you use kubectl to see why the pod is unscheduled:
kubectl describe pod -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz.
Cause: another collector holds host ports 4317, 4318, 8888, and 13133 on the node, for example a k8s-infra release installed with Helm. This happens on every platform except GKE Autopilot, where the agent binds no host ports.
Fix: keep one of the two agents and remove the other.
After the fix, kubectl get pods -n signoz shows one agent pod per node as Running.
On GKE Autopilot the agent DaemonSet has no pods
Run this on the machine where you use kubectl to see the DaemonSet's events:
kubectl describe daemonset -n signoz signoz-collector-agentThe events show the pods denied by an Autopilot policy (denied by autogke-).
Cause: the casting asks for host ports and host paths that GKE Autopilot denies.
Fix: use the GKE (Autopilot) casting from Step 2 and run foundryctl cast -f casting.yaml again from the directory that contains it.
After the fix, kubectl get pods -n signoz shows one agent pod per node.
Agent logs a root_path warning on GKE Autopilot
Run this on the machine where you use kubectl to see the agent's logs:
kubectl logs -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz. The logs show a warning that starts with No `root_path` config set when running in docker environment.
Cause: on GKE Autopilot the agent has no host root to read, so the hostmetrics receiver runs without root_path and reports the agent container's filesystem.
Fix: none needed. Node disk and network metrics come from the kubeletstats receiver as k8s.node.filesystem.* and k8s.node.network.*.
The agent keeps running: kubectl get pods -n signoz shows its pods as Running.
Agent pods stay in ErrImagePull
Run this on the machine where you use kubectl to see the pull error:
kubectl describe pod -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz. The events show ErrImagePull or ImagePullBackOff with no match for platform in manifest.
Cause: the collector image's OS does not match the node's OS, for example the Windows image on a Linux node.
Fix: keep each agent on nodes of its OS: add a patch on collectionagent/collector/agent/values.yaml that adds /otelAgent/nodeSelector, and one on collectionagent/collector/deployment/values.yaml that adds /otelDeployment/nodeSelector, for example kubernetes.io/os: windows. Then run foundryctl cast -f casting.yaml again from the directory that contains it.
After the fix, kubectl get pods -n signoz shows the agent pods as Running.
foundryctl cast reaches the wrong cluster or none
Run this on the machine where you run foundryctl to see which cluster it uses:
kubectl config current-contextCause: foundryctl cast applies to the cluster of your current kubectl context.
Fix: switch to the right context with kubectl config use-context <context-name>, then run foundryctl cast -f casting.yaml again from the directory that contains it. Replace <context-name> with a context from kubectl config get-contexts.
After the fix, kubectl get pods -n signoz shows the collector pods on that cluster.
Install with Foundry and Kustomize
Step 1: Install foundryctl
Run this on the machine where you use kubectl:
curl -fsSL https://signoz.io/foundry.sh | bashFor manual install (Windows PowerShell, air-gapped, etc.) or PATH setup, see the foundry getting-started guide.
Step 2: Create casting.yaml
Create a file named casting.yaml for your Kubernetes platform, with one document for each collector described in How it works:
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: kustomize
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: kustomize
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the Kubernetes Kustomize example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: aws
mode: kubernetes
flavor: kustomize
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: aws
mode: kubernetes
flavor: kustomize
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the AWS EKS Kustomize example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes
flavor: kustomize
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes
flavor: kustomize
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the GKE Kustomize example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes-auto
flavor: kustomize
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: gcp
mode: kubernetes-auto
flavor: kustomize
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the GKE Autopilot Kustomize example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: azure
mode: kubernetes
flavor: kustomize
collector:
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
platform: azure
mode: kubernetes
flavor: kustomize
collector:
kind: deployment
spec:
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.
For every option of this casting, see the AKS Kustomize example.
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: kustomize
collector:
spec:
image: otel/opentelemetry-collector-contrib:0.139.0-windows-2022-amd64
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/agent/agent.yaml: |
receivers:
hostmetrics:
root_path: ""
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}
---
apiVersion: v1alpha1
kind: CollectionAgent
metadata:
name: signoz
spec:
deployment:
mode: kubernetes
flavor: kustomize
collector:
kind: deployment
spec:
image: otel/opentelemetry-collector-contrib:0.139.0-windows-2022-amd64
env:
SIGNOZ_INGESTION_ENDPOINT: https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY: <your-ingestion-key>
K8S_CLUSTER_NAME: <CLUSTER_NAME>
OTEL_RESOURCE_ATTRIBUTES: deployment.environment=<DEPLOYMENT_ENVIRONMENT>
config:
data:
collector/deployment/deployment.yaml: |
exporters:
otlphttp/signoz:
headers:
signoz-ingestion-key: ${env:SIGNOZ_INGESTION_KEY}Verify these values:
<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz Cloud ingestion key. It is set as a plain environment variable on the collector pods.<CLUSTER_NAME>: A name for this cluster, unique across the clusters that send to the same SigNoz. Use the same value in both documents. It becomesk8s.cluster.nameon every signal and names the cluster in the SigNoz Kubernetes views.<DEPLOYMENT_ENVIRONMENT>: Your deployment environment, for examplestagingorproduction. It becomesdeployment.environmenton the collected telemetry.0.139.0-windows-2022-amd64: The image tag must match the Windows Server version of your nodes.0.139.0-windows-2022-amd64is for Windows Server 2022; use0.139.0-windows-2019-amd64for Windows Server 2019.
For every option of this casting, see the Kubernetes Kustomize example.
Step 3: Deploy
Run this from the directory that contains casting.yaml:
foundryctl cast -f casting.yamlThis command:
- writes one kustomize root per collector,
pours/collectionagent/collector/agentandpours/collectionagent/collector/deployment; - applies each root with
kubectl apply -kto the cluster of your currentkubectlcontext; - creates the
signoznamespace on the first apply, since each root holds the namespace, the collector's service account, RBAC, Service, workload, and config.
Run the same command again after editing casting.yaml to apply the change.
Step 4: Verify the Collection Agent
Run this on the machine where you use kubectl to check that the pods are running:
kubectl get pods -n signozThe output should look similar to the following, with one signoz-collector-agent pod per node. Pod suffixes vary, and if SigNoz runs in the same namespace its pods are listed too:
NAME READY STATUS RESTARTS AGE
signoz-collector-agent-7xk2p 1/1 Running 0 2m
signoz-collector-agent-q9m4d 1/1 Running 0 2m
signoz-collector-deployment-6d9c7b8f5c-k2x9p 1/1 Running 0 2mIn SigNoz, open the Kubernetes Monitoring views under Infrastructure Monitoring. The Clusters view lists your cluster under the name you set as <CLUSTER_NAME>, and the Pods and Nodes views fill in as data arrives. Check Logs Explorer to confirm container logs and Kubernetes events are flowing.
Customize the Collection Agent
Every change follows the same loop: edit casting.yaml, then run foundryctl cast -f casting.yaml again.
-
Collector settings (image, environment): set them in the collector's
spec(see spec fields). For example, to pin the collector image:spec: collector: spec: image: otel/opentelemetry-collector-contrib:0.139.0 -
Collector config (receivers, processors, pipelines): add it under
spec.collector.spec.config.data, keyedcollector/agent/agent.yamlorcollector/deployment/deployment.yaml. It merges into the generated config (see custom config files). For example, to scrape kubelet metrics every 60s:spec: collector: spec: config: data: collector/agent/agent.yaml: | receivers: kubeletstats: collection_interval: 60s -
Manifests (resources, tolerations, node selector): add patches under
spec.patchesagainstcollectionagent/collector/agent/workload.yamlorcollectionagent/collector/deployment/workload.yaml. For example, to set the agent's resource requests:spec: patches: - target: collectionagent/collector/agent/workload.yaml operations: - op: replace path: /spec/template/spec/containers/0/resources value: requests: cpu: 200m memory: 256MiEach run regenerates the files under
pours/, so keep every change incasting.yaml.
Troubleshooting
Agent pod stays Pending
Run this on the machine where you use kubectl to see why the pod is unscheduled:
kubectl describe pod -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz.
Cause: another collector holds host ports 4317, 4318, 8888, and 13133 on the node, for example a k8s-infra release installed with Helm. This happens on every platform except GKE Autopilot, where the agent binds no host ports.
Fix: keep one of the two agents and remove the other.
After the fix, kubectl get pods -n signoz shows one agent pod per node as Running.
On GKE Autopilot the agent DaemonSet has no pods
Run this on the machine where you use kubectl to see the DaemonSet's events:
kubectl describe daemonset -n signoz signoz-collector-agentThe events show the pods denied by an Autopilot policy (denied by autogke-).
Cause: the casting asks for host ports and host paths that GKE Autopilot denies.
Fix: use the GKE (Autopilot) casting from Step 2 and run foundryctl cast -f casting.yaml again from the directory that contains it.
After the fix, kubectl get pods -n signoz shows one agent pod per node.
Agent logs a root_path warning on GKE Autopilot
Run this on the machine where you use kubectl to see the agent's logs:
kubectl logs -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz. The logs show a warning that starts with No `root_path` config set when running in docker environment.
Cause: on GKE Autopilot the agent has no host root to read, so the hostmetrics receiver runs without root_path and reports the agent container's filesystem.
Fix: none needed. Node disk and network metrics come from the kubeletstats receiver as k8s.node.filesystem.* and k8s.node.network.*.
The agent keeps running: kubectl get pods -n signoz shows its pods as Running.
Agent pods stay in ErrImagePull
Run this on the machine where you use kubectl to see the pull error:
kubectl describe pod -n signoz <pod-name>Replace <pod-name> with the agent pod's name from kubectl get pods -n signoz. The events show ErrImagePull or ImagePullBackOff with no match for platform in manifest.
Cause: the collector image's OS does not match the node's OS, for example the Windows image on a Linux node.
Fix: keep each agent on nodes of its OS: add a patch with op: add at /spec/template/spec/nodeSelector on each collector's workload, collectionagent/collector/agent/workload.yaml and collectionagent/collector/deployment/workload.yaml, for example kubernetes.io/os: windows. Then run foundryctl cast -f casting.yaml again from the directory that contains it.
After the fix, kubectl get pods -n signoz shows the agent pods as Running.
foundryctl cast reaches the wrong cluster or none
Run this on the machine where you run foundryctl to see which cluster it uses:
kubectl config current-contextCause: foundryctl cast applies to the cluster of your current kubectl context.
Fix: switch to the right context with kubectl config use-context <context-name>, then run foundryctl cast -f casting.yaml again from the directory that contains it. Replace <context-name> with a context from kubectl config get-contexts.
After the fix, kubectl get pods -n signoz shows the collector pods on that cluster.
Send data from your applications
Node, pod, and container metrics, container logs, and Kubernetes events flow as soon as the agent pods are running. To send traces, metrics, and logs from your applications through the agent, see Send Data from Applications to the Collector.
Video Walkthrough
If you are someone who understands things better through video implementation, here is a video to help you. Check it out:
OpenTelemetry Kubernetes Tutorial: Deploy, Configure, and Scale with SigNoz Agents