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 an Init Container.
  • 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 a Pod's main containers. They are useful for:

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

Characteristics:​

  • Run sequentially (one after the other)
  • All must succeed before the main containers start
  • Have access to the same volumes as the 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 starting.

Apply the Pod:

kubectl apply -f pod-init-container.yaml

Step 2.2: Verify 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 logs of the Init Container:

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

Check the logs of the main container:

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

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


Part 3: Init Container with Dependency Waiting​

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 check' && sleep 3600"]

Apply the Pod:

kubectl apply -f pod-init-wait.yaml

Check the logs of the Init Container:

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 functionalities (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: {} # Volume shared 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 # Sidecar only reads 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 logs of the main container:

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

Check the logs of the sidecar:

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

You should see the sidecar displaying the 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
# Simulate metrics collection
echo "[$(date)] Metrics collected: CPU, Memory, Network"
sleep 15
done

Apply the Pod:

kubectl apply -f pod-sidecar-monitoring.yaml

Check the logs of the sidecar:

kubectl logs app-monitored -c metrics-collector

Part 6: Advantages of Patterns​

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 features 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 to use Init Containers to prepare the environment before applications start, 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 on: December 2024