> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiaxoniq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Install on Kubernetes

> Deploy the zero-code agent as a DaemonSet with Helm: values, profiles, bringing your own Secret, air-gapped installs, and what the chart renders.

One DaemonSet, one pod per node, observing every workload on that node.

<Warning>
  **Availability.** The zero-code agent is an early-access distribution. It is
  installable, upgradable and tested, and it is **not yet an integrated part of
  the product**: there is no dashboard page for it, no in-product installer and
  no self-service download. Ask your account contact for access.

  Its telemetry, once flowing, is ordinary OTLP and needs nothing special —
  it appears in Services, Traces and Metrics exactly like SDK telemetry does.
  That is the design rather than a shortcut.
</Warning>

<Info>
  **Before you start, you need two values.**

  1. **Your base endpoint** — shown on **Get Started** in the dashboard. These
     pages write it as `$OIQ_ENDPOINT`.
  2. **A license key** — created in **Settings → License Keys**, starting
     `oiq_`. Requires the Admin role. See
     [Create a license key](/get-started/license-keys). These pages write it as
     `$OIQ_LICENSE_KEY`.

  Export both before running anything below:

  ```bash theme={null}
  export OIQ_ENDPOINT="https://app.aiaxoniq.com/otlp"   # or your own
  export OIQ_LICENSE_KEY="oiq_..."
  ```
</Info>

## Before you install

