K8s by Example: Sidecar Pattern

The sidecar pattern deploys helper containers alongside your main application container in the same Pod. Sidecars share the Pod’s network namespace (localhost) and can share volumes. Use for: logging, monitoring, proxying, configuration sync, and security.

sidecar-logging.yaml

A logging sidecar reads application logs from a shared volume and ships them to a centralized logging system. The main app writes logs to a file; the sidecar streams them.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-logging
spec:
  containers:
    - name: app
      image: my-app:v1
      volumeMounts:
        - name: logs
          mountPath: /var/log/app

The fluentd sidecar container shares the same volume and continuously tails the log file, forwarding entries to your log aggregator (Elasticsearch, Loki, etc.).

    - name: log-shipper
      image: fluent/fluentd:v1.16
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
          readOnly: true
  volumes:
    - name: logs
      emptyDir: {}
sidecar-git-sync.yaml

A git-sync sidecar keeps configuration files updated by periodically pulling from a Git repository. The main app reads config from a shared volume that the sidecar keeps synchronized.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-config
spec:
  containers:
    - name: app
      image: nginx:alpine
      volumeMounts:
        - name: config
          mountPath: /usr/share/nginx/html
    - name: git-sync
      image: registry.k8s.io/git-sync/git-sync:v4.2.1
      args:
        - --repo=https://github.com/org/config
        - --root=/data
        - --period=60s
      volumeMounts:
        - name: config
          mountPath: /data
  volumes:
    - name: config
      emptyDir: {}
sidecar-https.yaml

An HTTPS termination sidecar handles TLS, allowing legacy apps to serve HTTP on localhost. Nginx terminates SSL on port 443 and proxies to the app on localhost:8080. Both containers share the network namespace.

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  containers:
    - name: app
      image: legacy-http-app:v1
      ports:
        - containerPort: 8080
    - name: ssl-proxy
      image: nginx:alpine
      ports:
        - containerPort: 443
      volumeMounts:
        - name: ssl-certs
          mountPath: /etc/nginx/certs
        - name: nginx-conf
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: ssl-certs
      secret:
        secretName: app-tls
    - name: nginx-conf
      configMap:
        name: nginx-ssl-config
nginx-ssl-config.yaml

The nginx ConfigMap configures SSL termination. It listens on 443, terminates TLS, and proxies requests to the app container on localhost:8080 (shared network namespace).

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ssl-config
data:
  default.conf: |
    server {
      listen 443 ssl;
      ssl_certificate /etc/nginx/certs/tls.crt;
      ssl_certificate_key /etc/nginx/certs/tls.key;
      location / {
        proxy_pass http://localhost:8080;
      }
    }
sidecar-monitoring.yaml

A monitoring sidecar collects metrics from the main app and exposes them in Prometheus format. The sidecar queries the app’s internal metrics endpoint and transforms them to a standard format.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-metrics
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
spec:
  containers:
    - name: app
      image: my-app:v1
      ports:
        - containerPort: 8080
    - name: metrics-exporter
      image: prom/statsd-exporter:v0.26.0
      ports:
        - containerPort: 9090
          name: metrics
terminal

Sidecar containers start and stop with the Pod. Check both containers are Running. Shared volumes appear in each container’s mounts. Logs from each container are accessed separately.

$ kubectl get pods app-with-logging
NAME              READY   STATUS    RESTARTS   AGE
app-with-logging  2/2     Running   0          5m

$ kubectl logs app-with-logging -c app
Application started on port 8080

$ kubectl logs app-with-logging -c log-shipper
Fluentd started, tailing /var/log/app/*.log

$ kubectl exec app-with-logging -c app -- ls /var/log/app
application.log

Index | GitHub | Use arrow keys to navigate |