Kubernetes Init Containers: Load Config Before Your App Starts
An init container runs to completion before any app container in the pod starts. That makes it a good place to fetch config - for example an AWS SSM parameter - and write it to a shared emptyDir volume the app reads. If the init container fails, the pod stays in Init:Error, and kubectl logs -c <init-name> shows why.
How init containers work
- They are listed under
spec.initContainers, next tospec.containers. - They run one after another, in order. Each must exit with code
0before the next starts. - App containers start only after all init containers succeed.
- If an init container fails, the kubelet restarts it (with back-off) and the
pod shows
Init:ErrororInit:CrashLoopBackOff.
Containers in a pod do not share a filesystem by default. To pass data from an
init container to the app, mount the same volume in both - usually an
emptyDir.
Example: fetch an SSM parameter before the app starts
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-consumer
spec:
replicas: 1
selector:
matchLabels:
app: config-consumer
template:
metadata:
labels:
app: config-consumer
spec:
volumes:
- name: cfg
emptyDir: {}
initContainers:
- name: ssm-loader
image: amazon/aws-cli
command:
- sh
- -c
- aws ssm get-parameter --name /app/feature-flag
--query Parameter.Value --output text > /cfg/feature-flag
env:
- name: AWS_DEFAULT_REGION
value: us-east-1
volumeMounts:
- name: cfg
mountPath: /cfg
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "cat /cfg/feature-flag; sleep 3600"]
volumeMounts:
- name: cfg
mountPath: /cfg
The init container writes the parameter value to /cfg/feature-flag. The app
container mounts the same cfg volume and reads the file at startup.
Debugging an init container that fails
kubectl get pods -l app=config-consumer
NAME READY STATUS RESTARTS AGE
config-consumer-5f6d8c7b9d-7hj2n 0/1 Init:CrashLoopBackOff 3 1m
Init: in the status means the pod is still in its init phase. Read the init
container's logs - you must name it with -c:
kubectl logs deploy/config-consumer -c ssm-loader
kubectl describe pod -l app=config-consumer # Events + init container state
A common error from the AWS CLI is:
Unable to locate credentials. You can configure credentials by running "aws configure".
Why the container has no AWS settings
Containers do not inherit your terminal's environment. Your shell may have
AWS_REGION, credentials, or an AWS_ENDPOINT_URL set, but the init container
only gets what is in its own env: list (or what the platform gives the pod).
Each container has its own env. Setting env on the app container does not
help the init container. Add the variables to the init container itself:
initContainers:
- name: ssm-loader
env:
- name: AWS_DEFAULT_REGION
value: us-east-1
- name: AWS_ENDPOINT_URL # only for a local or test endpoint
value: http://aws-endpoint:5000
Then apply and watch it:
kubectl apply -f deployment.yaml
kubectl rollout status deploy/config-consumer --timeout=90s
kubectl logs deploy/config-consumer -c app
Credentials in a real cluster
Do not put real AWS access keys in a Deployment's env. Use the cluster's
workload identity instead:
- EKS: IAM Roles for Service Accounts (IRSA) or EKS Pod Identity. The pod's ServiceAccount maps to an IAM role, and the AWS CLI and SDKs pick up temporary credentials automatically.
- Other clusters: read static keys from a Kubernetes Secret with
secretKeyRef, and give the IAM user onlyssm:GetParameteron the parameters it needs.
Init container vs sidecar
- Init container - runs once, before the app, and must finish. Use it for setup: fetch config, wait for a dependency, run a database migration check.
- Sidecar - runs next to the app for the pod's whole life. Use it for ongoing work: log shipping, proxies, refreshing config.
If the config must update while the app runs, an init container is not enough - use a sidecar that refreshes the file, or have the app read the parameter itself.
Do this project yourself. It's ready in a live cloud workspace in your browser - when you finish, it lands on your portfolio.
Start this project - freeWhat you'll practice
- Adding an init container that writes config into a shared emptyDir volume
- Reading init container logs with kubectl logs -c and describe pod
- Giving an init container its own AWS environment variables
FAQ
What is an init container in Kubernetes?
A container in spec.initContainers that runs to completion before the app containers start. Init containers run one at a time, in order, and each must exit with code 0.
How do I see the logs of an init container?
Use kubectl logs <pod> -c <init-container-name>. Without -c, kubectl shows the app container, which has not started yet.
What does Init:CrashLoopBackOff mean?
An init container keeps failing and the kubelet is restarting it with growing delays. The app containers will not start until it succeeds. Read its logs with kubectl logs -c.
How do I share files between an init container and the app container?
Mount the same volume, usually an emptyDir, in both containers. Whatever the init container writes there is visible to the app container.
Keep learning
Do this project yourself. It's ready in a live cloud workspace in your browser - when you finish, it lands on your portfolio.
Start this project - free