Skip to content

Kubernetes

Deploy one Runtime Sensor per Linux node with the Endura Helm chart. The chart creates a privileged DaemonSet with the host namespaces and mounts required for eBPF enforcement.

Sensor and Build Lifecycles

  • The DaemonSet Sensor runs continuously on each eligible node.
  • Each build Pod mounts that node’s /run/endura, installs only the endura CLI, and runs its own job lifecycle.
  • Build Pods do not run another Sensor.

Prerequisites

  • Kubernetes 1.25 or later with supported 64-bit Linux nodes
  • Helm 3.12 or later and configured kubectl
  • Cluster permissions to create a namespace, DaemonSet, ServiceAccount, RBAC, ConfigMaps, and Secrets
  • Pod Security settings that allow the Sensor’s privileged host access
  • BTF at /sys/kernel/btf/vmlinux on every target node
  • At least 1 GB of allocatable memory per Sensor Pod
  • An Endura license key
  • Team Server URL and Sensor token for centralized management

The examples pin Sensor image 1.0.3 and chart 0.1.0. Kubernetes deployments must use immutable versions.

Create the Namespace and Secret

kubectl create namespace endura
kubectl create secret generic endura-sensor-secrets \
  --namespace endura \
  --from-literal=ENDURA_LICENSE_KEY='<license_key>' \
  --from-literal=ENDURA_SENSOR_TOKEN='<sensor_token>'

The chart injects every key in this Secret as an environment variable. Omit the Sensor token in standalone mode.

Configure Helm Values

Create values.yaml:

image:
  tag: "1.0.3"

sensor:
  env:
    ENDURA_TEAM_SERVER: "https://team-server.example.com"
    ENDURA_LOG_LEVEL: "info"

resources:
  limits:
    memory: 2Gi
  requests:
    cpu: 250m
    memory: 1Gi

nodeSelector:
  kubernetes.io/os: linux

Omit ENDURA_TEAM_SERVER for standalone mode. Add tolerations if the Sensor must run on tainted nodes.

The chart sets ENDURA_PROC_PATH=/host/proc, hostPID: true, hostIPC: true, privileged security context, and the required /proc, /sys, /run, /var/log, and host identity mounts.

Install

helm install endura-sensor \
  oci://ghcr.io/endurasecurity/helm/endura-sensor \
  --version 0.1.0 \
  --namespace endura \
  --values values.yaml

Verify one ready Sensor Pod is scheduled on each eligible node:

kubectl rollout status daemonset/endura-sensor --namespace endura
kubectl get pods --namespace endura --output wide
kubectl logs --namespace endura \
  --selector app.kubernetes.io/name=endura-sensor

The startup and readiness probes call /endura sensor status. They validate that the Sensor is serving locally, not that Team Server is reachable.

When centrally managed, confirm the Sensors and node deployments appear in Team Server.

Configure Node Selection

Use nodeSelector, affinity, and tolerations to match the nodes that run protected workloads. A build Pod can communicate only with the Sensor on its own node, so every eligible build node must run the DaemonSet.

nodeSelector:
  kubernetes.io/os: linux
  node-role.kubernetes.io/worker: ""

tolerations:
  - operator: Exists
    effect: NoSchedule

Verify placement with kubectl get pods -n endura -o wide and compare it with kubectl get nodes.

Instrument Build Pods

Build Pods mount the node’s control socket directory and run endura job stop from a shell trap. This example uses an emptyDir workspace:

apiVersion: batch/v1
kind: Job
metadata:
  name: protected-build
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: build
          image: docker.io/redhat/ubi9:latest
          workingDir: /workspace
          command: ["/bin/sh", "-c"]
          args:
            - |
              set -e
              curl -sSf https://repo.endurasecurity.com/install/endura-sensor/testing.sh | sh
              cleanup() { endura job stop /workspace --exit-zero; }
              trap cleanup EXIT
              endura sensor wait
              endura job start --workspace /workspace
              # Run build and test commands here.
          volumeMounts:
            - name: endura-run
              mountPath: /run/endura
            - name: workspace
              mountPath: /workspace
      volumes:
        - name: endura-run
          hostPath:
            path: /run/endura
            type: Directory
        - name: workspace
          emptyDir: {}

The workspace must exist and, for a non-root container, be owned by its user. Provider-specific instrumentation is documented under Pipeline Security.

Update

Review Team Server Compatibility, then pin both new versions:

CHART_VERSION=0.1.0
IMAGE_VERSION=1.0.3
helm upgrade endura-sensor \
  oci://ghcr.io/endurasecurity/helm/endura-sensor \
  --version "$CHART_VERSION" \
  --namespace endura \
  --values values.yaml \
  --set image.tag="$IMAGE_VERSION"

kubectl rollout status daemonset/endura-sensor --namespace endura

The DaemonSet updates Sensors node by node. Confirm hook coverage after a Sensor or node-kernel update.

Operate and Monitor

# Follow logs from every Sensor.
kubectl logs --namespace endura \
  --selector app.kubernetes.io/name=endura-sensor \
  --follow --prefix

# Run status in one Pod.
SENSOR_POD=$(kubectl get pods --namespace endura \
  --selector app.kubernetes.io/name=endura-sensor \
  --output jsonpath='{.items[0].metadata.name}')
kubectl exec --namespace endura "$SENSOR_POD" -- /endura sensor status
kubectl exec --namespace endura "$SENSOR_POD" -- /endura sensor hooks

Uninstall

helm uninstall endura-sensor --namespace endura
kubectl delete secret endura-sensor-secrets --namespace endura

The chart does not remove host log files or pinned state left outside Kubernetes objects. Confirm that no Sensor is running before cleaning /var/log/endura or /run/endura on nodes.

Troubleshooting

Pod Is Pending or Rejected

kubectl describe daemonset endura-sensor --namespace endura
kubectl get events --namespace endura --sort-by=.lastTimestamp

Check Pod Security admission, node selectors, taints, and allocatable resources.

Pod Crashes or Never Becomes Ready

kubectl logs --namespace endura \
  --selector app.kubernetes.io/name=endura-sensor \
  --previous
kubectl describe pods --namespace endura \
  --selector app.kubernetes.io/name=endura-sensor

Check the license, BTF, privileged access, and required host paths.

Build Pod Cannot Reach the Sensor

Confirm that a Sensor Pod is ready on the same node and that the build Pod mounts host /run/endura at /run/endura.

Some Hooks Are Missing

Run endura sensor hooks in the affected node’s Sensor Pod. Kernel version, LSM configuration, lockdown state, and verifier support determine attachment coverage.