The kernel belongs to the **node**, so the requirements apply there — your
workloads' base images are irrelevant. Check a node with the preflight tool
before rolling anything out; see
[Install on Linux](/zero-code/linux#1-check-the-host-first).

<Warning>
  **On EKS and AKS, set `kernel.perf_event_paranoid=1` on your nodes.**

  Above 1 the kernel denies perf-event access even with the right capability,
  and the agent starts, reports healthy and collects nothing. Upstream's
  documented workaround is to grant `CAP_SYS_ADMIN` instead — which is
  near-root **on every node**. Set the sysctl.

  ```bash theme={null}
  sudo sysctl -w kernel.perf_event_paranoid=1
  echo 'kernel.perf_event_paranoid=1' | sudo tee /etc/sysctl.d/99-aiaxoniq.conf
  ```
</Warning>

## Install

```bash theme={null}
helm install aiaxoniq-zerocode ./helm/aiaxoniq-zerocode \
  -n aiaxoniq --create-namespace \
  --set endpoint="$OIQ_ENDPOINT" \
  --set licenseKey="$OIQ_LICENSE_KEY" \
  --set clusterName=prod-eu
```

<Note>
  **Set `clusterName`.** Without it, two clusters reporting to one organization
  are indistinguishable in the service map — the same service name from two
  places, silently merged. The chart warns on install; the warning is worth
  acting on.
</Note>

## Inspect before you install

Recommended, and exactly what a security review will ask for. Render the chart
and read what it would create, without touching the cluster:

```bash theme={null}
helm template aiaxoniq-zerocode ./helm/aiaxoniq-zerocode \
  --set endpoint="$OIQ_ENDPOINT" --set licenseKey=dummy \
  | grep -A14 securityContext
```

The default profile renders:

```yaml theme={null}
securityContext:
  runAsUser: 0
  readOnlyRootFilesystem: true
  capabilities:
    add: [BPF, SYS_PTRACE, NET_RAW, CHECKPOINT_RESTORE, DAC_READ_SEARCH, PERFMON]
    drop: [ALL]
```

No `privileged`, no `SYS_ADMIN`, no `NET_ADMIN`.

The DaemonSet also sets `hostPID: true` — **required**, because without a
shared PID namespace the agent sees only itself and silently reports nothing —
and requests `list` and `watch` on pods, services, nodes and replicasets,
read-only, solely to decorate telemetry with Kubernetes metadata.

## Profiles

```bash theme={null}
helm install ... -f ./helm/aiaxoniq-zerocode/profiles/profile-b.yaml   # default
helm install ... -f ./helm/aiaxoniq-zerocode/profiles/profile-c.yaml   # adds NET_ADMIN
```

<Warning>
  **Profile A is not available on Kubernetes.** The upstream chart hardcodes a
  six-capability floor for unprivileged mode, so a three-capability profile
  cannot be expressed through it without forking.

  The chart **refuses it by name** rather than quietly granting six
  capabilities and still calling it "network only". Your choice here is B or C
  — see [Capability profiles](/zero-code/profiles).
</Warning>

## Bring your own Secret

If you manage credentials with an external secrets operator, the chart never
needs to see the key at all:

```bash theme={null}
kubectl -n aiaxoniq create secret generic my-oiq \
  --from-literal=otlp-headers="X-License-Key=$OIQ_LICENSE_KEY"

helm install aiaxoniq-zerocode ./helm/aiaxoniq-zerocode \
  --set endpoint="$OIQ_ENDPOINT" --set existingSecret=my-oiq
```

<Info>
  **The key is never in the ConfigMap** — with or without your own Secret. That
  is asserted by a test, which means `kubectl get configmap` stays a safe
  debugging step you can hand to anyone.

  Issue the agent its own key, scoped to traces and metrics, because a
  DaemonSet places it on every node. See
  [Security model](/zero-code/security#scope-the-key).
</Info>

## Air-gapped clusters

The upstream chart is vendored, so `helm lint`, `helm template` and `helm
package` need no network access. Mirror the agent image into your registry and
point the chart at it with `image.registry`.

<Note>
  **The Linux installer is the path that needs outbound access**, because it
  downloads and checksum-verifies upstream artefacts at install time. The
  Kubernetes path pulls an image instead, so mirroring is the whole of the
  problem. See [OpenTelemetry OBI](/zero-code/obi#licensing).
</Note>

## One release per namespace

<Warning>
  **You cannot install two releases of the chart into one namespace.** The
  agent ConfigMap has a fixed name, because the upstream chart consumes it as a
  plain value rather than a template.

  This is a constraint you would want anyway: two DaemonSets both instrumenting
  every process on every node would double both the overhead and the telemetry.
  Helm fails loudly on the collision rather than producing a half-working
  install.
</Warning>

## Verify the rollout

```bash theme={null}
kubectl -n aiaxoniq rollout status daemonset -l app.kubernetes.io/name=opentelemetry-ebpf-instrumentation
kubectl -n aiaxoniq logs -l app.kubernetes.io/name=opentelemetry-ebpf-instrumentation --tail=50
```

Pods running is not the same as telemetry arriving. See
[Verification](/zero-code/verification).

## Managed Kubernetes support

| Platform                                      | Status                                                                          |
| :-------------------------------------------- | :------------------------------------------------------------------------------ |
| k3s / k3d                                     | **Validated** — full install, rollout and teardown                              |
| kind, minikube, kubeadm, RKE2                 | Expected; depends on the node kernel                                            |
| EKS on EC2 nodes, AKS                         | Expected — **set the perf-event sysctl on nodes**                               |
| GKE Standard                                  | Expected; both common node images carry the required kernel type information    |
| OpenShift 4.x                                 | Expected — needs the shipped constraints, see [OpenShift](/zero-code/openshift) |
| EKS Fargate, GKE Autopilot, AKS Virtual Nodes | **Unsupported** — no node access, no DaemonSet                                  |

<Note>
  **The rule: if you control the node, the agent works.** Where you do not —
  Fargate, Autopilot, Cloud Run, container instances — use the OpenTelemetry
  SDK or a sidecar Collector instead. See
  [Kubernetes with a Collector](/send-data/platforms/kubernetes).
</Note>

The full matrix is on [Compatibility](/zero-code/compatibility).

## Next

<CardGroup cols={3}>
  <Card title="OpenShift" icon="shield-halved" href="/zero-code/openshift">
    The SecurityContextConstraints, and why running privileged is the wrong fix.
  </Card>

  <Card title="Verification" icon="circle-check" href="/zero-code/verification">
    Confirm data is arriving.
  </Card>

  <Card title="Troubleshooting" icon="triangle-exclamation" href="/zero-code/troubleshooting">
    Including missing Kubernetes metadata.
  </Card>
</CardGroup>
