Skip to content

evolutics/zero-downtime-deployments-with-podman

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zero-downtime deployments with Podman (or Docker)

The motivation is to deploy an updated version of a container without service interruption. We want to keep things lightweight and only use rootless Podman.

Overview

Say we want to replace a service container hi-0 by hi-1. To keep the service always available during such a deployment, a reverse proxy forwards access to the service container(s) via their identical network alias "greet":

flowchart TD
    localhost:8080 ---|:81| proxy[Container reverse-proxy]
    proxy ---|greet:8282| hi0[Container hi-0]
    proxy ---|greet:8282| hi1[Container hi-1]
Loading

At any given time, at least one service container is available by making sure their lifetimes overlap:

____________________________________
Container hi-0                      Stop
                        ____________________________________
                        Start                 Container hi-1

                        ^^^^^^^^^^^^
                        Overlap

Demo

The following shows how to do such a deployment interactively.

  1. Run the reverse proxy on a network with

    podman network create test-net
    
    podman run --detach --name reverse-proxy --network test-net \
      --publish 127.0.0.1:8080:81 \
      docker.io/caddy:2 caddy reverse-proxy --from :81 --to greet:8282

    This Caddy reverse proxy forwards port 81 to the DNS name "greet", port 8282.

  2. Start version A of your service with

    podman run --detach --name hi-0 --network test-net --network-alias greet \
      docker.io/hashicorp/http-echo:1.0 -listen=:8282 -text='Hi from A'

    This container responds with a greeting to requests on port 8282. Most importantly, we give it the network alias "greet".

    Testing with curl localhost:8080 should now return "Hi from A".

    To see the following update in action, you could keep a test loop running in a separate shell session with

    while true; do curl --fail --max-time 0.2 localhost:8080; sleep 0.01s; done
  3. Start version B of your service with

    podman run --detach --name hi-1 --network test-net --network-alias greet \
      docker.io/hashicorp/http-echo:1.0 -listen=:8282 -text='Hi from B'

    At this point, both service versions are running at the same time with the same network alias.

  4. Stop version A of your service with

    podman stop hi-0

    Testing with curl localhost:8080 should now return "Hi from B". With that, the update is deployed.

You can clean up above experiments with

podman rm --force hi-0 hi-1 reverse-proxy
podman network rm test-net

Run the whole demo automatically with the script scripts/demo.sh.

Docker

Above also works with Docker, just replace podman by docker in the commands.

Docker Compose

Above can be automated in Docker Compose with Kerek (see example there).

About

Zero-downtime deployments with Podman (or Docker)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published