Skip to content

Metrics

Collect container metrics from Kubernetes with cased-agent

Cased Telemetry collects infrastructure metrics from your Kubernetes cluster using cased-agent, a lightweight DaemonSet that captures container CPU, memory, network, and events.

  • Container Metrics - CPU, memory, network I/O for every container
  • Kubernetes Events - Pod restarts, OOM kills, scheduling events
  • Node Metrics - Host-level CPU and memory utilization
  • eBPF HTTP Tracing - Kernel-level HTTP request/response capture without application changes
  • Low Overhead - Minimal resource usage (10m CPU, 64Mi memory)
  • Kubernetes 1.21+
  • kubectl configured with cluster access
  • Cased API key (from organization settings)
Terminal window
helm install cased-agent oci://ghcr.io/cased/charts/cased-agent \
--namespace cased-system \
--create-namespace \
--set apiKey=YOUR_CASED_API_KEY \
--set clusterId=prod

For a simpler installation without Helm:

Terminal window
# Apply the manifest (creates namespace and RBAC)
kubectl apply -f https://raw.githubusercontent.com/cased/cased-agent/main/deploy/manifests/install.yaml
# Create the API key secret
kubectl -n cased-system create secret generic cased-agent \
--from-literal=api-key="YOUR_CASED_API_KEY"
# Set your cluster ID
kubectl -n cased-system set env daemonset/cased-agent CASED_CLUSTER_ID=prod
Terminal window
# Check DaemonSet status
kubectl -n cased-system get daemonset cased-agent
# View agent logs
kubectl -n cased-system logs -l app=cased-agent --tail=50
VariableRequiredDefaultDescription
CASED_API_KEYYes-Your organization API key
CASED_API_ENDPOINTNohttps://app.cased.comCased API endpoint
CASED_CLUSTER_IDNodefaultIdentifier for this cluster
CASED_ORG_IDNo-Organization ID (auto-detected from API key)
ENABLE_EBPFNotrue*Enable eBPF HTTP tracing (requires privileged mode)

*Default in provided manifest. Binary defaults to false if not set.

ArgumentDefaultDescription
--interval15sMetrics collection interval
--batch-size100Number of metrics per API request

The default resource configuration is designed for minimal overhead:

resources:
requests:
cpu: 10m
memory: 64Mi
limits:
cpu: 200m
memory: 256Mi

Adjust based on cluster size. For large clusters (100+ nodes), consider:

resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
MetricTypeDescription
cpu_usage_coresgaugeCurrent CPU usage in cores
cpu_throttled_secondscounterTime CPU was throttled
memory_usage_bytesgaugeCurrent memory usage
memory_limit_bytesgaugeMemory limit from cgroup
network_rx_bytescounterNetwork bytes received
network_tx_bytescounterNetwork bytes transmitted

Each metric includes labels for filtering:

  • cluster - Cluster ID from configuration
  • namespace - Kubernetes namespace
  • pod - Pod name
  • container - Container name
  • node - Node hostname

The cased-agent uses eBPF (Extended Berkeley Packet Filter) to capture HTTP requests and responses at the kernel level. This provides:

  • Zero-instrumentation observability - No code changes or sidecars required
  • Complete visibility - Captures all HTTP traffic, including internal service-to-service calls
  • Low overhead - eBPF runs in kernel space with minimal performance impact
  • Cross-kernel portability - Uses CO:RE (Compile Once - Run Everywhere) for compatibility across kernel versions

eBPF programs attach to kernel syscalls (sendto, recvfrom) to intercept network data. The agent parses HTTP method, path, and status code from the raw bytes, then sends this data to Cased for correlation with errors and metrics.

┌─────────────────────────────────────────────────────────────┐
│ Kernel Space │
│ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │
│ │ sendto() │────>│ eBPF probe │────>│ Ring buffer │ │
│ │ recvfrom() │ │ (http_trace)│ │ │ │
│ └─────────────┘ └─────────────┘ └───────┬───────┘ │
└─────────────────────────────────────────────────┬─────────┘
┌─────────────────────────────────────────────────▼─────────┐
│ User Space │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ cased-agent: parse HTTP, enrich with K8s labels, │ │
│ │ send to Cased API │ │
│ └─────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘

