Workloads

Configuration

ConfigMaps, Secrets, SecurityContext, and ServiceAccounts for pod configuration.

ConfigMaps

Docs: K8s Docs - ConfigMaps

  • Store non-confidential configuration data as key-value pairs
  • Can be consumed as environment variables or mounted as files

Create a ConfigMap

Imperative:

# from literal values
kubectl create configmap app-config --from-literal=DB_HOST=postgres --from-literal=DB_PORT=5432

# from a file
kubectl create configmap app-config --from-file=config.properties

# from an env file
kubectl create configmap app-config --from-env-file=app.env

Declarative:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: postgres
  DB_PORT: "5432"
  app.properties: |
    server.port=8080
    log.level=info

Use as environment variables

spec:
  containers:
    - name: app
      image: myapp:1.0
      # inject all keys as env vars
      envFrom:
        - configMapRef:
            name: app-config
      # or inject specific keys
      env:
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: DB_HOST

Use as volume mount

spec:
  containers:
    - name: app
      image: myapp:1.0
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config
          readOnly: true
  volumes:
    - name: config-volume
      configMap:
        name: app-config
  • Each key in the ConfigMap becomes a file in /etc/config/
  • Volume-mounted ConfigMaps are updated automatically (eventually)

Secrets

Docs: K8s Docs - Secrets

  • Store sensitive data (passwords, tokens, keys)
  • Values are base64-encoded (not encrypted by default)

Secret Types

TypeUsage
Opaque (default)Arbitrary key-value data
kubernetes.io/tlsTLS certificate and key
kubernetes.io/dockerconfigjsonDocker registry credentials

Create a Secret

Imperative:

# from literal values (Opaque type)
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=s3cret

# TLS secret
kubectl create secret tls my-tls --cert=tls.crt --key=tls.key

# Docker registry secret
kubectl create secret docker-registry my-reg \
  --docker-server=registry.example.com \
  --docker-username=user \
  --docker-password=pass

Declarative:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=          # echo -n "admin" | base64
  password: czNjcmV0          # echo -n "s3cret" | base64

Base64 encode/decode

# encode
echo -n "admin" | base64

# decode
echo "YWRtaW4=" | base64 --decode

Use as environment variables

spec:
  containers:
    - name: app
      image: myapp:1.0
      envFrom:
        - secretRef:
            name: db-secret
      # or specific keys
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password

Use as volume mount

spec:
  containers:
    - name: app
      image: myapp:1.0
      volumeMounts:
        - name: secret-volume
          mountPath: /etc/secrets
          readOnly: true
  volumes:
    - name: secret-volume
      secret:
        secretName: db-secret

SecurityContext

Docs: K8s Docs - Security Context

  • Defines privilege and access control settings for pods and containers

Pod-level SecurityContext

  • Applies to all containers in the pod
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000

Container-level SecurityContext

  • Overrides pod-level settings for a specific container
spec:
  containers:
    - name: app
      image: myapp:1.0
      securityContext:
        runAsUser: 1000
        runAsNonRoot: true
        readOnlyRootFilesystem: true
        allowPrivilegeEscalation: false
        capabilities:
          add: ["NET_BIND_SERVICE"]
          drop: ["ALL"]

Common fields

FieldLevelDescription
runAsUserPod/ContainerUID to run the process as
runAsGroupPod/ContainerGID to run the process as
runAsNonRootPod/ContainerFail if container runs as root
fsGroupPodGID applied to all mounted volumes
readOnlyRootFilesystemContainerMount root filesystem as read-only
allowPrivilegeEscalationContainerPrevent child process from gaining more privileges
capabilitiesContainerAdd or drop Linux capabilities

ServiceAccounts

Docs: K8s Docs - ServiceAccounts

  • Provide an identity for processes running in pods
  • Each namespace has a default ServiceAccount
  • Pods use the default SA unless a different one is specified

Create a ServiceAccount

kubectl create serviceaccount deploy-bot -n dev
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deploy-bot
  namespace: dev

Assign to a pod

spec:
  serviceAccountName: deploy-bot
  automountServiceAccountToken: true    # default is true; set false to disable token mount
  containers:
    - name: app
      image: myapp:1.0

Token projection

  • Kubernetes automatically mounts a projected token at /var/run/secrets/kubernetes.io/serviceaccount/
  • The token is audience-bound and time-limited (auto-rotated)
  • Files mounted: token, ca.crt, namespace

Useful Commands

# --- ConfigMaps ---
kubectl create configmap <name> --from-literal=key=value
kubectl get configmaps
kubectl describe configmap <name>

# --- Secrets ---
kubectl create secret generic <name> --from-literal=key=value
kubectl get secrets
kubectl describe secret <name>
kubectl get secret <name> -o jsonpath='{.data.password}' | base64 --decode

# --- SecurityContext ---
# check which user a container is running as
kubectl exec <pod-name> -- id
kubectl exec <pod-name> -- whoami

# --- ServiceAccounts ---
kubectl create serviceaccount <name>
kubectl get serviceaccounts
kubectl describe serviceaccount <name>