K8s by Example: Environment Variables

Environment variables configure containers at runtime. Kubernetes supports multiple sources: static values, ConfigMaps, Secrets, and the Downward API. Env vars are set at container start and don’t auto-update.

pod-env.yaml

Define environment variables directly in the Pod spec. Simple and explicit, but requires redeployment to change values. Use for static config that rarely changes.

spec:
  containers:
    - name: app
      image: my-app:v1
      env:
        - name: PORT
          value: "8080"
        - name: DEBUG
          value: "false"
        - name: FEATURES
          value: "auth,logging,metrics"
pod-env-refs.yaml

Reference ConfigMaps and Secrets for externalized configuration. Use optional: false to fail Pod startup if the key is missing. Decouples config from Pod specs.

env:
  - name: DATABASE_URL
    valueFrom:
      secretKeyRef:
        name: db-secrets
        key: url
        optional: false
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL
        optional: true
pod-downward-api.yaml

The Downward API exposes Pod metadata via fieldRef. Inject Pod name, namespace, IP, and node info. Essential for logging, tracing, and self-discovery.

env:
  - name: POD_NAME
    valueFrom:
      fieldRef:
        fieldPath: metadata.name
  - name: POD_NAMESPACE
    valueFrom:
      fieldRef:
        fieldPath: metadata.namespace
  - name: POD_IP
    valueFrom:
      fieldRef:
        fieldPath: status.podIP
  - name: NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName
pod-labels-env.yaml

Access labels and annotations via the Downward API. Useful for passing deployment info to your application for metrics, tracing, or feature flags.

env:
  - name: APP_VERSION
    valueFrom:
      fieldRef:
        fieldPath: metadata.labels['app.kubernetes.io/version']
  - name: DEPLOY_SHA
    valueFrom:
      fieldRef:
        fieldPath: metadata.annotations['deploy-sha']
  - name: SERVICE_ACCOUNT
    valueFrom:
      fieldRef:
        fieldPath: spec.serviceAccountName
pod-resource-env.yaml

resourceFieldRef exposes container resource limits. Critical for JVM heap sizing and memory-aware caching. Use divisor to convert units (1Mi, 1m).

env:
  - name: MEMORY_LIMIT
    valueFrom:
      resourceFieldRef:
        containerName: app
        resource: limits.memory
        divisor: 1Mi
  - name: CPU_REQUEST
    valueFrom:
      resourceFieldRef:
        containerName: app
        resource: requests.cpu
        divisor: 1m
pod-envfrom.yaml

envFrom loads all keys from a ConfigMap or Secret. Use prefix to namespace them. Keys become prefixed: CONFIG_DEBUG, SECRET_API_KEY.

spec:
  containers:
    - name: app
      envFrom:
        - configMapRef:
            name: app-config
          prefix: CONFIG_
        - secretRef:
            name: app-secrets
          prefix: SECRET_
pod-env-interpolation.yaml

Env vars can reference other env vars using $(VAR_NAME) syntax. Evaluated at container start. Useful for building connection strings from components.

env:
  - name: DB_HOST
    value: "postgres"
  - name: DB_PORT
    value: "5432"
  - name: DB_NAME
    value: "myapp"
  - name: DATABASE_URL
    value: "postgresql://$(DB_HOST):$(DB_PORT)/$(DB_NAME)"

Order matters: env vars are evaluated in order. Later vars can reference earlier ones. ConfigMap/Secret refs are resolved before inline values using them.

env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secrets
        key: password
  - name: DATABASE_URL
    value: "postgresql://user:$(DB_PASSWORD)@db:5432/app"

Index | GitHub | Use arrow keys to navigate |