Skip to main content

Module 5: Running SPIRE on Kubernetes

Deploy and operate SPIRE in real Kubernetes clusters

4 hours. 4 hands-on labs. Free course module.

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

Why This Matters

This is where SPIRE becomes real. Deploying on Kubernetes is the most common production scenario, and the skills you build here — deploying, registering, debugging — are exactly what you will use every day as a platform engineer operating SPIRE.

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
Architecture diagram for Module 5: Running SPIRE on Kubernetes.

Lesson Content

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 Use Cases

  • 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

  • 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

  • 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 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

Production Story

A platform team deployed SPIRE on a 200-node cluster. Initial deployment went smoothly, but auto-scaling kept creating nodes that could not attest. The root cause: the k8s_psat attestor had a typo in the cluster name. One config fix later, new nodes joined automatically within seconds of creation.

Career Relevance

Kubernetes is the dominant container orchestrator, and SPIRE on Kubernetes is the most common production deployment model. This module gives you the hands-on skills that platform engineering and DevOps job descriptions increasingly list as requirements.

Key Terms

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

Hands-On Labs

  1. Deploying SPIRE on Kind

    Deploy a full SPIRE stack on a local Kind cluster.

    • Create a Kind cluster with 3 worker nodes
    • Deploy SPIRE Server as a StatefulSet
    • Deploy SPIRE Agent as a DaemonSet
    • Verify server-agent connectivity

    View lab files on GitHub

  2. Registering Kubernetes Workloads

    Register workloads and verify SVID issuance.

    • Deploy SPIRE Controller Manager
    • Create ClusterSPIFFEID resources
    • Deploy a demo application pod
    • Verify the pod receives an X.509-SVID

    View lab files on GitHub

  3. Automatic Identity Rotation

    Observe SVID rotation without application restart.

    • Set SVID TTL to 5 minutes for testing
    • Monitor the SVID expiration timestamp
    • Observe automatic rotation before expiry
    • Verify the application continues without interruption

    View lab files on GitHub

  4. Debugging Failed Attestation

    Troubleshoot common SPIRE deployment issues.

    • Intentionally misconfigure a workload selector
    • Observe the attestation failure in agent logs
    • Fix the registration entry
    • Verify successful attestation after the fix

    View lab files on GitHub

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