Kubernetes
This guide walks you through installing the SPIRL Agent on a Kubernetes cluster using the official Helm chart. The SPIRL Agent runs as a DaemonSet and provides SPIFFE identity services to workloads running in your cluster.
Prerequisites
Before installing the SPIRL Agent, ensure you have:
- A running Kubernetes cluster
kubectl
configured to access your cluster- Helm 3.x installed
- A deployed SPIRL Trust Domain Server
- Cluster registration details from your Trust Domain Server
We'll deploy the SPIRL Agent to the cluster using the Helm chart. You'll need to provide the following values to the Helm chart:
- Endpoint - the address of the Trust Domain server you previously deployed. e.g.
td-server.spirl.example.com
- ClusterVersionID - the Cluster Version ID you recorded after registering the cluster
with the Trust Domain server. e.g.
cv-1r0yfu9yjy
- PrivateKey - the Private Key you recorded after registering the cluster with the Trust Domain server.
Here is a sample values file:
agent:
endpoint:
endpoint: "td-server.spirl.example.com"
auth:
key:
id: "cv-1r0yfu9yjy"
pem: |
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIIsMdMEaZz+WVkIkiCzHHGWmvnyWiyhwFmxgKdUbTzRy
-----END PRIVATE KEY-----
Download the latest SPIRL Agent
You can download the latest version of the Helm chart by running the following command.
helm pull oci://ghcr.io/spirl/charts/spirl-system -d .
Deploy SPIRL Agent
You can deploy the SPIRL Agent to the cluster using the following command:
helm upgrade --install --namespace spirl-system --create-namespace --values ./values.yaml spirl-system ./spirl-system-0.23.0.tgz
You should see the following output:
Release "spirl-system" does not exist. Installing it now.
NAME: spirl-system
LAST DEPLOYED: Tue Dec 19 14:02:09 2023
NAMESPACE: spirl-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
Verify SPIRL Agent Deployment
Check your target namespace for the SPIRL Agent pods and verify that they are running. You can also check the logs of the SPIRL Agent pods to verify that they are connected to the SPIRL Trust Domain Server.
kubectl -n spirl-system logs $(kubectl -n spirl-system get pods -o name | grep "spirl-agent" | head -n 1)
For successful deployment you should see the following log message:
{"level":"info","ts":1703024269.4806662,"logger":"bundleRefresher","msg":"Bundle added or updated","trustDomain":"spirl.example.com"}
The trustDomain
key will contain the name of your trust domain.
Disable TLS for SPIRL Agent and SPIRL Trust Domain Server Communication
By default, SPIRL Agent and SPIRL Trust Domain server communicate over TLS. However, in
some scenarios (e.g. lab environments) you may want to disable TLS for SPIRL Agent and
SPIRL Trust Domain server communication. You can do that by editing the spirl-agent
daemonset and adding SPIRL_ENDPOINT_ENABLE_TLS
environment variable with the "false"
value.
If you are using HELM to install the agent, you can set the env variable in the values file.
agent:
env:
- name: SPIRL_ENDPOINT_ENABLE_TLS
value: "false"
Working with Node Taints and Tolerations
If your Kubernetes cluster has tainted nodes that require tolerations for pod scheduling, you can configure tolerations for the SPIRL Agent components. This is particularly useful when deploying on:
- Nodes with dedicated workloads
- Master/control plane nodes
- Nodes with special hardware requirements
- Nodes with specific scheduling constraints
Different SPIRL components have different scheduling requirements:
- Agent & CSI Driver: Must run on every node that hosts workloads requiring SPIFFE identities. These components need the same tolerations to ensure they can be scheduled on all workload nodes.
- Controller: Only needs to run somewhere in the cluster and can be scheduled independently. You may want different (or no) tolerations for the controller, allowing it to run on dedicated management nodes.
Example: Agent and CSI Driver Tolerations
For workloads running on tainted nodes, configure the agent and CSI driver with matching tolerations:
agent:
endpoint:
endpoint: "td-server.spirl.example.com"
auth:
key:
id: "cv-1r0yfu9yjy"
pem: |
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIIsMdMEaZz+WVkIkiCzHHGWmvnyWiyhwFmxgKdUbTzRy
-----END PRIVATE KEY-----
tolerations:
- key: "node.kubernetes.io/unschedulable"
operator: "Exists"
effect: "NoSchedule"
- key: "dedicated"
operator: "Equal"
value: "workload"
effect: "NoSchedule"
csiDriver:
tolerations:
- key: "node.kubernetes.io/unschedulable"
operator: "Exists"
effect: "NoSchedule"
- key: "dedicated"
operator: "Equal"
value: "workload"
effect: "NoSchedule"
Example: Controller with Different Tolerations
The controller can be configured with different tolerations, or run on untainted nodes:
# Option 1: Controller on management nodes
controller:
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
# Option 2: Controller with no specific tolerations (runs on any untainted node)
# controller: {}
# Option 3: Controller tolerating all taints
controller:
tolerations:
- operator: "Exists"
Common Toleration Patterns
Tolerate all taints:
agent:
tolerations:
- operator: "Exists"
Tolerate specific key with any value:
agent:
tolerations:
- key: "dedicated"
operator: "Exists"
effect: "NoSchedule"
Tolerate specific key-value pair:
agent:
tolerations:
- key: "node-type"
operator: "Equal"
value: "compute"
effect: "NoSchedule"
Working with Custom Docker Registries
Many enterprise environments require pulling images from private registries or through registry proxies. The SPIRL Agent Helm chart supports custom registries and image pull secrets for secure image access.
SPIRL Agent uses multiple container images from different sources:
- SPIRL Images: Agent, Controller, and Reflector (default:
ghcr.io/spirl
) - SPIFFE CSI Driver: From the SPIFFE project (default:
ghcr.io/spiffe
) - Kubernetes CSI Registrar: From Kubernetes SIG Storage (default:
registry.k8s.io/sig-storage
)
You can configure each component to use your custom registry independently.
Creating Image Pull Secrets
Before deploying, create the required image pull secrets:
kubectl create secret docker-registry my-registry-secret \
--namespace spirl-system \
--docker-server=my-registry.company.com \
--docker-username=myuser \
--docker-password=mypassword
Configuration Examples
Private Registry with Authentication:
images:
repository: "my-registry.company.com/spirl"
pullSecrets:
- name: "my-registry-secret"
csiDriver:
repository: "my-registry.company.com/spiffe"
csiNodeDriverRegistrar:
repository: "my-registry.company.com/sig-storage"
Registry Proxy/Mirror:
images:
repository: "proxy.company.com/ghcr.io/spirl"
csiDriver:
repository: "proxy.company.com/ghcr.io/spiffe"
csiNodeDriverRegistrar:
repository: "proxy.company.com/registry.k8s.io/sig-storage"
Air-Gapped Environment (Pin Versions):
images:
repository: "internal-registry.local/spirl"
pullSecrets:
- name: "internal-registry-secret"
agent:
tag: "v1.2.3"
controller:
tag: "v1.2.3"
csiDriver:
tag: "0.2.7"
repository: "internal-registry.local/spiffe"
csiNodeDriverRegistrar:
tag: "v2.14.0"
repository: "internal-registry.local/sig-storage"
Helm Values Reference
This section provides a comprehensive reference for all configuration options available in the SPIRL Agent Helm chart. These values can be used to customize your SPIRL Agent deployment to meet specific requirements.
Platform Configuration
platform
: Platform type (default:"K8S"
). Supported values:k8s
- Standard Kubernetesistio
- Kubernetes with Istio service mesheks
- Amazon EKSeks-istio
- Amazon EKS with Istiolinux
- Linux environments
Images Configuration
images.repository
: Base repository for all images (default:"ghcr.io/spirl"
)images.pullPolicy
: Image pull policy (default:"IfNotPresent"
)images.pullSecrets
: Array of image pull secrets (default:[]
)images.controller.name
: Controller image name (default:"spirl-controller"
)images.controller.tag
: Controller image tag (default: Chart appVersion)images.controller.repository
: Controller-specific repository (optional)images.agent.name
: Agent image name (default:"spirl-agent"
)images.agent.tag
: Agent image tag (default: Chart appVersion)images.agent.repository
: Agent-specific repository (optional)images.csiDriver.name
: CSI driver image name (default:"spiffe-csi-driver"
)images.csiDriver.tag
: CSI driver image tag (default:"0.2.7"
)images.csiDriver.repository
: CSI driver repository (default:"ghcr.io/spiffe"
)images.csiNodeDriverRegistrar.name
: CSI node driver registrar image name (default:"csi-node-driver-registrar"
)images.csiNodeDriverRegistrar.tag
: CSI node driver registrar image tag (default:"v2.14.0"
)images.csiNodeDriverRegistrar.repository
: CSI node driver registrar repository (default:"registry.k8s.io/sig-storage"
)images.reflector.name
: Reflector image name (default:"reflector"
)images.reflector.tag
: Reflector image tag (default: Chart appVersion)images.reflector.repository
: Reflector-specific repository (optional)
Agent Configuration
Endpoint Configuration
agent.endpoint.endpoint
: Primary trust domain server endpoint (default:""
)agent.endpoint.endpoints
: Array of additional fallback endpoints (default:[]
)agent.endpoint.supplementalRootsPEM
: Additional root CAs for endpoint trust (PEM format)agent.endpoint.connectionMaxAge
: Maximum age for endpoint connections (default:"30m"
)agent.endpoint.useGRPCFastRedial
: Enable fast redialing for gRPC connections (default:true
)
Authentication Configuration
agent.auth.key.id
: Cluster version IDagent.auth.key.pem
: Private key for cluster authentication (PEM format)agent.auth.suppliedSecretName
: Name of pre-existing secret for authentication
Security and Resources
agent.supplementalRootsPEM
: Additional trust anchors for trust bundleagent.podSecurityContext
: Pod security context configurationagent.containerSecurityContext
: Container security context configurationagent.resources
: Resource requests and limitsagent.priorityClassName
: Priority class name for pod scheduling
Scheduling and Placement
agent.affinity
: Node affinity rulesagent.tolerations
: Array of node tolerations for tainted nodes (default:[]
)agent.annotations
: Map of pod annotations (default:{}
)agent.additionalLabels
: Map of additional pod labels (default:{}
)
Advanced Configuration
agent.env
: Array of environment variables (default:[]
)agent.additionalVolumes
: Array of additional volumes (default:[]
)agent.additionalVolumeMounts
: Array of additional volume mounts (default:[]
)agent.allowedAttributes
: Array of allowed workload attributes (default:[]
)
Controller Configuration
controller.env
: Array of environment variables (default:[]
)controller.podSecurityContext
: Pod security context configurationcontroller.containerSecurityContext
: Container security context configurationcontroller.resources
: Resource requests and limitscontroller.affinity
: Node affinity rulescontroller.tolerations
: Array of node tolerations (default:[]
)controller.annotations
: Map of pod annotations (default:{}
)controller.priorityClassName
: Priority class name
CSI Driver Configuration
csiDriver.env
: Array of environment variables (default:[]
)csiDriver.podSecurityContext
: Pod security context configurationcsiDriver.containerSecurityContext
: Container security context configurationcsiDriver.resources
: Resource requests and limitscsiDriver.affinity
: Node affinity rulescsiDriver.tolerations
: Array of node tolerations (default:[]
)csiDriver.annotations
: Map of pod annotations (default:{}
)csiDriver.priorityClassName
: Priority class name
CSI Node Driver Registrar Configuration
csiNodeDriverRegistrar.env
: Array of environment variables (default:[]
)csiNodeDriverRegistrar.containerSecurityContext
: Container security context configurationcsiNodeDriverRegistrar.resources
: Resource requests and limits
Node Configuration
node.kubeletRootDirectory
: Kubelet root directory path (default:/var/lib/kubelet
)node.spirlAgentSocketDirectory
: SPIRL agent socket directory path
Platform-Specific Configuration
Kubernetes (k8s
)
k8s.spiffeSocketPath
: SPIFFE socket path (default:"/run/spirl/sockets/agent.sock"
)k8s.skipKubeletVerification
: Skip kubelet verification (default:true
)k8s.kubeletHost
: Kubelet host overridek8s.includeAnnotations
: Array of pod annotation prefixes to include in attestation (default:[]
)k8s.updateStrategy
: DaemonSet update strategy configuration (default: RollingUpdate with maxUnavailable: 0, maxSurge: 10%)
Istio (istio
)
istio.spiffeSocketPath
: SPIFFE socket path (default:"/run/spirl/sockets/socket"
)istio.skipKubeletVerification
: Skip kubelet verification (default:true
)istio.socketVolumeName
: Socket volume name (default:"workload-socket"
)istio.socketVolumeMountPath
: Socket volume mount path (default:"/run/secrets/workload-spiffe-uds"
)istio.socketFileName
: Socket file name (default:"socket"
)istio.includeAnnotations
: Array of pod annotation prefixes to include in attestation (default:[]
)
Amazon EKS (eks
)
eks.spiffeSocketPath
: SPIFFE socket path (default:"/run/spirl/sockets/agent.sock"
)eks.includeAnnotations
: Array of pod annotation prefixes to include in attestation (default:[]
)
Amazon EKS with Istio (eksIstio
)
eksIstio.spiffeSocketPath
: SPIFFE socket path (default:"/run/spirl/sockets/socket"
)eksIstio.socketVolumeName
: Socket volume name (default:"workload-socket"
)eksIstio.socketVolumeMountPath
: Socket volume mount path (default:"/run/secrets/workload-spiffe-uds"
)eksIstio.socketFileName
: Socket file name (default:"socket"
)eksIstio.includeAnnotations
: Array of pod annotation prefixes to include in attestation (default:[]
)
Telemetry Configuration
telemetry.enabled
: Enable telemetry collection (default:false
)telemetry.metricsAPI.port
: Port for metrics API exposure (default:9090
)telemetry.collectors.grpc.emmitLatencyMetrics
: Enable gRPC latency metrics (default:false
)
Webhook Configuration
webhook.namespaceSelector
: Namespace selector configuration for admission webhook (default:{}
)webhook.objectSelector
: Object selector configuration for admission webhook (default: matches labels withk8s.spirl.com/spiffe-csi: enabled
)
Reflector Configuration
Basic Configuration
reflector.enabled
: Enable reflector component (default:false
)reflector.additionalLabels
: Map of additional labels for reflector pods (default:{}
)
Endpoint Configuration
reflector.endpoint.endpoint
: Reflector endpoint URLreflector.endpoint.endpoints
: Array of fallback endpointsreflector.endpoint.supplementalRootsPEM
: Additional root CAs (PEM format)reflector.endpoint.connectionMaxAge
: Maximum connection agereflector.endpoint.useGRPCFastRedial
: Enable fast redialing
Service Configuration
reflector.service.type
: Kubernetes service type (default:"ClusterIP"
)reflector.service.port
: Service port number (default:9190
)reflector.service.annotations
: Map of service annotations (default:{}
)
Deployment Configuration
reflector.deployment.replicaCount
: Number of replicas (default:2
)reflector.deployment.env
: Array of environment variables (default:[]
)reflector.deployment.resources
: Resource requests and limitsreflector.deployment.affinity
: Node affinity rules (default:{}
)
Pod Disruption Budget
reflector.deployment.podDisruptionBudget.enabled
: Enable PDB (default:false
)reflector.deployment.podDisruptionBudget.minAvailable
: Minimum available podsreflector.deployment.podDisruptionBudget.maxUnavailable
: Maximum unavailable pods
Horizontal Pod Autoscaler
reflector.deployment.hpa.enabled
: Enable HPA (default:false
)reflector.deployment.hpa.minReplicas
: Minimum number of replicas (default:2
)reflector.deployment.hpa.maxReplicas
: Maximum number of replicas (default:7
)reflector.deployment.hpa.targetCPUUtilizationPercentage
: Target CPU utilization (default:50
)reflector.deployment.hpa.behavior
: HPA behavior configuration
Authentication
reflector.auth.key.id
: Cluster version ID for reflectorreflector.auth.key.pem
: Private key for reflector authenticationreflector.auth.suppliedSecretName
: Pre-existing secret name
Cloud Provider Configuration
AWS Configuration
reflector.aws.kmsKeyARN
: AWS KMS key ARN for encryptionreflector.aws.endpoints.kms
: Custom KMS endpoint URL
Azure Configuration
reflector.azure.keyVault.url
: Azure Key Vault URLreflector.azure.keyVault.keyName
: Key name in Key Vaultreflector.azure.keyVault.keyVersion
: Key version (optional)
GCP Configuration
reflector.gcp.projectID
: GCP project IDreflector.gcp.location
: GCP location/regionreflector.gcp.kms.keyRing
: KMS key ring namereflector.gcp.kms.keyName
: KMS key name
Experimental Features
experimental.supplementalAttestation.jwt.issuer
: JWT attestation issuerexperimental.supplementalAttestation.jwt.jwksUrl
: JWKS URL for JWT validationexperimental.supplementalAttestation.jwt.supplementalRootsFile
: Supplemental roots file pathexperimental.useLegacyEnvoyValidation
: Use legacy Envoy validation (default:false
)