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 theenduraCLI, 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/vmlinuxon 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: linuxOmit 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.yamlVerify 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-sensorThe 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: NoScheduleVerify 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 enduraThe 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 hooksUninstall
helm uninstall endura-sensor --namespace endura
kubectl delete secret endura-sensor-secrets --namespace enduraThe 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=.lastTimestampCheck 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-sensorCheck 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.