Multi-Container Pods
A Pod can hold several containers that cooperate closely, often using the sidecar pattern.
While most Pods run one container, sometimes two containers are so tightly coupled that they should share a network and disk. That is when you put them in the same Pod.
The sidecar pattern
A sidecar is a helper container that supports the main one. Common examples:
- A log-shipping container that reads files the main app writes.
- A proxy that handles TLS or service-mesh traffic.
- A container that syncs content from Git into a shared volume.
Because containers in a Pod share localhost and can mount the same volume, they communicate cheaply and directly.
Example
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
volumes:
- name: shared-logs
emptyDir: {}
containers:
- name: app
image: nginx:1.27
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
- name: log-shipper
image: busybox:1.36
command: ["sh", "-c", "tail -f /logs/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /logsWhen to use it
- A service mesh sidecar (Envoy) is added as a second container in every Pod to handle mTLS and traffic routing without changing the main application.
- A log-shipping sidecar reads the application's log files from a shared volume and forwards them to an Elasticsearch cluster.
- An init container fetches configuration secrets from Vault and writes them to a shared volume before the main application container starts.
More examples
App with log-shipper sidecar
Pairs a main application container with a Fluentd sidecar, both sharing an emptyDir volume so the sidecar can ship logs.
apiVersion: v1
kind: Pod
metadata:
name: web-with-logger
spec:
containers:
- name: web
image: myapp:1.0
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-shipper
image: fluentd:v1.16
volumeMounts:
- name: logs
mountPath: /var/log/app
volumes:
- name: logs
emptyDir: {}Envoy sidecar for traffic proxy
Adds an Envoy proxy as a sidecar that intercepts network traffic for the main container, enabling service mesh features.
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
- name: envoy
image: envoyproxy/envoy:v1.28
ports:
- containerPort: 9901 # admin
- containerPort: 15001 # proxyShare namespace between containers
Shows that containers in the same Pod share a network namespace, so they can communicate over localhost, and how to exec into a specific container.
kubectl exec -it web-with-logger -c web -- /bin/sh
# From inside web container, localhost resolves to sidecar too
curl http://localhost:9901/ready # Envoy admin endpoint
# Or target the sidecar directly
kubectl exec -it web-with-logger -c envoy -- envoy --version
Discussion