Rolling Updates mit Docker Compose

In diesem Beispiel geht es darum, händisch einen Service, der via Docker Compose bereitgestellt wird, zu updaten.

Dazu haben wir folgende (nicht ganz so sinnvolle) docker-compose.yml:

version: '3'

services:
  nginx:
    image: nginx:1.22.1-perl
    restart: unless-stopped
    stop_grace_period: 130s
    deploy:
        mode: replicated
        replicas: 5
        update_config:
            failure_action: rollback
            parallelism: 1
            delay: 20s
            order: start-first
        rollback_config:
            parallelism: 1
            delay: 20s
            order: stop-first

Starten wir diesen Stack mit docker compose up und schauen wir uns mit docker ps die Container an, sehen wir (wie erwartet) die 5 nginx-Container:

Unsere Aufgabe nun: mit möglichst zero downtime alle Container auf 1.23.3-alpine hochzuziehen.

Dazu passen wir das Tag unter image in der docker-compose.yml an:

version: '3'

services:
  nginx:
    image: nginx:1.23.3-alpine
    restart: unless-stopped
    stop_grace_period: 130s
    deploy:
        mode: replicated
        replicas: 5
        update_config:
            failure_action: rollback
            parallelism: 1
            delay: 20s
            order: start-first
        rollback_config:
            parallelism: 1
            delay: 20s
            order: stop-first

Mit dem Befehl docker compose up -d --scale nginx=10 --no-recreate erstellen wir nun 5 (5 laufen, scale = 10) zusätzliche Container in der neuen Version. Die alten behalten wir – deswegen das --no-recreate

Wir haben nun also 10 Container, 5 davon in der neuen Version, 5 in der alten.

Nun skalieren wir unsere Container wieder mit docker compose up -d --scale nginx=5 --no-recreate auf die gewünschten 5 Container runter. Docker löscht nun automatisch die Container, die am längsten laufen – und damit auch die, die noch auf der alten Version laufen:

Und schon sind alle unsere Container up2date – ohne Downtime 👍

Natürlich können wir auch, wenn wir Websocket-Verbindungen o.ä. nutzen, erst von 10 auf 9, nach ein paar Stunden auf 8, dann auf 7, etc. runter skalieren. Dann haben nicht alle Clients gleichzeitig einen disconnect.

Bonus-Info: wir geben in der docker-compose.yml zwar etwas unter update_config an; das greift allerdings nur, wenn wir in einem Swarm via docker stack deploy ausrollen.

Kategorien:Docker