3.6. Init containers
A Pod can have multiple containers running apps within it, but it can also have one or more init containers, which are run before the app container is started.
Init containers are exactly like regular containers, except:
- Init containers always run to completion.
- Each init container must complete successfully before the next one starts.
Check Init Containers from the Kubernetes documentation for more details.
Task 3.6.1: Add an init container
In Backend
you created the example-frontend
application. In this task, you are going to add an init container which checks if the MariaDB database is ready to be used before actually starting your example application.
Edit your existing example-frontend
Deployment by changing your local deployment_example-frontend.yaml
. Add the init container into the existing Deployment (same indentation level as containers):
...
spec:
initContainers:
- name: wait-for-db
securityContext:
runAsUser: 1000
image: mirror.gcr.io/busybox:1.28
command:
[
"sh",
"-c",
"until nslookup mariadb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done",
]
...
And then apply again with:
kubectl apply -f deployment_example-frontend.yaml --namespace <namespace>
Note
This obviously only checks if there is a DNS Record for your MariaDB Service and not if the database is ready. But you get the idea, right?Let’s see what has changed by analyzing your newly created example-frontend
Pod with the following command (use kubectl get pod
or auto-completion to get the Pod name):
kubectl describe pod <pod> --namespace <namespace>
You see the new init container with the name wait-for-db
:
...
Init Containers:
wait-for-db:
Container ID: docker://77e6e309c88cfe62d03ed97e8fae20704bbf547a1e717a8f699ba79d9879cca2
Image: busybox
Image ID: docker-pullable://busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
Port: <none>
Host Port: <none>
Command:
sh
-c
until nslookup mariadb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done
State: Terminated
Reason: Completed
Exit Code: 0
Started: Tue, 10 Nov 2020 21:00:24 +0100
Finished: Tue, 10 Nov 2020 21:02:52 +0100
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xz2b7 (ro)
...
The init container has the State: Terminated
and an Exit Code: 0
which means it was successful. That’s what we wanted, the init container was successfully executed before our main application.
You can also check the logs of the init container with:
kubectl logs -c wait-for-db <pod> --namespace <namespace>
Which should give you something similar to:
Server: 10.43.0.10
Address 1: 10.43.0.10 rke2-coredns-rke2-coredns.kube-system.svc.cluster.local
Name: mariadb.<namespace>.svc.cluster.local
Address 1: 10.43.87.97 mariadb.<namespace>.svc.cluster.local
Check Init Container from the Kubernetes documentation for more details.