Skip to content

Daemon Deployment on Kubernetes

This guide covers deploying the Riptides daemon as a DaemonSet on Kubernetes clusters. The daemon runs on every node, loads the Riptides kernel module, and connects to the control plane for identity issuance and policy enforcement.

  • Kubernetes 1.24+
  • Helm 3.2.0+
  • Privileged container support (required for kernel module loading)
  • Network connectivity from workload nodes to the control plane (ports 8443, 9443, 8001)
  • A running Riptides control plane (see Control Plane Deployment)

Install the daemon using the Riptides OCI Helm chart:

Terminal window
helm install riptides-daemon oci://ghcr.io/riptides-packages/helm/daemon --version version \
--namespace riptides-system \
--create-namespace \
-f daemon-values.yaml

The daemon Helm chart deploys a DaemonSet that runs on every node in your cluster. Each pod consists of:

  1. Driver loader init container — Loads the Riptides kernel module onto the host before the daemon starts. The init container runs privileged and uses a pre-built image matching your kernel version and distribution.

  2. Daemon container — The main daemon process that communicates with the kernel module (via /dev/riptides), connects to the control plane, manages certificates, and applies policies.

All daemon settings live under config.daemon:

ParameterDescriptionDefault
config.daemon.trustDomainSPIFFE trust domain (must match control plane)example.com
config.daemon.defaultCertTTLDefault TTL for issued workload certificates2h
config.daemon.dataDirPersistent data directory inside the container/data/riptides
config.daemon.kernelModuleDevicePath to the kernel module character device/host/dev/riptides

Settings under config.daemon.controlPlane:

ParameterDescriptionDefault
config.daemon.controlPlane.enabledEnable control plane connectiontrue
config.daemon.controlPlane.urlHTTPS base URL of the control planehttps://controlplane:8443
config.daemon.controlPlane.grpcServerAddressgRPC endpoint (host:port)none
config.daemon.controlPlane.tokenBrokerBaseURLToken broker endpoint URLnone
config.daemon.controlPlane.allowInsecureConnectionSkip TLS verification (development only)false
config.daemon.controlPlane.authPlugin.typeAuthentication plugin type (see below)joinToken

When using separate DNS records for each control plane service (typical in production), configure all three endpoints:

config:
daemon:
controlPlane:
url: https://cp.example.com
grpcServerAddress: grpc.example.com:443
tokenBrokerBaseURL: https://cp.example.com/token-broker

For daemons behind NAT or restrictive firewalls, configure a tunnel connection:

ParameterDescriptionDefault
config.daemon.tunnelServer.addressTunnel server endpoint (host:port)none
config:
daemon:
tunnelServer:
address: tunnel.example.com:443

The daemon authenticates to the control plane using one of these plugins:

A static shared token, suitable for development or initial bootstrapping:

config:
daemon:
controlPlane:
authPlugin:
type: joinToken
config:
token: "your-join-token-here"

Create the corresponding resources on the control plane:

apiVersion: auth.riptides.io/v1alpha1
kind: Verifier
metadata:
name: jointoken
namespace: riptides-system
spec:
joinToken: {}
---
apiVersion: auth.riptides.io/v1alpha1
kind: JoinToken
metadata:
name: my-join-token
namespace: riptides-system
spec:
token: "your-join-token-here"

Recommended for AWS deployments. The daemon uses the EC2 instance identity document for attestation — no shared secrets required:

config:
daemon:
controlPlane:
authPlugin:
type: AWSIID

Recommended for GCP deployments. Uses the GCP instance identity token:

config:
daemon:
controlPlane:
authPlugin:
type: GCPIIT

Metadata collectors enrich workload identity information with context from the runtime environment. Configure under config.daemon.metadataCollectors:

CollectorDescriptionDefault
procfsCollects process information from /procenabled: true
procfs.extractEnvsAlso collect environment variablesfalse
linuxosCollects OS release informationenabled: true
sysfsdmiCollects DMI/SMBIOS hardware infoenabled: true
ec2AWS EC2 instance metadataenabled: true
gcpGCP instance metadataenabled: true
azureAzure instance metadataenabled: true
kubernetesKubernetes pod and node metadataenabled: true
dockerDocker container metadataenabled: false

