Day 11/40 Days of K8s: Kubernetes Multi-container Pods: Sidecar vs Init Container
π Overview
In a Kubernetes pod, we can have multiple containers:
Main application container (ex: Nginx)
Init container
Sidecar/helper container
These containers share pod resources like CPU, RAM, and storage.
π Init Containers
Init containers starts even before the app container starts. If pod is scheduled, first init container starts and once done, app container will be up and running. It works in conjunction with main app container.
Use Case: Waiting for a service to be Ready(in our example below..)
An init container can be used to wait for the service to be ready before it to start and the main application container starts.
π€ Sidecar/Helper Containers
Side car runs alongside with app container. Like it sends some input or collects output from main container.
Use Case: Logging and Monitoring
Consider a web application that needs to send logs to an external logging service. A sidecar container can be used to handle the log shipping process.
Environment Variables in Kubernetes Pods
Let's look at how to use environment variables in a Kubernetes pod Yaml file:
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
name: myapp-pod
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh','-c', 'echo the app is running && sleep 3600']
env:
- name: FIRSTNAME
value: "vivek"
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c']
args: ['until nslookup my-service.default.svc.local,; do echo "waiting for service to be up"; sleep 2;done']
π Key Points:
The
FIRSTNAME
environment variable is set with the value "vivek" inside the container.Once the container is running, we can access this env var from inside the container.
myapp-container: It is using busy box image and using the command to echo the app is running and make the container up and running for 3600 sec to avoid pod crashes.
init-myservice container: It is using busy box image and using nslookup command and work only or until where service my-service is available else it keeps waiting for service to be up and running.
NOTE: until init container is up and running the main app container will not come up.
Next Steps:
Create the pod using this YAML file
vivekmanne@Viveks-MacBook-Pro Day11 % k describe pod myapp-pod Name: myapp-pod Namespace: default Priority: 0 Service Account: default Node: kind-cluster-1-worker2/172.19.0.3 Start Time: Thu, 04 Jul 2024 07:07:03 +0530 Labels: app.kubernetes.io/name=MyApp Annotations: <none> Status: Pending IP: 10.244.2.9 IPs: IP: 10.244.2.9 Init Containers: init-myservice: Container ID: containerd://ff2fc60945348780227def2c944a392eae8e145a3f48395575742dc206c64287 Image: busybox:1.28 Image ID: docker.io/library/busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 Port: <none> Host Port: <none> Command: sh -c Args: until nslookup my-service.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done State: Running Started: Thu, 04 Jul 2024 07:07:04 +0530 Ready: False Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-nvpjk (ro) Containers: myapp-container: Container ID: Image: busybox:1.28 Image ID: Port: <none> Host Port: <none> Command: sh -c echo The app is running! && sleep 3600 State: Waiting Reason: PodInitializing Ready: False Restart Count: 0 Environment: FIRSTNAME: Vivek Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-nvpjk (ro) Conditions: Type Status PodReadyToStartContainers True Initialized False Ready False ContainersReady False PodScheduled True Volumes: kube-api-access-nvpjk: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 19s default-scheduler Successfully assigned default/myapp-pod to kind-cluster-1-worker2 Normal Pulled 18s kubelet Container image "busybox:1.28" already present on machine Normal Created 18s kubelet Created container init-myservice Normal Started 18s kubelet Started container init-myservice
check logs of the Init container
nslookup: can't resolve 'my-service.default.svc.cluster.local'
We can see the init container is running but waiting for the condition to be satisfied. Until it find the service 'my-service' it keeps on trying for every 2 sec.
Create deploy nginx and expose it to make svc available
Now, as you can see the pod is up and running and both app container and Init containers are running.
Now, exec into the pod where app container is running and access the ENV variable defined.
π Muti-init containers in the pod.
Updated pod yaml:
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app.kubernetes.io/name: MyApp spec: containers: - name: myapp-container image: busybox:1.28 env: - name: FIRSTNAME value: "Vivek" command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c'] args: ['until nslookup my-service.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done'] - name: init-mydb image: busybox:1.28 command: ['sh', '-c'] args: ['until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done']
In this case we have added another init container named init-mydb. It is using busy box image and the command using nslookup command and work only or until where svc mydb is available else it keep waiting for service to be up and running.
- Let's create pod using pod yaml...
vivekmanne@Viveks-MacBook-Pro Day11 % k apply -f pod.yaml
The Pod "myapp-pod" is invalid: spec.initContainers: Forbidden: pod updates may not add or remove containers
NOTE: We canβt add or delete init containers once it is created, so delete the pod and recreate the pod which updates 2 init containers.
As you can see above, myapp-pod is not running since init-db container is not running as it couldnβt find the service as it can't resolve 'mydb.default.svc.cluster.local'
- Create my-db service and expose
- Finally, the myapp-pod is running as both init containers are running. To verify it.
k logs myapp-pod -c init-mydb
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: mydb.default.svc.cluster.local
Address 1: 10.96.245.177 mydb.default.svc.cluster.local
It's important to understand how multi-container pod works and about the init containers startups for effectively managing pod lifecycles in Kubernetes.
#Kubernetes #Pod #Multi-container Pod #Init container #Sidecar container#CKASeries #40DaysofKubernetes
Subscribe to my newsletter
Read articles from Gopi Vivek Manne directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Gopi Vivek Manne
Gopi Vivek Manne
I'm Gopi Vivek Manne, a passionate DevOps Cloud Engineer with a strong focus on AWS cloud migrations. I have expertise in a range of technologies, including AWS, Linux, Jenkins, Bitbucket, GitHub Actions, Terraform, Docker, Kubernetes, Ansible, SonarQube, JUnit, AppScan, Prometheus, Grafana, Zabbix, and container orchestration. I'm constantly learning and exploring new ways to optimize and automate workflows, and I enjoy sharing my experiences and knowledge with others in the tech community. Follow me for insights, tips, and best practices on all things DevOps and cloud engineering!