Use #docker-compose to manage Pods on #Docker

Docker does not implement the concept of a pod. But pods can be created by explicitly sharing the network namespace of containers. With docker-compose it is possible to manage pods in an declarative way using the network_mode field.

What are pods

Pods consist of one or more containers that are sharing a context. Typically these containers share the network namespace. This requires them to be scheduled on the same host. A pods implements the concept of a logical host.

In Kubernetes, pods are the smallest unit of deployment. As Docker does not implement them natively, pods must be constructed by creating multiple containers with a shared network namespace.

Managing pods using docker-compose

The following docker-compose.yaml describes a list of services which are sharing the network namespace by pointing the network_mode field to another service. The top most service called pod is used to create the initial container including a new network namespace. All addition pods are created to share the network namespace with this service.

version: "3.3"

services:

  pod:
    image: alpine
    command: [ "sh", "-c", "while true; do sleep 5; done" ]

  dind:
    image: docker:stable-dind
    command: [ "dockerd", "--host", "tcp://127.0.0.1:2375" ]
    privileged: true
    depends_on:
    - pod
    network_mode: service:pod

  registry:
    image: registry:2
    depends_on:
    - pod
    network_mode: service:pod

Note that docker-compose was not created to manage pods. Therefore scaling does not make sense in the context of pods because additional containers created for a services will be sharing the network namespace as well. As the services registry and dind are using fixed ports, scaling will also fail because the ports cannot be reused on the same host.

Using YAML anchors

You have probably noticed that the fields network_mode and depends_on are repeated for every service in the pod. These fields can be factored out using YAML anchors in docker-compose. You will have to increase the field version to at least 3.4.

version: "3.4"

x-pod-template: &pod
  depends_on:
  - pod
  network_mode: service:pod

services:

  pod:
    image: alpine
    command: [ "sh", "-c", "while true; do sleep 5; done" ]

  registry:
    <<: *pod
    image: registry:2

  dind:
    <<: *pod
    image: docker:stable-dind
    command: [ "dockerd", "--host", "tcp://127.0.0.1:2375" ]
    privileged: true

Managing pods explicitly

Please refer to my earlier post about managing pods using Docker how to achieve this manually.

I have also published a Docker CLI plugin for managing pods.

Feedback is always welcome! If you'd like to get in touch with me concerning the contents of this article, please use Twitter.