5.4 KiB
Assignment
There are some applications that need to be deployed on Kubernetes cluster and these apps have some pre-requisites where some configurations need to be changed before deploying the app container. Some of these changes cannot be made inside the images so the DevOps team has come up with a solution to use init containers to perform these tasks during deployment. Below is a sample scenario that the team is going to test first.
Create a Deployment named as ic-deploy-devops.
Configure spec as replicas should be 1, labels app should be ic-devops, template's metadata lables app should be the same ic-devops.
The initContainers should be named as ic-msg-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'echo Init Done - Welcome to xFusionCorp Industries > /ic/media'. The volume mount should be named as ic-volume-devops and mount path should be /ic.
Main container should be named as ic-main-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'while true; do cat /ic/media; sleep 5; done'. The volume mount should be named as ic-volume-devops and mount path should be /ic.
Volume to be named as ic-volume-devops and it should be an emptyDir type.
Note: The kubectl utility on the jump-host has been configured to work with the Kubernetes cluster.
Solution
Deployment with Init Container — ic-deploy-devops
An init container writes a message to a shared emptyDir volume; the main container then reads it
in a loop. This is the canonical init-container pattern. Applied inline via a heredoc — no manifest
file on disk.
Apply (heredoc → kubectl)
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: ic-deploy-devops
labels:
app: ic-devops
spec:
replicas: 1
selector:
matchLabels:
app: ic-devops
template:
metadata:
labels:
app: ic-devops
spec:
initContainers:
- name: ic-msg-devops
image: fedora:latest
command:
- /bin/bash
- -c
- "echo Init Done - Welcome to xFusionCorp Industries > /ic/media"
volumeMounts:
- name: ic-volume-devops
mountPath: /ic
containers:
- name: ic-main-devops
image: fedora:latest
command:
- /bin/bash
- -c
- "while true; do cat /ic/media; sleep 5; done"
volumeMounts:
- name: ic-volume-devops
mountPath: /ic
volumes:
- name: ic-volume-devops
emptyDir: {}
EOF
kubectl rollout status deployment/ic-deploy-devops
How it works
The heredoc apply pattern
kubectl apply -f -reads from stdin; nothing written to disk.<<'EOF'(delimiter quoted) keeps the manifest literal — the right default for k8s YAML.
Init container vs. main container — the ordering guarantee
This is a classic init container (under initContainers, no restartPolicy override), which
behaves very differently from the main container:
ic-msg-devops(init) runs first, to completion, before any main container starts. Itechos the message into/ic/mediaand exits0. Because it's a one-shot task that finishes, a classic init container is exactly right here — it does setup work, then gets out of the way.ic-main-devops(main) starts only after the init container succeeds. It then loops,cat-ing/ic/mediaevery 5 seconds. Thewhile truekeeps it running so the pod stays up.
The sequencing is guaranteed by Kubernetes: init containers complete before app containers begin. That's what makes the pattern work — the file is written before the main container ever tries to read it.
The shared emptyDir volume
ic-volume-devops(emptyDir: {}) is declared once and mounted at/icin both containers.emptyDiris created empty when the pod starts and shared by all its containers, so the init container's write to/ic/mediais visible to the main container at the same path. This is the hand-off mechanism: init writes, main reads, through shared storage.
Both volumeMounts reference the same volume name (ic-volume-devops) at the same path — that's
what ties them to one storage location.
Why the commands need /bin/bash -c
Each command is a shell one-liner (a redirect for the init, a loop for the main), so both run via
/bin/bash -c. The main container's while true loop is what keeps it in Running state — without
a long-running process, the fedora container would exit immediately and the pod would crash-loop.
Verify
# Deployment ready
kubectl get deployment ic-deploy-devops
kubectl get pods -l app=ic-devops
# Init container completed (check pod init status)
kubectl get pod -l app=ic-devops \
-o jsonpath='{.items[0].status.initContainerStatuses[0].state}{"\n"}'
# Main container is printing the message from the shared volume
kubectl logs -l app=ic-devops -c ic-main-devops --tail=3
Expected — deployment READY 1/1, the init container state showing terminated/reason: Completed, and the main container's logs repeatedly printing
Init Done - Welcome to xFusionCorp Industries.
If the pod is stuck in
Init:0/1, the init container hasn't completed — checkkubectl logs -l app=ic-devops -c ic-msg-devops. Unlike a native sidecar, a classic init container here is meant to finish, and it does (the echo exits immediately).