Storage, ConfigMaps & Secrets

25 minLesson 4 of 8

Learning Objectives

  • Create and use ConfigMaps for application configuration
  • Manage sensitive data with Secrets
  • Understand Volume types and persistence
  • Use PersistentVolumes and PersistentVolumeClaims

ConfigMaps

ConfigMaps store non-sensitive configuration data as key-value pairs.

Creating ConfigMaps

# From literal values
kubectl create configmap app-config \
  --from-literal=APP_ENV=production \
  --from-literal=APP_PORT=3000 \
  --from-literal=LOG_LEVEL=info
 
# From a file
kubectl create configmap nginx-config --from-file=nginx.conf
 
# From an env file
kubectl create configmap app-env --from-env-file=.env

ConfigMap YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  APP_PORT: "3000"
  LOG_LEVEL: "info"
  config.json: |
    {
      "database": {
        "host": "db-service",
        "port": 5432,
        "name": "nextgen_db"
      }
    }

Using ConfigMaps in Pods

# As environment variables
apiVersion: v1
kind: Pod
metadata:
  name: app-pod
spec:
  containers:
  - name: app
    image: nextgen-app:1.0
    envFrom:
    - configMapRef:
        name: app-config
 
    # Or individual keys
    env:
    - name: DATABASE_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: APP_ENV
# As mounted files
spec:
  containers:
  - name: app
    image: nextgen-app:1.0
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: app-config

Secrets

Secrets store sensitive data (passwords, tokens, keys) encoded in base64.

Creating Secrets

# From literal values
kubectl create secret generic db-credentials \
  --from-literal=username=admin \
  --from-literal=password=s3cur3P@ss
 
# From files
kubectl create secret generic tls-cert \
  --from-file=cert.pem \
  --from-file=key.pem
 
# TLS secret
kubectl create secret tls app-tls \
  --cert=cert.pem \
  --key=key.pem

Secret YAML

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=          # base64 encoded "admin"
  password: czNjdXIzUEBzcw==  # base64 encoded "s3cur3P@ss"
# Encode/decode base64
echo -n "admin" | base64           # YWRtaW4=
echo "YWRtaW4=" | base64 --decode  # admin

Using Secrets in Pods

spec:
  containers:
  - name: app
    image: nextgen-app:1.0
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: password
 
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
 
  volumes:
  - name: secret-volume
    secret:
      secretName: db-credentials

Volumes

Volume Types

TypePersistenceUse Case
emptyDirPod lifetimeTemp storage, shared between containers
hostPathNode lifetimeDevelopment, single-node testing
PersistentVolumeIndependentProduction data storage
configMapPod lifetimeConfiguration files
secretPod lifetimeSensitive files

emptyDir

spec:
  containers:
  - name: app
    volumeMounts:
    - name: cache
      mountPath: /tmp/cache
  - name: sidecar
    volumeMounts:
    - name: cache
      mountPath: /data
  volumes:
  - name: cache
    emptyDir: {}

PersistentVolumes & Claims

PersistentVolume (PV)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: app-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /data/app

PersistentVolumeClaim (PVC)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

Using PVC in a Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: password
        volumeMounts:
        - name: postgres-data
          mountPath: /var/lib/postgresql/data
        ports:
        - containerPort: 5432
      volumes:
      - name: postgres-data
        persistentVolumeClaim:
          claimName: app-pvc

Access Modes

ModeAbbreviationDescription
ReadWriteOnceRWOSingle node read-write
ReadOnlyManyROXMultiple nodes read-only
ReadWriteManyRWXMultiple nodes read-write

Summary

You've learned:

  • Creating and using ConfigMaps for application configuration
  • Managing sensitive data securely with Secrets
  • Volume types and their use cases
  • PersistentVolumes and PersistentVolumeClaims for data persistence
  • Mounting configuration and secrets into containers

Next Steps

Next, we'll explore Helm for packaging and deploying complex Kubernetes applications.