If you don’t need HTTP tracing or can’t run privileged containers, disable eBPF:

env:
- name: ENABLE_EBPF
value: "false"

With eBPF disabled, the agent still collects container metrics and Kubernetes events, but won’t capture HTTP traffic.

The cased-agent requires elevated permissions to collect comprehensive telemetry. This section explains what’s required and why.

When eBPF HTTP tracing is enabled, the agent requires privileged mode:

securityContext:
privileged: true
capabilities:
add:
- SYS_PTRACE # Read process info from /proc
- SYS_ADMIN # Load eBPF programs into kernel
- NET_ADMIN # Attach to network syscalls

Why privileged mode?

eBPF programs run in kernel space and require CAP_SYS_ADMIN to load. While Kubernetes supports granular capabilities, eBPF verifier and BTF (BPF Type Format) access typically require privileged mode for reliable operation across different kernel versions and cloud providers.

This is the same approach used by other eBPF-based observability tools like Groundcover, Cilium, and Pixie.

Additional mounts required:

  • /sys/kernel/debug (read-only) - Access BTF type information for CO:RE

When eBPF is disabled, the agent requires minimal permissions:

  • hostPID: true - Access to /proc for container metrics
  • SYS_PTRACE - Read process information from /proc
  • ClusterRole - Read-only access to pods, nodes, namespaces, events

The agent’s ClusterRole has read-only access:

rules:
- apiGroups: [""]
resources: ["pods", "nodes", "namespaces", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list"]
  1. Dedicated namespace - Deploy in cased-system to isolate from application workloads
  2. Network policies - Restrict egress to only Cased API endpoints
  3. Image scanning - The cased-agent image is regularly scanned for vulnerabilities
  4. Audit logging - Enable Kubernetes audit logs to monitor privileged container activity
  5. Pod Security Standards - If using PSS, you’ll need to exempt cased-system namespace from restricted policies

Check pod status:

Terminal window
kubectl -n cased-system describe pod -l app=cased-agent

Common issues:

  • Missing secret: Create the cased-agent-config secret
  • Image pull error: Verify ECR access or use public image
  1. Verify the agent is healthy:
Terminal window
kubectl -n cased-system logs -l app=cased-agent | grep -i error
  1. Check API connectivity:
Terminal window
kubectl -n cased-system exec -it $(kubectl -n cased-system get pod -l app=cased-agent -o jsonpath='{.items[0].metadata.name}') -- wget -qO- https://app.cased.com/health
  1. Verify API key is valid in Cased dashboard

If the agent uses more resources than expected:

  • Increase --interval to collect less frequently
  • Reduce --batch-size to send smaller payloads
  • Check for network issues causing retries

If you see “eBPF HTTP tracing disabled” in logs when it should be enabled:

  1. Check privileged mode:
Terminal window
kubectl -n cased-system get pod -l app=cased-agent -o jsonpath='{.items[0].spec.containers[0].securityContext.privileged}'
# Should return: true
  1. Verify kernel supports BTF:
Terminal window
kubectl -n cased-system exec -it $(kubectl -n cased-system get pod -l app=cased-agent -o jsonpath='{.items[0].metadata.name}') -- ls /sys/kernel/btf/vmlinux

Most modern kernels (5.4+) include BTF. If missing, the eBPF program can’t load with CO:RE.

  1. Check debugfs is mounted:
Terminal window
kubectl -n cased-system exec -it $(kubectl -n cased-system get pod -l app=cased-agent -o jsonpath='{.items[0].metadata.name}') -- ls /sys/kernel/debug
  1. Review agent logs for eBPF errors:
Terminal window
kubectl -n cased-system logs -l app=cased-agent | grep -i ebpf

If you see “operation not permitted” errors:

  • Ensure privileged: true is set in the DaemonSet
  • Verify capabilities include SYS_ADMIN and NET_ADMIN
  • Check if Pod Security Policies/Standards are blocking privileged containers

To run without eBPF, set ENABLE_EBPF=false (metrics collection still works).

Terminal window
kubectl delete -f install.yaml