Skip to content

Sidecar Containers

Environment Variables

We are going to use some environment variables in this tutorial. Please make sure you have set them correctly.

# check if the environment variables are set if not set them
export NAMESPACE=<namespace>
echo $NAMESPACE

Let’s first have another look at the Pod’s description on the Kubernetes documentation page:

Quote

A Pod (as in a pod of whales or pea pod) is a group of one or more containers (such as Docker containers), with shared storage/network, and a specification for how to run the containers. A Pod’s contents are always co-located and co-scheduled, and run in a shared context. A Pod models an application-specific “logical host” - it contains one or more application containers which are relatively tightly coupled — in a pre-container world, being executed on the same physical or virtual machine would mean being executed on the same logical host. The shared context of a Pod is a set of Linux namespaces, cgroups, and potentially other facets of isolation - the same things that isolate a Docker container. Within a Pod’s context, the individual applications may have further sub-isolations applied.

A sidecar container is a utility container in the Pod. Its purpose is to support the main container. It is important to note that the standalone sidecar container does not serve any purpose, it must be paired with one or more main containers. Generally, sidecar containers are reusable and can be paired with numerous types of main containers.

In a sidecar pattern, the functionality of the main container is extended or enhanced by a sidecar container without strong coupling between the two. Although it is always possible to build sidecar container functionality into the main container, there are several benefits with this pattern:

  • Different resource profiles, i.e. independent resource accounting and allocation
  • Clear separation of concerns at packaging level, i.e. no strong coupling between containers
  • Reusability, i.e., sidecar containers can be paired with numerous “main” containers
  • Failure containment boundary, making it possible for the overall system to degrade gracefully
  • Independent testing, packaging, upgrade, deployment and if necessary rollback

Task 1: Create a sidecar container

We want to create a Pod that runs a sidecar container that reads a log file and prints it to stdout. The main container writes a log file every seconds.

Create a file called sidecar-pod.yaml with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
spec:
  initContainers:
    - name: init
      image: busybox
      command:
        - 'sh'
        - '-c'
        - 'echo "init" >> /work-dir/test.log'
      volumeMounts:
        - name: workdir
          mountPath: /work-dir
  containers:
  - name: logwriter
    image: busybox
    command:
      - 'sh'
      - '-c'
      - 'while true; do printf "%s %s\n" "$(date)" >> /work-dir/test.log; sleep 1; done'
    resources:
      requests:
        cpu: 10m
        memory: 16Mi
      limits:
        cpu: 20m
        memory: 32Mi
    volumeMounts:
      - name: workdir
        mountPath: /work-dir
  - name: logreader
    image: busybox
    command:
    - 'sh'
    - '-c'
    - 'while true; do cat /work-dir/test.log; sleep 1; done'
    resources:
      requests:
        cpu: 10m
        memory: 16Mi
      limits:
        cpu: 20m
        memory: 32Mi
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  volumes:
  - name: workdir
    emptyDir: {}

Apply the file:

kubectl apply -f sidecar-pod.yaml --namespace $NAMESPACE

Check the logs of the logreader container:

kubectl logs sidecar-demo logreader --namespace $NAMESPACE --follow

You should see the log file being printed to stdout every second.

Note

The --follow flag tells kubectl to keep the connection open and stream the logs.