How it works
The collector binary is the samedag-fargate-agent used on ECS Fargate; it detects at startup that it is running in a Kubernetes pod rather than a Fargate task. It runs as PID 1 inside your application container, installs a seccomp-BPF filter that traps only the ~20 syscalls Hilt cares about (execve, open, unlink, rename, chmod, connect, etc.), then fork+execs your original application. Every descendant process inherits the filter; everything else runs at native speed, uninstrumented. All of this happens inside the pod’s guest VM — nothing needs to cross the hypervisor boundary.
You do not rebuild your application image. An initContainer (the same installer image used for Fargate) copies the agent binary into a pod-scoped emptyDir volume before your app starts; the container’s command is rewritten to launch the agent first, which then launches your original command.
This mechanism is for pods whose
runtimeClassName puts them behind a guest kernel (Kata, and by extension other VM-isolated runtimes). Ordinary runc pods on the same cluster should keep using the eBPF DaemonSet — it has strictly more coverage. The two coexist: the DaemonSet simply cannot see Kata pods, and the in-workload agent fills exactly that hole.Prerequisites
- A Kubernetes cluster with a Kata runtime class (e.g.
runtimeClassName: kata),x86_64orarm64 - A reachable Hilt ingest endpoint (
DAG_SHIP_URL, provided during onboarding) - The installer image URI Hilt gives you at onboarding (the same
dag-fargate-installerimage used for ECS Fargate). The nodes must be able to pull it.
What gets injected into your pod spec
If something fails to attach at runtime, the agent fails open: your application always starts and runs normally, with or without telemetry.
Installation
There are two ways to get the collector into Kata pods. Both produce the same pod spec.Automatic injection (admission webhook)
Thedag-kata-injector webhook watches pod creation. Every pod whose runtimeClassName is kata or starts with kata- (kata-qemu, kata-clh, kata-fc, …) is created with the collector already wrapped around its entrypoint. Ordinary runc pods are never sent to the webhook. Pods that already exist are not changed; they pick up the collector the next time they are recreated (a rollout, a reschedule, or a scale-up).
1
Apply the manifest
Download Use the same
kata-injector.yaml for your collector version (it ships next to daemonset.yaml), fill in the placeholders, and apply it:DAG_CLUSTER_ID as your DaemonSet so Kata pods and node-level telemetry group under one cluster. No cert-manager is needed: the webhook creates its own TLS certificate on first start.2
Roll a Kata workload
injected mode=full containers=…. If a pod was not injected, it says why.-
Pod Security. In namespaces that enforce the Pod Security
baselineorrestrictedlevel,SYS_PTRACEis not allowed, so pods there are injected inmetadatamode (no capability). If your API server enforcesbaselinecluster-wide through its admission configuration, setDAG_INJECT_DEFAULT_MODE=metadataon the webhook. -
Image entrypoints. Kubernetes
commandreplaces an image’sENTRYPOINTinstead of prepending to it. For containers that don’t setcommand, the webhook reads the originalENTRYPOINT/CMDfrom the image registry (public images by default). For private registries, enableDAG_INJECT_PULL_SECRETS=true(and the optional secret-read rule in the manifest), setcommandexplicitly, or annotate the pod:A container whose entrypoint cannot be determined is left unwrapped rather than started with a guessed command. The pod gets adag.hilt.ai/inject-skippedannotation andkubectlshows a warning.
Manual injection (pod template patch)
Use this if you cannot run an admission webhook in your cluster.1
Add the volume and initContainer
In your pod template (Deployment, StatefulSet, Job — anything that produces a pod spec):
2
Wrap your container's entrypoint
Rewrite the app container’s
command so the agent starts first. If your image relies on its default ENTRYPOINT/CMD, spell them out explicitly — Kubernetes command/args replace, they never prepend.3
Add environment and identity
There is no metadata endpoint inside the guest VM, so the pod spec hands the agent its own coordinates via the downward API:The agent never contacts the Kubernetes API server — identity is entirely env-driven, so no serviceaccount token or RBAC is needed.
4
Roll out and verify
Apply the change and check the wrapped container’s logs: the line
kata: identity loaded — host_id=<pod-uid> host_type=kata … appears on stderr before your application’s own output.deploy/kata/pod-reference.yaml.
Configuration
Coverage
Matches the ECS Fargate collector — precise exec/file/network-lifecycle events via seccomp+ptrace in full mode, and themetadata kill-switch mode — with one Kata-specific difference: network byte counters are not available. The sampled sock_diag byte counters need INET_DIAG in the kernel serving the pod, and Kata’s default guest kernels are built without it, so on Kata the agent reports network connection lifecycle (who connected where, when) without byte volumes. If your Kata deployment ships a custom guest kernel with CONFIG_INET_DIAG, byte sampling lights up automatically. Data-flow lineage, cgroup lifecycle events, and latency probes are eBPF-collector features and are not available inside VM-isolated pods. Visibility is scoped to the wrapped container’s process subtree — one agent per wrapped container.
Identity mapping
Kata pods are as ephemeral as Fargate tasks. Expect turnover in the fleet view; the
namespace and pod_name tags (and your own DAG_TAGS) give you stable grouping across pod restarts.Verification
After deploying, confirm on the Collectors page that:- The pod appears with
host_type=kata - It’s grouped under the correct
DAG_CLUSTER_ID - The
pod_name,namespace, andruntime_classtags are present - Exec and network events are arriving
Upgrade
Update the installer image tag (DAG_INJECT_INSTALLER_IMAGE on the webhook, or the initContainer image in a patched template) and roll the workload. The agent binary is copied fresh from the initContainer on every pod start, so a new pod always picks up the latest agent.
Uninstall
Automatic:kubectl delete -f kata-injector.yaml (and the dag-kata-injector-tls Secret), then roll your Kata workloads. New pods are created without the collector.
Manual: Remove the injected pieces (initContainer, emptyDir volume, command rewrite, SYS_PTRACE capability, and DAG_* environment variables) from the pod template and roll the workload.