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