☸️ Kubernetes - Pod Init Containers
If your pod has a clear setup phase, use init containers. Init containers are ran before the actual containers are started. Each init container must run to successful completion for the next one to start.
Statuses of init containers are found in status.initContainerStatuses
.
Init containers are like normal containers but don't support readiness. By definition, pod cannot be ready if init containers are running.
Initializing pod is in Pending
state and has Initializing
condition set to true.
Init container code should be idempotent. Init containers can be restarted and all init containers are executed again if the pod is restarted. Just check if the generated files already exist. App container image changes only restart the app container.
The highest resource limit on all init containers is the "init request". "Pod request" is the sum of all app containers OR "init request" if that is higher.
Common init container use-cases:
- Run custom code that uses languages not installed in the actual container.
- You can define conditions that must be true before starting the actual container.
- Register the pod to a endpoint outside of Kubernetes.
- Clone a git repository into a volume.
- Find config values and save them into a configuration file for the actual container.
Example pod uses init containers to wait for services to become available:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: [ 'sh', '-c', 'echo The app is running! && sleep 3600' ]
initContainers:
- name: init-myservice
image: busybox
command: [ 'sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;' ]
- name: init-mydb
image: busybox
command: [ 'sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;' ]
kubectl create -f myapp.yaml
# you will notice that the app will not start but begins to wait
kubectl get -f myapp.yaml
kubectl describe -f myapp.yaml
# inspect the init containers
kubectl logs myapp-pod -c init-myservice
kubectl logs myapp-pod -c init-mydb
# start the services to see that the app starts too
kubectl create -f services.yaml
kubectl get -f myapp.yaml