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
Deploymentnamed asic-deploy-xfusion. - Configure
specas replicas should be1, labelsappshould beic-xfusion, template's metadata lablesappshould be the sameic-xfusion. - The
initContainersshould be named asic-msg-xfusion, use imagefedorawithlatesttag and use command'/bin/bash','-c'and'echo Init Done - Welcome to xFusionCorp Industries > /ic/official'. The volume mount should be named asic-volume-xfusionand mount path should be/ic. - Main container should be named as
ic-main-xfusion, use imagefedorawithlatesttag and use command'/bin/bash','-c'and'while true; do cat /ic/official; sleep 5; done'. The volume mount should be named asic-volume-xfusionand mount path should be/ic. - Volume to be named as
ic-volume-xfusionand it should be an emptyDir type.
🎉 CONGRATULATIONS! 🎉
You have successfully completed the Init Containers in Kubernetes challenge!
What Are Init Containers?
Init containers are containers that run and complete before the main containers in a pod start. They are useful for:
- Setting up configuration files
- Running database migrations
- Waiting for external dependencies
- Seeding data
- Performing pre-start checks
Key Characteristics
| Feature | Description |
|---|---|
| Execution Order | Run sequentially before any main container starts |
| Completion | Must complete successfully for pod to start |
| Failure | If an init container fails, the pod restarts (unless restartPolicy is Never) |
| Resources | Can have different resource limits than main containers |
| Volumes | Can share volumes with main containers for data sharing |
What We Will Build
Task Overview
| Component | Specification |
|---|---|
| Deployment Name | ic-deploy-xfusion |
| Replicas | 1 |
| Labels | app: ic-xfusion |
| Init Container |
ic-msg-xfusion – fedora:latest, writes to /ic/official
|
| Main Container |
ic-main-xfusion – fedora:latest, reads /ic/official every 5 seconds |
| Volume |
ic-volume-xfusion – emptyDir mounted at /ic
|
Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Pod: ic-deploy-xfusion-xxxxxxxxxx-xxxxx │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Init Container: ic-msg-xfusion │ │ │
│ │ │ (Runs first, then exits) │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Writes: │ │ │ │
│ │ │ │ "Init Done - Welcome to xFusionCorp Industries" │ │ │ │
│ │ │ │ To: /ic/official │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Main Container: ic-main-xfusion │ │ │
│ │ │ (Runs after init container completes) │ │ │
│ │ │ ┌────────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Reads: /ic/official │ │ │ │
│ │ │ │ Prints: "Init Done - Welcome to xFusionCorp Industries" │ │ │ │
│ │ │ │ Every 5 seconds │ │ │ │
│ │ │ └────────────────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Volume: ic-volume-xfusion (emptyDir) │ │ │
│ │ │ Mounted at: /ic │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Step-by-Step Implementation
Step 1: Create the Deployment YAML
vi ic-deployment.yaml
YAML Content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ic-deploy-xfusion
spec:
replicas: 1
selector:
matchLabels:
app: ic-xfusion
template:
metadata:
labels:
app: ic-xfusion
spec:
volumes:
- name: ic-volume-xfusion
emptyDir: {}
initContainers:
- name: ic-msg-xfusion
image: fedora:latest
command:
- /bin/bash
- -c
- echo 'Init Done - Welcome to xFusionCorp Industries' > /ic/official
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
containers:
- name: ic-main-xfusion
image: fedora:latest
command:
- /bin/bash
- -c
- while true; do cat /ic/official; sleep 5; done
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
YAML Breakdown
Deployment Metadata
apiVersion: apps/v1
kind: Deployment
metadata:
name: ic-deploy-xfusion
spec:
replicas: 1
selector:
matchLabels:
app: ic-xfusion
template:
metadata:
labels:
app: ic-xfusion
Volume Definition
volumes:
- name: ic-volume-xfusion
emptyDir: {}
An emptyDir volume is created at the pod level, shared between all containers.
Init Container
initContainers:
- name: ic-msg-xfusion
image: fedora:latest
command:
- /bin/bash
- -c
- echo 'Init Done - Welcome to xFusionCorp Industries' > /ic/official
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
The init container writes a message to /ic/official and then exits.
Main Container
containers:
- name: ic-main-xfusion
image: fedora:latest
command:
- /bin/bash
- -c
- while true; do cat /ic/official; sleep 5; done
volumeMounts:
- name: ic-volume-xfusion
mountPath: /ic
The main container continuously reads and prints the content of /ic/official.
Step 2: Create the Deployment
kubectl apply -f ic-deployment.yaml
Output:
deployment.apps/ic-deploy-xfusion created
Step 3: Verify the Deployment
kubectl get deployments
Output:
NAME READY UP-TO-DATE AVAILABLE AGE
ic-deploy-xfusion 1/1 1 1 9s
Step 4: Verify the Pod
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
ic-deploy-xfusion-5b95cd58c5-8jxkb 1/1 Running 0 22s
Step 5: Check the Output
kubectl logs ic-deploy-xfusion-5b95cd58c5-8jxkb -c ic-main-xfusion
Output:
Init Done - Welcome to xFusionCorp Industries
Init Done - Welcome to xFusionCorp Industries
Init Done - Welcome to xFusionCorp Industries
...
Step 6: Check Init Container Status
kubectl logs ic-deploy-xfusion-5b95cd58c5-8jxkb -c ic-msg-xfusion
Output:
(No output - the init container completed successfully)
Step 7: Inspect the Pod
kubectl describe pod ic-deploy-xfusion-5b95cd58c5-8jxkb
Key Output:
Init Containers:
ic-msg-xfusion:
State: Terminated
Reason: Completed
Exit Code: 0
Containers:
ic-main-xfusion:
State: Running
Volumes:
ic-volume-xfusion:
Type: EmptyDir
Understanding the Execution Flow
1. Pod Creation
The pod is scheduled to a node.
2. Volume Creation
The emptyDir volume ic-volume-xfusion is created.
3. Init Container Execution
The init container ic-msg-xfusion starts and:
- Writes the message to
/ic/official - Exits with exit code 0 (success)
4. Main Container Execution
The main container ic-main-xfusion starts and:
- Reads
/ic/officialevery 5 seconds - Prints the content to stdout
5. Continuous Operation
The main container continues running indefinitely.
Key Learnings
1. Init Container Lifecycle
┌─────────────────────────────────────────────────────────────────────────────┐
│ Pod Startup Process │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Step 1: Pod Created │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Step 2: Volume Created │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Step 3: Init Container Runs │ │
│ │ - Executes setup tasks │ │
│ │ - Must complete successfully │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Step 4: Main Container Starts │ │
│ │ - All init containers must have completed │ │
│ │ - Main application runs │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Step 5: Pod is Running │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
2. Use Cases for Init Containers
| Use Case | Example |
|---|---|
| Configuration Generation | Creating config files from templates |
| Database Migrations | Running schema migrations before app starts |
| Waiting for Dependencies | Checking if a database is ready |
| Data Seeding | Populating initial data |
| File Permissions | Setting up file permissions |
3. Comparison: Init vs Main Containers
| Aspect | Init Container | Main Container |
|---|---|---|
| Execution Order | Runs first | Runs after init containers |
| Purpose | Setup and preparation | Application runtime |
| Lifecycle | Runs to completion | Runs continuously |
| Restart Policy | Restarts on failure | Restarts according to pod policy |
| Volume Access | Can share volumes | Can share volumes |
Troubleshooting
Pod Stuck in Init State
# Check pod status
kubectl get pods
# Check init container logs
kubectl logs <pod-name> -c <init-container-name>
# Check pod details
kubectl describe pod <pod-name>
Init Container Failing
# Check the exit code
kubectl describe pod <pod-name> | grep -A 5 "Init Containers:"
# Check the last state
kubectl get pod <pod-name> -o jsonpath='{.status.initContainerStatuses[*].state}'
Volume Not Mounted
# Check volume mounts
kubectl describe pod <pod-name> | grep -A 10 "Mounts:"
# Verify volume exists
kubectl describe pod <pod-name> | grep -A 10 "Volumes:"
Main Container Not Starting
# Check if init containers completed
kubectl get pod <pod-name> -o jsonpath='{.status.initContainerStatuses[*].state}'
# Check pod events
kubectl describe pod <pod-name> | grep -A 20 "Events:"
Useful Commands
| Command | Purpose |
|---|---|
kubectl get deployments |
List deployments |
kubectl get pods |
List pods |
kubectl logs <pod> -c <container> |
View container logs |
kubectl describe pod <pod> |
Detailed pod information |
kubectl get pod <pod> -o yaml |
View pod configuration |
kubectl delete deployment ic-deploy-xfusion |
Delete deployment |
Summary
In this challenge, we successfully:
- Created a deployment with an init container that writes a configuration file
- Used an emptyDir volume to share data between the init and main containers
- Verified that the init container runs before the main container
- Confirmed that the main container can access the data written by the init container
Init containers are a powerful feature for managing complex application deployments. They enable clean separation of setup tasks from the main application logic, making deployments more reliable and maintainable.
Top comments (0)