The sidecar container pattern
in Kubernetes is a design approach where a secondary container (the "sidecar") runs alongside the primary container in the same pod. This pattern is used to add functionality or support to the primary application without modifying its code. The sidecar container shares the same network and storage as the main container, making it highly effective for certain scenarios.
Sidecars can handle tasks like:
- Logging: A sidecar container might collect, aggregate, and forward application logs.
- Monitoring: Sidecars can collect application metrics and send them to a monitoring system.
- Proxying/Networking: Sidecars can act as service proxies (e.g., Envoy or Istio sidecars) for service mesh implementations.
- Security: Sidecars can handle certificate rotation or inject secrets securely into the application.
Real-World Use Cases for Sidecar Containers
- Logging & Monitoring: Sidecar Containers can collect and forward logs (e.g., Fluentd), expose metrics (e.g., Prometheus exporters).
- Service Mesh: They help to manage service communication, encryption, and telemetry (e.g., Istio, Linkerd).
- Configuration & Secrets: They help to fetch and update configs or secrets (e.g., HashiCorp Vault).
- Data Synchronization: They help to sync files/data from external sources (e.g., S3, FTP).
- Network Proxying & Security: They can act as reverse proxies (e.g., NGINX) or handle SSL/TLS.
- Caching: They can provide a caching layer (e.g., Redis, Memcached).
- Testing & Debugging: You can run debugging tools in sidecar containers (e.g., tcpdump) or generate test traffic.
- Background Tasks: They can handle periodic jobs like cleanup or health checks.
- API Gateway/Translator: They can translate or adapt API requests (e.g., gRPC to REST).
- CI/CD: Helper function run as sidecar container (e.g., Gitlab runner helpers).
- Automated Backups: A sidecar container periodically backs up database data to a remote storage location like AWS S3.
- Log Archiving: A sidecar compresses and archives old logs from the primary container.
- Vulnerability Scanning: They can scan app for risks (e.g., Clair, Trivy).
- Retries & Circuit Breaker: They can help to retry failed requests, manage service health (e.g., Envoy).
- Data Backups: They can help periodic database backups (e.g., mysqldump, AWS CLI).
- Rate Limiting: They can help to throttle API requests (e.g., Kong, Envoy).
Hands-On Sample
This hands-on illustrates the simple sample data synchronization real-world use-case. This scenario shows:
- how to create multicontainer in one pod,
- how the multicontainers in the same pod have same ethernet interface (IPs),
- how the multicontainers in the same pod can reach the shared volume area,
- how to make port-forwarding to host PC ports
How to install Minikube?
Minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes.
It includes essential Kubernetes components like the API server, scheduler, controller manager, and etcd, along with optional add-ons like the dashboard and ingress. Minikube supports multiple platforms and integrates with kubectl for seamless interaction with the cluster.
All you need is Docker (or similarly compatible) container or a Virtual Machine environment, and Kubernetes is a single command away:
minikube start
To install: https://minikube.sigs.k8s.io/docs/start/
Steps
- Run minikube (in this scenario, K8s runs on WSL2- Ubuntu 20.04) ("minikube start")
user@k8s:$ minikube start
π minikube v1.35.0 on Ubuntu 20.04
β¨ Automatically selected the docker driver
π Using Docker driver with root privileges
π Starting "minikube" primary control-plane node in "minikube" cluster
π Pulling base image v0.0.46 ...
π₯ Creating docker container (CPUs=2, Memory=3100MB) ...
β Failing to connect to https://registry.k8s.io/ from inside the minikube container
π‘ To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
π³ Preparing Kubernetes v1.32.0 on Docker 27.4.1 ...
βͺ Generating certificates and keys ...
βͺ Booting up control plane ...
βͺ Configuring RBAC rules ...
π Configuring bridge CNI (Container Networking Interface) ...
π Verifying Kubernetes components...
βͺ Using image gcr.io/k8s-minikube/storage-provisioner:v5
π Enabled addons: storage-provisioner, default-storageclass
π Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Create YAML file (multicontainer.yaml) in your directory and copy the below definition into the file.
File: https://github.com/omerbsezer/Fast-Kubernetes/blob/main/labs/pod/multicontainer.yaml
YAML File explanation:
-
name: webcontainer
=> container name: webcontainer -
image: nginx
=> image from nginx -
containerPort: 80
=> opening-port: 80 -
mountPath: /usr/share/nginx/html
=> path in the container -
image: busybox
=> sidecar, second container image is busybox -
command: ["/bin/sh"]
=> suppose args run on shell -
args: ["-c", "while true; do wget -O /var/log/index.html https://raw.githubusercontent.com/omerbsezer/Fast-Kubernetes/main/index.html; sleep 15; done"]
=> it pulls index.html file from github every 15 seconds -
volumes: name: sharedvolume
=> define emptydir temporary volume, when the pod is deleted, volume also deleted -
name: sharedvolume
=> name of volume -
emptyDir: {}
=> volume type emtpydir: creates empty directory where the pod is runnning
multicontainer.yaml:
apiVersion: v1
kind: Pod
metadata:
name: multicontainer
spec:
containers:
- name: webcontainer
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: sharedvolume
mountPath: /usr/share/nginx/html
- name: sidecarcontainer
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do wget -O /var/log/index.html https://raw.githubusercontent.com/omerbsezer/Fast-Kubernetes/main/index.html; sleep 15; done"]
volumeMounts:
- name: sharedvolume
mountPath: /var/log
volumes:
- name: sharedvolume
emptyDir: {}
First version of index.html
on internet link (GitHub):
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World!
<p>
This is the multicontainer scenario!
</p>
</h1>
</center>
</body>
</html>
After 2-3 mins, implement second version of index.html
on internet link (GitHub) and push the second version. However, updating raw.githubusercontent on GitHub takes some time (e.g. 4-6 mins) (https://raw.githubusercontent.com/):
<!-- MultiContainer Update Page -->
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World! This file is created for the multicontainer-sidecar github update.
<p>
This is the multicontainer scenario! Second version.
</p>
</h1>
</center>
</body>
</html>
- Create multicontainer on the pod (webcontainer and sidecarcontainer):
user@k8s:$ kubectl apply -f multicontainer.yaml
pod/multicontainer created
user@k8s:$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
multicontainer 0/2 ContainerCreating 0 16s <none> minikube <none> <none>
user@k8s:$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
multicontainer 2/2 Running 0 20s 10.244.0.3 minikube <none> <none>
- Connect
webcontainer
in the multicontainer pod (bash of the webcontainer) and install net-tools to show ethernet interface (IP: 10.244.0.3)
user@k8s:$ kubectl exec -it multicontainer -c webcontainer -- bash
root@multicontainer:/# ifconfig
bash: ifconfig: command not found
root@multicontainer:/# apt update
Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Get:4 http://deb.debian.org/debian bookworm/main amd64 Packages [8792 kB]
Get:5 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [13.5 kB]
Get:6 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [241 kB]
Fetched 9302 kB in 2s (4603 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
root@multicontainer:/# apt install net-tools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
net-tools
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 243 kB of archives.
After this operation, 1001 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bookworm/main amd64 net-tools amd64 2.10-0.1 [243 kB]
Fetched 243 kB in 0s (1244 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package net-tools.
(Reading database ... 7580 files and directories currently installed.)
Preparing to unpack .../net-tools_2.10-0.1_amd64.deb ...
Unpacking net-tools (2.10-0.1) ...
Setting up net-tools (2.10-0.1) ...
root@multicontainer:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.244.0.3 netmask 255.255.0.0 broadcast 10.244.255.255
inet6 fe80::dc22:5dff:fe50:1574 prefixlen 64 scopeid 0x20<link>
ether de:22:5d:50:15:74 txqueuelen 0 (Ethernet)
RX packets 2862 bytes 9831210 (9.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1505 bytes 118298 (115.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@multicontainer:/# exit
- Connect
sidecarcontainer
in the multicontainer pod (/bin/sh of the sidecarcontainer) and show ethernet interface (IP: 10.244.0.3). - Containers running on same pod have same ethernet interfaces and same IPs (10.244.0.3).
user@k8s:$ kubectl exec -it multicontainer -c sidecarcontainer -- /bin/sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr DE:22:5D:50:15:74
inet addr:10.244.0.3 Bcast:10.244.255.255 Mask:255.255.0.0
inet6 addr: fe80::dc22:5dff:fe50:1574/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3243 errors:0 dropped:0 overruns:0 frame:0
TX packets:1890 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:9965052 (9.5 MiB) TX bytes:155052 (151.4 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # exit
- Under the webcontainer, the shared volume with sidecarcontainer can be reachable:
user@k8s:$ kubectl exec -it multicontainer -c webcontainer -- bash
root@multicontainer:/# cd /usr/share/nginx/html
root@multicontainer:/usr/share/nginx/html# ls
index.html
root@multicontainer:/usr/share/nginx/html# cat index.html
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World!
<p>
This is the multicontainer scenario!
</p>
</h1>
</center>
</body>
</html>
root@multicontainer:/usr/share/nginx/html# exit
exit
- It can be seen from sidecarcontainer. Both of the container can reach same volume area.
- If the new file is created on this volume, other container can also reach same new file.
user@k8s:$ kubectl exec -it multicontainer -c sidecarcontainer -- /bin/sh
/ # cd /var/log
/var/log # ls
index.html
/var/log # cat index.html
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World!
<p>
This is the multicontainer scenario!
</p>
</h1>
</center>
</body>
</html>
/var/log # exit
- When we look at the sidecarcontainer logs, it pulls index.html file from "https://raw.githubusercontent.com/omerbsezer/Fast-Kubernetes/main/index.html" every 15 seconds.
user@k8s:$ kubectl logs -f multicontainer -c sidecarcontainer
Connecting to raw.githubusercontent.com (185.199.111.133:443)
wget: note: TLS certificate validation not implemented
saving to '/var/log/index.html'
index.html 100% |********************************| 307 0:00:00 ETA
'/var/log/index.html' saved
Connecting to raw.githubusercontent.com (185.199.111.133:443)
wget: note: TLS certificate validation not implemented
saving to '/var/log/index.html'
index.html 100% |********************************| 307 0:00:00 ETA
'/var/log/index.html' saved
Connecting to raw.githubusercontent.com (185.199.110.133:443)
wget: note: TLS certificate validation not implemented
saving to '/var/log/index.html'
index.html 100% |********************************| 307 0:00:00 ETA
'/var/log/index.html' saved
- We can forward the port of the pod to the host PC port (hostPort:containerPort, e.g: 8080:80):
user@k8s:$ kubectl port-forward pod/multicontainer 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
Handling connection for 8080
Handling connection for 8080
- On the browser or new terminal, open http://127.0.0.1:8080/
user@k8s:$ curl 127.0.0.1:8080
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World!
<p>
This is the multicontainer scenario!
</p>
</h1>
</center>
</body>
</html>
- After updating the content of the index.html, new html page will be downloaded by the sidecarcontainer:
user@k8s:$ curl 127.0.0.1:8080
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World!
<p>
This is the multicontainer scenario!
</p>
</h1>
</center>
</body>
</html>
user@k8s:$ curl 127.0.0.1:8080
<!-- MultiContainer Update Page -->
<html>
<body style="background-color:gray">
<center>
<h1 style="color:red">
Hello World! This file is created for the multicontainer-sidecar github update.
<p>
This is the multicontainer scenario! Second version.
</p>
</h1>
</center>
</body>
</html>
- Delete multicontainer pod, emptydir volume also deleted. The data in an emptyDir volume is transient and exists only as long as the Pod is running on the node. When the Pod is deleted or rescheduled, the data is lost.:
user@k8s:$ kubectl delete -f multicontainer.yaml
pod "multicontainer" deleted
user@k8s:$ kubectl get pods -o wide
No resources found in default namespace.
user@k8s:$ minikube delete
π₯ Deleting "minikube" in docker ...
π₯ Deleting container "minikube" ...
π₯ Removing /home/omer/.minikube/machines/minikube ...
π Removed all traces of the "minikube" cluster.
Conclusion
This post explores sidecar containers (multiple containers within a single pod) and provides hands-on examples to demonstrate their relationships and shared resources. We also mentioned containers' network connection, port-forwarding, emptydir volume, volume sharing between containers in one pod.
If you're interested in exploring other Kubernetes components, please have a look:
K8s Tutorial - Part 1: Learn and Master Kubernetes, Kubectl, Pods, Deployments, Network, Service
Γmer Berat Sezer γ» Jan 19
Other K8s Feature Post:
Kubernetes Deployment Scaling Up & Down, Horizontal Pod Autoscaling with Hands-on Samples
Γmer Berat Sezer γ» Jan 28
If you found the tutorial interesting, Iβd love to hear your thoughts in the blog post comments. Feel free to share your reactions or leave a comment. I truly value your input and engagement π
For other posts π https://dev.to/omerberatsezer π§
Follow for Tips, Tutorials, Hands-On Labs for AWS, Kubernetes, Docker, Linux, DevOps, Ansible, Machine Learning, Generative AI.
Top comments (0)