11. ConfigMaps and Secrets

Chapter 11 of 24 · 25 min

ConfigMaps and Secrets inject configuration and sensitive data into containers. The distinction lies in storage encryption and access control. ConfigMaps store non-sensitive configuration; Secrets store credentials, tokens, and certificates with encryption at rest.

Immutable ConfigMaps prevent modification during runtime. Marking a ConfigMap immutable disables update operations, forcing deployments to create new ConfigMaps. The practice improves predictability and prevents pod-configuration drift during rolling updates.

apiVersion: v1
kind: ConfigMap
metadata:
  name: inference-config
  namespace: ai-inference
  labels:
    app.kubernetes io/part-of: inference-stack
data:
  MAX_BATCH_SIZE: "32"
  MAX_SEQUENCE_LENGTH: "2048"
  DEVICE: "cuda"
  LOG_LEVEL: "info"
apiVersion: v1
kind: ConfigMap
metadata:
  name: inference-config-immutable
  namespace: ai-inference
immutable: true
data:
  MODEL_CONFIG: |
    {
      "model_type": "transformer",
      "precision": "fp16",
      "use_flash_attention": true
    }

Secrets require careful handling to prevent exposure. Base64 encoding in Kubernetes YAML is not encryption. The etcd encryption feature enables at-rest encryption for Secret contents. Enabling encryption at rest requires kube-apiserver configuration and key rotation procedures.

# Secret with base64-encoded credentials
apiVersion: v1
kind: Secret
metadata:
  name: model-registry credentials
  namespace: ai-inference
type: Opaque
data:
  username: YWRtaW5vc2Vy
  password: cGFzc3dvcmQxMjM=
---
# For credentials containing special characters,
# use stringData to avoid manual base64 encoding
apiVersion: v1
kind: Secret
metadata:
  name: huggingface-token
  namespace: ai-inference
type: Opaque
stringData:
  hf_token: "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Injection methods include environment variables, volume mounts, and projected volumes. Environment variables suit simple scalar values. Volume mounts provide file-based access suitable for configuration files or certificate bundles. Projected volumes combine multiple ConfigMaps and Secrets into unified mounts.

env:
  - name: MODEL_CONFIG_PATH
    valueFrom:
      configMapKeyRef:
        name: inference-config
        key: MODEL_CONFIG_FILE
secretRef:
  name: huggingface-token
volumes:
  - name: config
    configMap:
      name: inference-config
  - name: certs
    secret:
      secretName: inference-tls

External secrets operators synchronize secrets from external secret managers (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) into Kubernetes Secrets. The pattern centralizes secret management while maintaining Kubernetes-native injection mechanisms.

Access Control

RBAC policies restrict unauthorized access to Secrets. Service accounts should receive least-privilege access to only the Secrets required for operation. Pod security policies enforce namespace-level restrictions on secret access.

# Role for reading specific secrets
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: inference-secret-reader
  namespace: ai-inference
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["model-registry-credentials", "huggingface-token"]
    verbs: ["get", "list", "watch"]

EXERCISE

Configure a model inference deployment with environment-specific configuration. Create a ConfigMap with model parameters, a Secret for registry credentials, and inject both into the deployment using appropriate methods. Verify the values appear correctly in the pod environment.

# Create ConfigMap
kubectl create configmap inference-params \
  --from-literal=MAX_BATCH_SIZE=32 \
  --from-literal=LOG_LEVEL=info \
  --namespace=ai-inference

# Create Secret for HuggingFace token
kubectl create secret generic hf-credentials \
  --from-literal=hf_token=hf_xxxxx \
  --namespace=ai-inference

# Inject into deployment
kubectl set env deployment/inference-server \
  --from=configmap/inference-params \
  --from=secret/hf-credentials

# Verify injection
kubectl describe deployment inference-server \
  | grep -A20 "Environment:"

# Exec into pod to verify values
kubectl exec -it deploy/inference-server -- \
  printenv | grep -E "MAX_BATCH|hf_token"