Skip to main content

Lab 7.4 - Init Containers and Sidecars

Lab Objectives

By the end of this lab, you will be able to:

  • Understand the concept of Init Containers.
  • Create Pods with Init Containers.
  • Use Init Containers for environment preparation.
  • Understand the Sidecar pattern.
  • Implement a Sidecar pattern for logging.

Estimated Duration

45-60 minutes

Prerequisites

  • kubectl installed and configured.
  • Functional local Kubernetes cluster (minikube or kind).
  • Knowledge of Init Containers and Sidecars (Chapter 7.4).

Part 1: Understanding Init Containers

Init Containers run before the main containers of a Pod. They are useful for:

  • Initializing data or configurations
  • Waiting for dependencies to be ready
  • Preparing the environment before application startup

Characteristics:

  • Run sequentially (one after another)
  • Must all succeed before main containers start
  • Have access to the same volumes as main containers

Part 2: Creating a Pod with Init Container

We will create a Pod with an Init Container that prepares files before the application starts.

Step 2.1: Create the Pod with Init Container

Create a file pod-init-container.yaml:

# pod-init-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
volumes:
- name: shared-data
emptyDir: {} # Volume shared between Init Container and main container
initContainers:
- name: init-setup
image: busybox:1.35
command: ["/bin/sh", "-c"]
args:
- |
echo "Init Container: Preparing the environment..."
echo "Configuration initialized" > /shared/config.txt
echo "Data prepared" > /shared/data.txt
echo "Init Container completed successfully"
volumeMounts:
- name: shared-data
mountPath: /shared
containers:
- name: app-container
image: nginx:1.20
command: ["/bin/sh", "-c"]
args:
- |
echo "Application: Reading files prepared by Init Container"
cat /shared/config.txt
cat /shared/data.txt
echo "Application started"
nginx -g "daemon off;"
volumeMounts:
- name: shared-data
mountPath: /shared
ports:
- containerPort: 80

Explanation:

  • The Init Container prepares files in the shared volume.
  • The main container reads these files after startup.

Apply the Pod:

kubectl apply -f pod-init-container.yaml

Step 2.2: Verify the Execution

Check the Pod status:

kubectl get pods app-with-init

You should see the Pod go through the phases:

  1. Init:0/1 (Init Container running)
  2. PodInitializing
  3. Running (main container started)

Check the Init Container logs:

kubectl logs app-with-init -c init-setup

Check the main container logs:

kubectl logs app-with-init -c app-container

You should see that the main container read the files created by the Init Container.


Part 3: Init Container with Dependency Wait

Init Containers can wait for external services to be available.

Step 3.1: Create a Pod that Waits for a Service

Create a file pod-init-wait.yaml:

# pod-init-wait.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-wait-service
spec:
initContainers:
- name: wait-for-service
image: busybox:1.35
command: ["/bin/sh", "-c"]
args:
- |
echo "Waiting for the service to be available..."
until nslookup kubernetes.default.svc.cluster.local; do
echo "Service not available, waiting..."
sleep 2
done
echo "Service available!"
containers:
- name: app-container
image: busybox:1.35
command: ["/bin/sh", "-c"]
args: ["echo 'Application started after service verification' && sleep 3600"]

Apply the Pod:

kubectl apply -f pod-init-wait.yaml

Check the Init Container logs:

kubectl logs app-wait-service -c wait-for-service

Part 4: Sidecar Pattern

A Sidecar is an auxiliary container that runs in the same Pod as the main container to provide complementary functionality (logging, monitoring, proxy, etc.).

Step 4.1: Create a Pod with Sidecar Pattern for Logging

Create a file pod-sidecar-logging.yaml:

# pod-sidecar-logging.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
volumes:
- name: shared-logs
emptyDir: {} # Shared volume for logs
containers:
- name: app-container
image: busybox:1.35
command: ["/bin/sh", "-c"]
args:
- |
counter=0
while true; do
echo "[$(date)] Log entry $counter from application" >> /logs/app.log
counter=$((counter+1))
sleep 5
done
volumeMounts:
- name: shared-logs
mountPath: /logs
- name: log-collector
image: busybox:1.35
command: ["/bin/sh", "-c"]
args:
- |
echo "Sidecar: Collecting application logs..."
while true; do
if [ -f /logs/app.log ]; then
echo "=== New logs ==="
tail -n 5 /logs/app.log
fi
sleep 10
done
volumeMounts:
- name: shared-logs
mountPath: /logs
readOnly: true # The sidecar only reads the logs

Explanation:

  • The main container writes logs to a shared volume.
  • The sidecar reads these logs and processes them (here, displays them).

Apply the Pod:

kubectl apply -f pod-sidecar-logging.yaml

Step 4.2: Verify the Sidecar Pattern

Check that both containers are running:

kubectl get pods app-with-sidecar

Check the main container logs:

kubectl logs app-with-sidecar -c app-container

Check the sidecar logs:

kubectl logs app-with-sidecar -c log-collector

You should see the sidecar displaying logs collected from the main container.


Part 5: Sidecar for Monitoring

Let's create another example with a sidecar for monitoring.

Step 5.1: Create a Pod with Monitoring Sidecar

Create a file pod-sidecar-monitoring.yaml:

# pod-sidecar-monitoring.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-monitored
spec:
containers:
- name: app-container
image: nginx:1.20
ports:
- containerPort: 80
- name: metrics-collector
image: busybox:1.35
command: ["/bin/sh", "-c"]
args:
- |
echo "Sidecar: Collecting metrics..."
while true; do
echo "[$(date)] Metrics collected: CPU, Memory, Network"
sleep 15
done

Apply the Pod:

kubectl apply -f pod-sidecar-monitoring.yaml

Check the sidecar logs:

kubectl logs app-monitored -c metrics-collector

Part 6: Pattern Advantages

Init Containers:

  • Separation of concerns: Preparation vs execution
  • Guaranteed order: Run before main containers
  • Reusability: Same Init Container for multiple Pods

Sidecars:

  • Cohesion: Containers in the same Pod share network and storage
  • Flexibility: Add functionality without modifying the main application
  • Isolation: Each container can have its own resources

Part 7: Cleanup

Delete the created Pods:

kubectl delete pod app-with-init app-wait-service app-with-sidecar app-monitored

Lab Summary

In this lab, you explored Init Containers and the Sidecar pattern. You learned how to use Init Containers to prepare the environment before application startup, implement sidecars for logging and monitoring, and understand the advantages of these patterns for application architecture.


Next Steps

This module on Advanced Workloads is now complete. You can proceed to Module 8 on Ingress and Load Balancing.

Module 8: Ingress and Load Balancing


Lab created: December 2024