DEV Community

Janak Shrestha
Janak Shrestha

Posted on

Day 61: Init Containers in Kubernetes

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.

  1. Create a Deployment named as ic-deploy-xfusion.
  2. Configure spec as replicas should be 1, labels app should be ic-xfusion, template's metadata lables app should be the same ic-xfusion.
  3. The initContainers should be named as ic-msg-xfusion, use image fedora with latest tag and use command '/bin/bash''-c' and 'echo Init Done - Welcome to xFusionCorp Industries > /ic/official'. The volume mount should be named as ic-volume-xfusion and mount path should be /ic.
  4. Main container should be named as ic-main-xfusion, use image fedora with latest tag and use command '/bin/bash''-c' and 'while true; do cat /ic/official; sleep 5; done'. The volume mount should be named as ic-volume-xfusion and mount path should be /ic.
  5. Volume to be named as ic-volume-xfusion and 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                                               │ │ │
│  │  └──────────────────────────────────────────────────────────────────┘ │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Implementation

Step 1: Create the Deployment YAML

vi ic-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Volume Definition

volumes:
- name: ic-volume-xfusion
  emptyDir: {}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

The main container continuously reads and prints the content of /ic/official.

Step 2: Create the Deployment

kubectl apply -f ic-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Output:

deployment.apps/ic-deploy-xfusion created
Enter fullscreen mode Exit fullscreen mode

Step 3: Verify the Deployment

kubectl get deployments
Enter fullscreen mode Exit fullscreen mode

Output:

NAME                READY   UP-TO-DATE   AVAILABLE   AGE
ic-deploy-xfusion   1/1     1            1           9s
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify the Pod

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Output:

NAME                                 READY   STATUS    RESTARTS   AGE
ic-deploy-xfusion-5b95cd58c5-8jxkb   1/1     Running   0          22s
Enter fullscreen mode Exit fullscreen mode

Step 5: Check the Output

kubectl logs ic-deploy-xfusion-5b95cd58c5-8jxkb -c ic-main-xfusion
Enter fullscreen mode Exit fullscreen mode

Output:

Init Done - Welcome to xFusionCorp Industries
Init Done - Welcome to xFusionCorp Industries
Init Done - Welcome to xFusionCorp Industries
...
Enter fullscreen mode Exit fullscreen mode

Step 6: Check Init Container Status

kubectl logs ic-deploy-xfusion-5b95cd58c5-8jxkb -c ic-msg-xfusion
Enter fullscreen mode Exit fullscreen mode

Output:

(No output - the init container completed successfully)
Enter fullscreen mode Exit fullscreen mode

Step 7: Inspect the Pod

kubectl describe pod ic-deploy-xfusion-5b95cd58c5-8jxkb
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/official every 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                                              │ │
│  └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

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:"
Enter fullscreen mode Exit fullscreen mode

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:"
Enter fullscreen mode Exit fullscreen mode

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:

  1. Created a deployment with an init container that writes a configuration file
  2. Used an emptyDir volume to share data between the init and main containers
  3. Verified that the init container runs before the main container
  4. 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)