CFN Cloud
Cloud Future New Life
en zh
2025-10-08 · 0 views

ConfigMaps and Secrets

Decouple configuration and sensitive data from images.

ConfigMaps are for regular configuration, Secrets are for sensitive data (passwords, certificates). Both help keep images clean and make configuration changes safer across environments.

This quick start shows common patterns: environment variables, file mounts, checksums for rolling updates, and basic security practices.

Why ConfigMaps and Secrets

  • Keep build artifacts immutable and environment-specific settings outside images.
  • Rotate credentials without rebuilding containers.
  • Standardize configuration across dev, staging, and production.

Create a ConfigMap and Secret

You can create them from YAML or from literals:

kubectl create configmap app-config --from-literal=LOG_LEVEL=info
kubectl create secret generic db-secret --from-literal=DB_PASSWORD='changeme'

Here is the YAML equivalent:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  DB_PASSWORD: "changeme"

From files and directories

You can also create ConfigMaps and Secrets from files, which is handy for full config files or certificates:

kubectl create configmap app-config --from-file=app.yaml=./app.yaml
kubectl create secret generic tls-secret --from-file=tls.crt=./tls.crt --from-file=tls.key=./tls.key

This preserves file structure and makes it easy to update and version configs alongside your code.

For a directory:

kubectl create configmap app-config --from-file=./config-dir

Inject as environment variables

Use envFrom to load all keys at once:

envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: db-secret

Or map specific keys:

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: DB_PASSWORD

Combining with init containers

If your application needs a config file rendered from templates, use an init container to generate it from env vars, then write it to a shared volume that the main container mounts. This avoids baking secrets into the image while keeping config files on disk.

Resource size planning

Keep ConfigMaps focused and small. If your config grows large, split it into multiple ConfigMaps or store large static files in object storage. This reduces update blast radius and makes rollouts faster.

When possible, avoid putting certificates and keys in the same Secret as app config. Separate resources make it easier to rotate sensitive data without touching unrelated settings.

Keep ownership clear by naming resources after the workload they serve.

Mount as files

Mount ConfigMaps and Secrets into the container filesystem:

volumes:
  - name: config
    configMap:
      name: app-config
  - name: secret
    secret:
      secretName: db-secret
volumeMounts:
  - name: config
    mountPath: /etc/app/config
    readOnly: true
  - name: secret
    mountPath: /etc/app/secret
    readOnly: true

This pattern is safer for large configs or TLS certificates.

Rolling updates on changes

ConfigMaps and Secrets do not automatically restart Pods. A common pattern is to add a checksum annotation to your Deployment so any change triggers a rollout:

metadata:
  annotations:
    checksum/config: "{{ .Values.configChecksum }}"

If you are not using Helm, you can manually restart:

kubectl rollout restart deployment/my-app

Example: manual hash annotation

If you are not using Helm, you can compute a hash of the ConfigMap and set it on the Deployment:

kubectl get configmap app-config -o json | sha256sum
kubectl patch deployment my-app -p '{"spec":{"template":{"metadata":{"annotations":{"config-hash":"<sha>"}}}}}'

Access control summary

Give service accounts only the permissions required to read the specific ConfigMaps or Secrets they need. This keeps blast radius small if a Pod is compromised.

Avoid giving broad read access to all Secrets in a namespace.

Auditing and compliance

If you operate regulated workloads, log access to Secrets and keep an audit trail for config changes. GitOps workflows help here by turning config changes into reviewed pull requests.

Namespaces and scoping

ConfigMaps and Secrets are namespace-scoped. If you use multiple namespaces, ensure the Pod and the config live in the same namespace. Cross-namespace access is not allowed by default.

Security tips

  • Secrets are base64-encoded, not encrypted by default. Enable encryption at rest in the API server if you handle sensitive data.
  • Restrict access with RBAC and avoid mounting secrets into Pods that do not need them.
  • Consider external secret managers (Vault, cloud KMS) for production.
  • Avoid checking secrets into git repositories.

Audit cluster-wide usage periodically so unused Secrets can be removed.

Config updates and application reloads

When you change a ConfigMap that is mounted as files, Kubernetes updates the volume contents, but your application might not reload automatically. Make sure your process watches the files or supports a reload signal. For env vars, Pods must be restarted to pick up changes.

If you deploy via Helm, you can hash the ConfigMap content into a Deployment annotation so a change triggers a rollout.

Example: Application Deployment

Below is a minimal Deployment that uses both env vars and file mounts:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: app
        image: nginx:1.27
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: db-secret
        volumeMounts:
        - name: config
          mountPath: /etc/app/config
          readOnly: true
        - name: secret
          mountPath: /etc/app/secret
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: app-config
      - name: secret
        secret:
          secretName: db-secret

Size limits and best practices

ConfigMaps are limited in size (about 1MiB). Keep them small, and store large artifacts in object storage or container images. Secrets are also limited in size, so certificates should be compact and rotated periodically.

If you need dynamic configuration, consider a dedicated config service or use GitOps to version changes in a repo.

Debugging

Check what is loaded into your Pod:

kubectl describe pod <pod-name>

Inspect the ConfigMap or Secret:

kubectl get configmap app-config -o yaml
kubectl get secret db-secret -o yaml

You can also exec into the Pod to confirm file mounts:

kubectl exec -it <pod-name> -- ls -l /etc/app/config
kubectl exec -it <pod-name> -- ls -l /etc/app/secret

If env vars look wrong, validate the key names and ensure the Secret is in the same namespace.

If files look correct but the app still fails, confirm it reads the right paths and supports reload.

Common pitfalls

  • Large ConfigMaps can hit size limits; keep them under 1MiB.
  • Secrets mounted as env vars are only read at Pod start.
  • If you run multiple containers, ensure the ConfigMap and Secret names are consistent across all of them.

Avoid storing large binary blobs in ConfigMaps. Use object storage and fetch them at runtime instead.

Treat ConfigMaps as configuration, not data storage.

Rotation and lifecycle

Rotate secrets regularly. If you change a secret used as an environment variable, you must restart Pods for the new value to take effect. If mounted as files, the projected volume updates automatically, but most applications still need a reload signal to pick up the change.

Consider a policy where secrets are versioned and rotated on a schedule, then deprecate old versions after a safe window.

If your app supports hot reload, wire it to watch the mounted secret path and reload without downtime.

Practical notes

  • Start with a quick inventory: kubectl get nodes, kubectl get pods -A, and kubectl get events -A.
  • Compare desired vs. observed state; kubectl describe usually explains drift or failed controllers.
  • Keep names, labels, and selectors consistent so Services and controllers can find Pods.
  • Document config defaults and overrides so other operators can change them safely.

Quick checklist

  • The resource matches the intent you described in YAML.
  • Namespaces, RBAC, and images are correct for the target environment.
  • Health checks and logs are in place before promotion.
  • Secrets are encrypted at rest and access is audited.

References