Init Containers

Init containers run and finish before the main containers start, handling setup work.

Syntaxspec: initContainers: - name: <name> image: <image> containers: - name: <name> image: <image>

An init container is a special container that runs to completion before the app containers start. If it fails, Kubernetes restarts it until it succeeds.

What they are good for

  • Waiting for a database or another service to become reachable.
  • Running a one-time database migration or schema setup.
  • Downloading or generating files the main app needs.
  • Setting file permissions on a shared volume.

How they run

Init containers run one at a time, in order. Only when the last one finishes do the regular containers begin. This guarantees your setup is done before the app boots.

Example

Example Β· yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.36
      command: ['sh', '-c', 'until nc -z db 5432; do echo waiting; sleep 2; done']
  containers:
    - name: app
      image: myapp:1.0
      ports:
        - containerPort: 8080

When to use it

  • An init container waits for a database to become reachable before the main application container starts, preventing connection errors on boot.
  • A security-focused team uses an init container to fetch secrets from HashiCorp Vault and write them to a shared volume, keeping secrets out of environment variables.
  • A migration init container applies database schema changes before the new application version starts, ensuring the schema is always compatible on startup.

More examples

Wait-for-db init container

Polls the postgres service port in a loop inside an init container and only exits (success) once the database is reachable.

Example Β· yaml
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.36
      command:
        - sh
        - -c
        - |
          until nc -z postgres-svc 5432; do
            echo "Waiting for postgres..."
            sleep 2
          done
  containers:
    - name: app
      image: myapp:1.0

Fetch secret into shared volume

Uses a Vault init container to write a secret to a shared emptyDir volume, which the main app reads at runtime.

Example Β· yaml
spec:
  initContainers:
    - name: fetch-secret
      image: vault:1.15
      command:
        - sh
        - -c
        - vault read -field=password secret/db > /vault/secret/db_pass
      volumeMounts:
        - name: secret-vol
          mountPath: /vault/secret
  containers:
    - name: app
      image: myapp:1.0
      volumeMounts:
        - name: secret-vol
          mountPath: /run/secrets
  volumes:
    - name: secret-vol
      emptyDir: {}

Multiple ordered init containers

Defines two init containers that run sequentially: the DB migration completes first, then the cache seeder runs, before the app starts.

Example Β· yaml
spec:
  initContainers:
    - name: migrate-db
      image: myapp-migrations:1.0
      command: ["./run-migrations.sh"]
    - name: seed-cache
      image: myapp-seeder:1.0
      command: ["./seed-redis.sh"]
  containers:
    - name: app
      image: myapp:1.0

Discussion

  • Be the first to comment on this lesson.
Init Containers β€” Kubernetes | SoundsCode