Module 5 of 13

Running SPIRE on Kubernetes

Deploy and operate SPIRE in real Kubernetes clusters

4 hours4 labsFree

Start here

Learning objectives

  • Deploy SPIRE Server and Agent on Kubernetes
  • Configure Kubernetes workload and node attestors
  • Use SPIRE Controller Manager for automatic registration
  • Retrieve SVIDs inside pods
SPIRE ON KUBERNETESKubernetes ClusterSPIRE Server (StatefulSet)+ Controller Manager + DatastoreAgent (DaemonSet)Node 1Agent (DaemonSet)Node 2Agent (DaemonSet)Node 3Pod (SVID)Pod (SVID)Pod (SVID)Pod (SVID)SPIRE CSI DriverMounts Workload API socket

This is where SPIRE becomes real. In this module, you deploy SPIRE on Kubernetes, register workloads, and watch pods receive cryptographic identities automatically. This is the hands-on foundation for everything that follows.

Kubernetes Identity Challenges

Kubernetes provides service account tokens, but they were not designed for workload identity. Default tokens are long-lived (no expiration until K8s 1.24+), shared across all pods using the same service account, not cryptographic certificates (cannot be used for mTLS), and not verifiable across clusters.

SPIRE Kubernetes Architecture

SPIRE on Kubernetes consists of the SPIRE Server running as a StatefulSet, the SPIRE Agent running as a DaemonSet on every node, the SPIRE Controller Manager that auto-registers workloads, and the SPIRE CSI Driver that mounts the Workload API socket into pods.

Deploying SPIRE Server

# spire-server.yaml (simplified)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: spire-server
  namespace: spire
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spire-server
  template:
    spec:
      containers:
        - name: spire-server
          image: ghcr.io/spiffe/spire-server:1.9
          ports:
            - containerPort: 8081  # Server API
          volumeMounts:
            - name: spire-config
              mountPath: /run/spire/config
            - name: spire-data
              mountPath: /run/spire/data

Deploying SPIRE Agent

# spire-agent.yaml (simplified)
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: spire-agent
  namespace: spire
spec:
  selector:
    matchLabels:
      app: spire-agent
  template:
    spec:
      containers:
        - name: spire-agent
          image: ghcr.io/spiffe/spire-agent:1.9
          volumeMounts:
            - name: spire-agent-socket
              mountPath: /run/spire/sockets

Automatic Workload Registration

The SPIRE Controller Manager watches Kubernetes for pod creations and automatically creates registration entries based on annotations or ClusterSPIFFEID resources. This eliminates manual registration.

# ClusterSPIFFEID resource for auto-registration
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: default-workloads
spec:
  spiffeIDTemplate: "spiffe://example.org/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
  podSelector:
    matchLabels: {}  # Match all pods
  namespaceSelector:
    matchExpressions:
      - key: kubernetes.io/metadata.name
        operator: NotIn
        values: ["kube-system", "spire"]

Retrieving SVIDs Inside Pods

# Using spiffe-helper to write SVIDs to disk:
# The pod mounts the Workload API socket via CSI driver
# spiffe-helper fetches SVIDs and writes them as files:
# /run/spire/certs/svid.pem       (X.509 certificate)
# /run/spire/certs/svid_key.pem   (private key)
# /run/spire/certs/bundle.pem     (trust bundle)

# Applications read these files for mTLS configuration

Real world

Where this shows up

  • Production Kubernetes clusters with hundreds of services needing identity
  • Multi-tenant clusters where different teams own different namespaces
  • Auto-scaling environments where pods spin up and need instant identity
  • GitOps workflows where workload registration is declarative via ClusterSPIFFEID

Production notes

Keep these close

  • Use the SPIRE CSI Driver to mount the Workload API socket into pods. It is cleaner than hostPath volumes and provides proper lifecycle management.
  • In production, always run SPIRE Server as a StatefulSet with persistent storage. Losing the datastore means losing all registration entries.
  • Monitor SVID rotation continuously. A stalled rotation means certificates will expire and services will fail.

Common mistakes

What usually breaks

  • Deploying SPIRE Agent as a sidecar instead of a DaemonSet
  • Forgetting to create the spire-bundle ConfigMap before starting agents
  • Using the wrong cluster name in k8s_psat attestor config
  • Not giving SPIRE Server RBAC permissions for tokenreviews
  • Setting SVID TTL too short without monitoring rotation success

Security risks

Threats to watch

  • SPIRE Agent runs with hostPID — a compromised agent can see all processes on the node
  • ClusterSPIFFEID with empty matchLabels registers ALL pods — scope it to specific namespaces
  • Workload API socket mounted via hostPath can be accessed by any pod if not properly secured

Key terms

Vocabulary used in this module

DaemonSet

Kubernetes resource that runs one pod per node

StatefulSet

Kubernetes resource for stateful applications with persistent storage

ClusterSPIFFEID

Custom resource for automatic workload registration

CSI Driver

Container Storage Interface driver for mounting Workload API socket

k8s_psat

Kubernetes Projected Service Account Token attestor

Labs

Hands-on labs

Deploying SPIRE on Kind

Deploy a full SPIRE stack on a local Kind cluster.

  1. Create a Kind cluster with 3 worker nodes
  2. Deploy SPIRE Server as a StatefulSet
  3. Deploy SPIRE Agent as a DaemonSet
  4. Verify server-agent connectivity
View lab on GitHub

Registering Kubernetes Workloads

Register workloads and verify SVID issuance.

  1. Deploy SPIRE Controller Manager
  2. Create ClusterSPIFFEID resources
  3. Deploy a demo application pod
  4. Verify the pod receives an X.509-SVID
View lab on GitHub

Automatic Identity Rotation

Observe SVID rotation without application restart.

  1. Set SVID TTL to 5 minutes for testing
  2. Monitor the SVID expiration timestamp
  3. Observe automatic rotation before expiry
  4. Verify the application continues without interruption
View lab on GitHub

Debugging Failed Attestation

Troubleshoot common SPIRE deployment issues.

  1. Intentionally misconfigure a workload selector
  2. Observe the attestation failure in agent logs
  3. Fix the registration entry
  4. Verify successful attestation after the fix
View lab on GitHub

Recap

Key takeaways

  • SPIRE Server runs as a StatefulSet, Agent as a DaemonSet
  • SPIRE Controller Manager auto-registers workloads from Kubernetes metadata
  • CSI Driver mounts the Workload API socket into pods transparently
  • SVIDs rotate automatically — applications never handle certificate renewal
  • ClusterSPIFFEID resources define SPIFFE ID templates for automatic registration
  • Debug attestation failures by checking agent logs and registration entry selectors

Related resources

Keep learning across CodersSecret