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:
Init:0/1(Init Container running)PodInitializingRunning(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