For the Kubernetes metadata collector:

ParameterDescriptionDefault
kubernetes.kubeletHostKubelet API hostlocalhost
kubernetes.kubeletPortKubelet API port10250
kubernetes.kubeletCAPath to kubelet CA certificate/etc/kubernetes/pki/ca.crt
kubernetes.skipKubeletVerificationSkip kubelet TLS verificationtrue
kubernetes.credentialsPath to service account token/var/run/secrets/kubernetes.io/serviceaccount/token

Disable cloud provider collectors that do not apply to your environment to avoid unnecessary metadata API calls:

config:
daemon:
metadataCollectors:
ec2:
enabled: true
gcp:
enabled: false
azure:
enabled: false

The driver loader init container loads the Riptides kernel module before the daemon starts:

ParameterDescriptionDefault
driverLoader.image.repositoryDriver loader imageghcr.io/riptides-packages/images/driver-loader
driverLoader.image.pullPolicyPull policyIfNotPresent
driverLoader.driverVersionDriver version (git branch, tag, or commit)main
driverLoader.commandTimeoutTimeout in seconds for load commands5
driverLoader.dynDBGEnable kernel dynamic debug for the modulefalse
ParameterDescriptionDefault
healthStatus.portDaemon health check port10100

A complete daemon-values.yaml for an AWS EKS cluster:

image:
tag: "v0.1.0"
pullPolicy: Always
driverLoader:
image:
tag: "v0.5.2"
driverVersion: "v0.1.0"
commandTimeout: 5
dynDBG: false
config:
daemon:
trustDomain: example.com
defaultCertTTL: 2h
dataDir: /data/riptides
metadataCollectors:
procfs:
enabled: true
extractEnvs: false
linuxos:
enabled: true
sysfsdmi:
enabled: true
ec2:
enabled: true
gcp:
enabled: false
azure:
enabled: false
kubernetes:
enabled: true
kubeletHost: localhost
kubeletPort: 10250
kubeletCA: /etc/kubernetes/pki/ca.crt
skipKubeletVerification: true
credentials: /var/run/secrets/kubernetes.io/serviceaccount/token
docker:
enabled: false
controlPlane:
enabled: true
url: https://cp.example.com
grpcServerAddress: grpc.example.com:443
tokenBrokerBaseURL: https://cp.example.com/token-broker
authPlugin:
type: AWSIID
tunnelServer:
address: tunnel.example.com:443
healthStatus:
port: 10100
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
tolerations:
- operator: Exists

Check that daemon pods are running on all nodes:

Terminal window
kubectl get pods -n riptides-system -l app.kubernetes.io/name=daemon -o wide

Check the driver loader init container logs to confirm the kernel module loaded:

Terminal window
kubectl logs -n riptides-system -l app.kubernetes.io/name=daemon -c daemon-driver-loader

Check the daemon logs for control plane connectivity:

Terminal window
kubectl logs -n riptides-system -l app.kubernetes.io/name=daemon -f

Verify health:

Terminal window
kubectl port-forward -n riptides-system daemonset/riptides-daemon 10100:10100
curl http://localhost:10100/healthz

If the init container fails, the kernel module loader may have failed. Check the kernel module loader init container.

Terminal window
kubectl logs -n riptides-system <failed-daemon-pod> -c daemon-driver-loader

Verify network connectivity from a workload node to the control plane endpoints:

Terminal window
kubectl run -n riptides-system netcheck --rm -it --image=busybox -- \
wget -qO- --timeout=5 https://cp.example.com:8443/healthz

Ensure your security groups or network policies allow outbound traffic to ports 8443, 9443, and 8001 on the control plane.

Check that the trust domain in the daemon configuration exactly matches the trust domain configured on the control plane. For join token auth, verify the token value matches the JoinToken resource on the control plane.

Terminal window
helm upgrade riptides-daemon oci://ghcr.io/riptideslabs/helm/daemon \
--namespace riptides-system \
-f daemon-values.yaml

The DaemonSet performs a rolling update by default. The driver loader init container will reload the kernel module on each node as pods restart.