Fallen auf dem Weg von Blue-Green-Bereitstellungen mit Docker

Docker (wie auch Kubernetes) bietet Ihnen eine Möglichkeit, Ihre Anwendungen ohne Ausfallzeiten durch eine gemeinsame Strategie namens
Blau-Grün-Einsatz.

Blau-Grün-Bereitstellungen funktionieren folgendermaßen:

  1. Ihre derzeit bereitgestellte Anwendung (“Grün”) bedient den eingehenden Datenverkehr.
  2. Eine neue Version Ihrer Anwendung wurde bereitgestellt (“Blau”) und getestet, empfängt aber noch keinen Datenverkehr.
  3. Wenn „Blau“ bereit ist, können wir damit beginnen, den eingehenden Datenverkehr auch an „Blau“ zu senden.
  4. An diesem Punkt laufen zwei Kopien unserer Anwendung parallel (die „Grüne“ und die „Blaue“).
  5. Jetzt müssen wir aufhören, eingehenden Datenverkehr an die Anwendung „Grün“ zu senden, „Blau“ verarbeitet den gesamten eingehenden Datenverkehr.
  6. Da “Grün” keinen Verkehr mehr empfängt, kann es sicher entfernt werden.
  7. Das „Blaue“ wird als „Grünes“ gekennzeichnet, was in Zukunft den Einsatz einer neueren Version mit der gleichen Strategie ermöglicht.

Docker Swarm Blau-Grün-Bereitstellung

Wenn Sie Docker Swarm verwenden, kann dies eine Stapeldatei sein, die die Blau-Grün-Bereitstellungsstrategie implementiert.



version: '3.4'
services:
  app:
    image: acme/todo-list:${VERSION}
    deploy:
      update_config:
        order: start-first

acme/todo-list ist eine einfache Todo-Listen-Webanwendung. Das update_config.order: start-first weist docker swarm an
Verwenden Sie die Blau-Grün-Bereitstellungsstrategie.

Stellen Sie die bereit v1 unserer Todo-Liste in einem Docker-Swarm-Cluster können wir ausführen:

VERSION=v1 docker stack deploy todolist_app -c app.yml

Wenn wir die App aktualisieren möchten v2 wir können laufen:

VERSION=v2 docker stack deploy todolist_app -c app.yml

Das Update folgt der zuvor beschriebenen Blau-Grün-Bereitstellungsstrategie.
Docker behält v1 läuft und wird bereitgestellt v2.
Wann v2 bereit ist, wird der gesamte Datenverkehr umgeleitet v2 und wird entfernt v1. Sauber!

Aber wenn wir uns die Protokolle unseres Load Balancers ansehen, sehen wir Folgendes:

1.2.3.4 - - [13/Jun/2019:06:00:10 +0000] "GET /toto/list HTTP/1.1" 502 150 ....

Der Statuscode ist 502“Schlechter Zugang”.
Dieser HTTP-Statuscode bedeutet, dass der Load Balancer eine ungültige Antwort vom Anwendungsserver (oder keine Antwort) erhalten hat.
Warum ist das so?

Zu entfernen v1sendet Docker nach dem Stoppen des Sendens von eingehendem Datenverkehr die SIG_TERM Signal an die App und wartet
bis zu 10 Sekunden, damit sich die App ordnungsgemäß beendet.
Wenn v1 läuft immer noch nach 10 Sekunden, Docker killt das brutal v1 App.
Dadurch wird jede Verbindung der App beendet (und ausstehende Anfragen erhalten den Fehler 502).

Anmutiger Halt

Wir können die Anzahl der Sekunden ändern, die Docker wartet, bevor der Container entfernt wird, indem wir die stop_grace_period Parameter:



version: '3.4'
services:
  php:
    image: acme/todo-list:${VERSION}
    stop_grace_period: 120s
    deploy:
      update_config:
        order: start-first

Bei dieser Konfiguration wird nach dem Absenden der SIG_TERM signalisiert, wartet Docker bis zu zwei Minuten, bevor er die App beendet.
Abhängig von der spezifischen Logik und den Reaktionszeiten Ihrer Anwendung können Sie Docker mitteilen, wie lange es dauern soll
Warten Sie, bis Ihre Anwendung beendet ist, bevor Sie sie erzwingen.

Blue-Green-Bereitstellungen und PHP-FPM

Wenn Sie PHP-FPM verwenden, reichen die vorherigen Konfigurationen möglicherweise nicht aus.

Leider (?) ist PHP-FPM standardmäßig so konfiguriert, dass es sofort nach Erhalt beendet wird SIG_TERM Signal.
Auch wenn Docker bereit ist, 10 Sekunden zu warten (oder einen anderen Wert, den Sie möglicherweise konfiguriert haben stop_grace_period)
PHP beendet sich selbst (und alle verarbeiteten Anfragen) ohne zu warten.

Dies wird wieder zu führen 502 Fehler.

Um dies zu lösen, müssen wir auch PHP anweisen, sich selbst genügend Zeit zu geben, um die ausstehenden Anforderungen vollständig zu bedienen.
stimmen process_control_timeout Parameter (überprüfen hier für eine vollständige Liste der PHP-FPM-Konfigurationen).

Indem man es einstellt process_control_timeout = 5,
PHP-FPM wartet bis zu 5 Sekunden, bevor alle Prozesse beendet und beendet werden, die Anforderungen bedient haben.

Wir können diesen Parameter in der hinzufügen Dockerfile beim Erstellen unseres PHP-Images.


FROM php:fpm



RUN { \
    echo '[global]'; \
    echo 'process_control_timeout = 5'; \
    } | tee /usr/local/etc/php-fpm.conf
    

So wie Docker darauf gewartet hat, dass ein Container seine Arbeit beendet, tut PHP jetzt dasselbe und wartet bis zu 5 Sekunden
für seine untergeordneten Prozesse, um die Anforderungen zu erfüllen.

Auf diese Weise haben wir konfiguriert, wie lange Docker warten soll, bevor der Container beendet wird, und auch, wie lange PHP
wird warten, bis die Anfragen abgeschlossen sind.

Wenn PHP in weniger als 5 Sekunden aufhören kann zu laufen, wird es dies tun (zum Beispiel, wenn alle ausstehenden Anfragen schnell bedient werden).
Gleiches gilt für Docker.
Auf diese Weise werden diese Timeouts nur für den schlimmsten Fall angewendet.

Dieser Beitrag wurde zuerst veröffentlicht am https://www.goetas.com/blog/traps-on-the-way-of-blue-green-deployments/.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *