Skip to main content

Kubernetes deployment

infrasagent runs as a DaemonSet (one pod per node) for host-level telemetry collection, or as a Deployment in gateway mode for centralized aggregation.

DaemonSet (agent mode)​

The DaemonSet deploys one agent per node to collect host metrics, container logs, and OTLP from local workloads.

1. Create the namespace and secret​

kubectl create namespace infrasage

kubectl create secret generic infrasagent \
--namespace infrasage \
--from-literal=api-key=<YOUR_API_KEY>

2. Apply the ConfigMap​

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: infrasagent
namespace: infrasage
data:
agent.yaml: |
agent:
name: "${HOSTNAME}-agent"
mode: agent

api:
listen: "0.0.0.0:8080"

sources:
otlp_in:
type: otlp
grpc:
listen: "0.0.0.0:4317"
http:
listen: "0.0.0.0:4318"

host_metrics:
type: hostmetrics
collection_interval: 15s
scrapers: [cpu, memory, disk, network, load, processes]

docker_logs:
type: docker_logs

k8s_events:
type: k8s_events

processors:
k8s_enrich:
type: k8s_attributes
sources: [otlp_in, docker_logs, k8s_events]

batch_main:
type: batch
timeout: 5s
max_size: 10000
sources: [k8s_enrich, host_metrics]

sinks:
infrasage:
type: otlp
endpoint: "https://api.infrasage.dev"
protocol: http
auth_header: "Bearer ${INFRASAGE_API_KEY}"
sources: [batch_main]
kubectl apply -f configmap.yaml

3. Apply the DaemonSet and RBAC​

# daemonset.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: infrasagent
namespace: infrasage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: infrasagent
rules:
- apiGroups: [""]
resources: [pods, namespaces, nodes, events]
verbs: [get, list, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: infrasagent
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: infrasagent
subjects:
- kind: ServiceAccount
name: infrasagent
namespace: infrasage
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: infrasagent
namespace: infrasage
spec:
selector:
matchLabels:
app: infrasagent
template:
metadata:
labels:
app: infrasagent
spec:
serviceAccountName: infrasagent
tolerations:
- effect: NoSchedule
operator: Exists
containers:
- name: agent
image: ghcr.io/infrasagedev/sagent:latest
args: ["-config", "/etc/infrasagent/agent.yaml"]
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: INFRASAGE_API_KEY
valueFrom:
secretKeyRef:
name: infrasagent
key: api-key
ports:
- name: otlp-grpc
containerPort: 4317
- name: otlp-http
containerPort: 4318
- name: admin
containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/infrasagent
- name: docker-sock
mountPath: /var/run/docker.sock
readOnly: true
- name: host-proc
mountPath: /host/proc
readOnly: true
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
volumes:
- name: config
configMap:
name: infrasagent
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: host-proc
hostPath:
path: /proc
kubectl apply -f daemonset.yaml

4. Verify​

kubectl -n infrasage get pods
# NAME READY STATUS RESTARTS AGE
# infrasagent-x4k2p 1/1 Running 0 30s
# infrasagent-7j9qm 1/1 Running 0 30s

kubectl -n infrasage logs daemonset/infrasagent | tail -5

Helm chart​

No chart repository is published yet, so install from the chart in the agent repository:

git clone https://github.com/infrasagedev/sagent.git
cd sagent

helm install sagent ./deploy/helm/sagent \
--namespace infrasage \
--create-namespace \
--set config.sinks.infrasage.authHeader="Bearer ${INFRASAGE_API_KEY}"

Key values:

# values.yaml
image:
repository: ghcr.io/infrasagedev/sagent
tag: latest

daemonset:
enabled: true
tolerations:
- effect: NoSchedule
operator: Exists

resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi

config:
sources:
hostmetrics:
enabled: true
collection_interval: 15s
docker_logs:
enabled: true
k8s_events:
enabled: true
sinks:
infrasage:
endpoint: "https://api.infrasage.dev"
protocol: http
authHeader: "" # set via --set or existingSecret

Sending OTLP from pods​

Configure your applications to send OTLP to the agent running on the same node using the downward API:

# In your application pod
env:
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://$(NODE_IP):4318"
- name: OTEL_SERVICE_NAME
value: "my-service"