Skip to main content

Kubernetes Configuration

Decouple configuration artifacts from image content to keep containerized applications portable.

1. ConfigMaps

Used to store non-confidential data in key-value pairs.
  • Environment variables
  • Command-line arguments
  • Configuration files

Creating ConfigMaps

Imperative (CLI):
kubectl create configmap app-config --from-literal=LOG_LEVEL=info
Declarative (YAML):
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # Key-value pair
  database_host: "postgres-service"
  log_level: "debug"
  
  # File content
  nginx.conf: |
    server {
      listen 80;
      server_name localhost;
    }

Using ConfigMaps in Pods

As Environment Variables:
spec:
  containers:
  - name: app
    env:
    # Single variable
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: log_level
    
    # All variables from ConfigMap
    envFrom:
    - configMapRef:
        name: app-config
As a Volume (Mounting files):
spec:
  containers:
  - name: nginx
    volumeMounts:
    - name: config-volume
      mountPath: /etc/nginx/conf.d
  volumes:
  - name: config-volume
    configMap:
      name: app-config
      items:
      - key: nginx.conf
        path: default.conf

2. Secrets

Used to store sensitive information, such as passwords, OAuth tokens, and SSH keys.
  • Stored in etcd (encrypted at rest if configured).
  • Mounted into pods as files or environment variables.
  • Base64 encoded (not encrypted by default in YAML!).

Creating Secrets

Imperative:
kubectl create secret generic db-pass --from-literal=password=supersecret123
Declarative:
apiVersion: v1
kind: Secret
metadata:
  name: db-pass
type: Opaque
data:
  # Must be Base64 encoded!
  # echo -n "supersecret123" | base64
  password: c3VwZXJzZWNyZXQxMjM=

Using Secrets in Pods

As Environment Variables:
spec:
  containers:
  - name: app
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-pass
          key: password
As a Volume:
spec:
  containers:
  - name: app
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/certs
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: ssl-certs

Best Practices

Never commit YAML files containing Base64 encoded secrets. Use tools like Sealed Secrets, External Secrets Operator, or Vault.
Set immutable: true for ConfigMaps/Secrets to prevent accidental updates and improve performance.
If you mount a ConfigMap as a volume, updates propagate to the file automatically (eventually). Apps need to watch the file for changes to reload without restart.

Resource Quotas

Limit resource consumption per namespace.
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"
    services: "10"
    secrets: "20"
    configmaps: "20"
Interview Tip: ResourceQuotas are enforced at the namespace level. When a quota is set, all pods must specify resource requests/limits.

LimitRanges

Set default and max/min resource constraints for pods/containers in a namespace.
apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: development
spec:
  limits:
  - type: Container
    default:          # Default limits
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:   # Default requests
      cpu: "100m"
      memory: "128Mi"
    max:              # Maximum allowed
      cpu: "2"
      memory: "2Gi"
    min:              # Minimum required
      cpu: "50m"
      memory: "64Mi"

Priority Classes

Control pod scheduling and eviction priority.
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "Critical production workloads"
preemptionPolicy: PreemptLowerPriority
---
# Use in Pod spec
spec:
  priorityClassName: high-priority
Built-in PriorityValueUse Case
system-cluster-critical2000000000kube-system pods
system-node-critical2000001000Node-critical pods
Custom high priority1000000Production apps
Default (none set)0Standard workloads

Secrets Management Best Practices

1. External Secrets Operator

Sync secrets from external sources (AWS Secrets Manager, HashiCorp Vault).
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: SecretStore
  target:
    name: db-secret
  data:
  - secretKey: password
    remoteRef:
      key: prod/database
      property: password

2. Sealed Secrets

Encrypt secrets that can be safely stored in Git.
# Create SealedSecret
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

3. Enable etcd Encryption

Encrypt secrets at rest in etcd:
# /etc/kubernetes/enc/enc.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
    - secrets
    providers:
    - aescbc:
        keys:
        - name: key1
          secret: <base64-encoded-key>
    - identity: {}

Interview Questions & Answers

AspectConfigMapSecret
PurposeNon-sensitive configSensitive data
EncodingPlain textBase64 encoded
At-rest encryptionNoOptional (etcd encryption)
Size limit1MB1MB
MountingEnv vars or volumesEnv vars or volumes
Not by default!
  • Secrets are only Base64 encoded, not encrypted
  • Anyone with RBAC access can read them
  • They’re stored in etcd (unencrypted by default)
To secure secrets:
  • Enable etcd encryption at rest
  • Use RBAC to restrict access
  • Use external secret management (Vault, AWS Secrets Manager)
  • Use Sealed Secrets for GitOps
Option 1: Volume mount - ConfigMap changes propagate automatically (with delay)
  • App must watch file for changes
Option 2: Trigger rollout manually:
kubectl rollout restart deployment/my-app
Option 3: Use Reloader - Automatically restarts pods when ConfigMap changes:
annotations:
  reloader.stakater.com/auto: "true"
ResourceQuotas prevent resource exhaustion in multi-tenant clusters by:
  • Limiting total CPU/memory per namespace
  • Limiting number of objects (pods, services, secrets)
  • Enforcing resource requests/limits on all pods
Without quotas, one team could consume all cluster resources.
  1. External Secrets Operator: Auto-syncs from external sources on schedule
  2. Volume-mounted secrets: Kubernetes updates files (apps must reload)
  3. Rolling restart: kubectl rollout restart to pick up new secrets
  4. Sidecar pattern: Use a sidecar that watches for secret changes

Common Pitfalls

1. Base64 ≠ Encryption: Base64 is encoding, not encryption. Anyone can decode it.2. Committing Secrets to Git: Never commit Secret YAMLs with actual values. Use Sealed Secrets or External Secrets.3. Not Setting ResourceQuotas: Without quotas, a runaway pod can consume all cluster resources.4. Forgetting LimitRanges: Without defaults, pods without resource specs can consume unlimited resources.5. Large ConfigMaps: ConfigMaps have a 1MB limit. For larger configs, use a sidecar to fetch from external storage.

Key Takeaways

  • Use ConfigMaps for plain text config.
  • Use Secrets for sensitive data.
  • Inject as Environment Variables for simple values.
  • Mount as Volumes for config files.
  • Base64 is NOT encryption!
  • Use ResourceQuotas and LimitRanges for multi-tenant clusters.
  • Implement proper secrets management with external tools.

Next: Kubernetes Storage →