Das Buchungsportal der Nordlicht Reisen GmbH wird auch am Vormittag bedient, wenn Reisende buchen. Ein Neustart bei jeder Auslieferung ist dann nicht hinnehmbar. Und wenn am Freitagnachmittag ein Fehler auffällt, der Buchungen verhindert, braucht das Team einen Weg, der schneller ist als der gewöhnliche, ohne die Regeln der Auslieferung zu verlassen. Das sind die Fähigkeiten dieser Lektion: Ausfallzeit minimieren (Lastverteilung, rollende Aktualisierung, Slots und Tausch), ein Hotfix-Pfad und eine Resilienzstrategie für die Bereitstellung.

Vorwissen: Das Zurückrollen von Revisionen in Azure Container Apps lehrt K3, Lektion 3.7.6; die Strategien als Entwurf, Blue-Green und gewichteter Verkehr stehen in Lektion 4.8, Prüfungen und Umgehen im Notfall in Lektion 4.7, Verzweigungsmodelle in Lektion 2.1. Diese Lektion nimmt das als bekannt an und fragt: Wie bleibt die Anwendung während der Auslieferung erreichbar, wie sieht der Notfallweg aus, und was gehört in die Strategie, damit eine misslungene Auslieferung klein bleibt?

Nicht gegen Azure, GitHub oder Azure DevOps ausgeführt; aus der Referenz von Microsoft und GitHub: Alle Befehle, YAML-Dateien und Menüpfade dieser Lektion stammen aus der Dokumentation oder sind aus ihr abgeleitet; sie sind in diesem Kurs nicht ausgeführt worden.

Ausfallzeit minimieren

Microsoft setzt das Ziel hoch: Teams sollen sich mit der Haltung nähern, neue Versionen ohne jede Ausfallzeit bereitzustellen. Moderne Infrastruktur und Pipelines machten das für fast jedes Team möglich. Daraus folgt eine zweite Haltung: Wenn nichts ausfällt, ist es gleichgültig, wann ausgeliefert wird, und es ist sogar vorteilhaft, während der Arbeitszeit auszuliefern, am besten früh am Tag und früh in der Woche, denn alle sind da und der Wirkungsradius eines Fehlers bleibt kontrollierbar. Dafür gibt es drei Mittel.

Lastverteilung

Ein Load Balancer verteilt Anfragen auf Instanzen. Für Bereitstellungen zählt seine Gesundheitsprüfung (health probe): Fällt sie für eine Instanz aus, schickt der Load Balancer keine neuen Verbindungen mehr dorthin. Die Instanz kann also aus der Rotation genommen, aktualisiert und wieder aufgenommen werden. Was Microsoft dazu sagt:

  • Die Prüfung entscheidet, welche Instanzen neue Verbindungen bekommen. Bestehende TCP-Verbindungen zu einer ausgefallenen Instanz laufen bei einem Standard Load Balancer weiter, bis die Anwendung sie beendet, eine Leerlaufgrenze greift oder die VM heruntergefahren wird. Eine Aktualisierung unterbricht sie also, wenn die Maschine neu startet.
  • Der Prüfport soll den Zustand der Instanz und des Dienstes abbilden. Die Anwendung kann ihre Antwort selbst steuern: Mit einer fehlschlagenden Prüfung entlastet sie sich oder bereitet eine Wartung vor, und die Verbindungen laufen aus (Draining).
  • Der Administrative Status (admin state) überschreibt die Prüfung für eine Instanz: Down nimmt sie unabhängig von der Prüfung aus der Rotation, Up hält sie drin. Das ist für Wartung gedacht, also für Bereitstellungen, die man selbst steuert.
  • Einstellbar sind Intervall und Schwelle der Prüfung.

Eine Prüfung, die zu streng ist, ist ein Risiko, keine Hilfe: Antwortet die Anwendung beim Start zu langsam, nimmt der Load Balancer sie sofort wieder heraus. Microsoft nennt als häufige Ursachen für ausgefallene Prüfungen eine Anwendung, die den Prüfport nicht belegt, eine Netzwerksicherheitsgruppe, die die Quelladresse der Prüfung (168.63.129.16) blockiert, und eine Anwendung, die langsamer antwortet als die Zeitgrenze der Prüfung.

Rollende Aktualisierung

Bei einer rollenden Aktualisierung (rolling update) werden Instanzen in Gruppen ersetzt, so dass immer ein Teil der Instanzen antwortet. Zwei Wege in unserer Werkzeugwelt:

Deployment-Job mit rolling (Lektion 4.8): Der Stapel wird mit maxParallel festgelegt (Zahl oder Prozent), preDeploy, deploy, routeTraffic und postRouteTraffic laufen je Stapel, danach on: success oder on: failure. Die Strategie gilt laut Microsoft nur für Ressourcen vom Typ virtuelle Maschine; nach der Beschreibung bleibt die Anwendung auf den übrigen Maschinen erreichbar, während der Stapel aktualisiert wird, und eine Gesundheitsprüfung nach jedem Stapel kann die Auslieferung stoppen.

Virtual Machine Scale Sets haben eine Upgrade-Richtlinie mit drei Modi:

Modus Verhalten Wofür
Automatic keine Garantie über die Reihenfolge; die Instanzen können gleichzeitig ausfallen Entwicklung und Test, wo Verfügbarkeit nicht zählt
Manual Sie bestimmen, wann Instanzen aktualisiert werden; neue Instanzen erhalten das aktuelle Modell Arbeitslasten, die mehr Kontrolle brauchen
Rolling Aktualisierung in Stapeln mit Stapelgröße, höchstem Anteil gesunder Instanzen und weiteren Einstellungen Produktion, in der eine bestimmte Zahl Instanzen immer verfügbar sein muss

Microsoft nennt Rolling den sichersten Weg, Instanzen auf das neueste Modell zu bringen, ohne Verfügbarkeit zu opfern. Bedingung: Das Scale Set braucht eine Gesundheitssignal, nämlich bei einheitlicher Orchestrierung eine Prüfung des Load Balancers oder die Application Health extension, bei flexibler Orchestrierung die Erweiterung. Manche Änderungen verlangen Neustart, Neuabbild oder Neubereitstellung: Kennwort oder SSH-Schlüssel, Bild-Verweise, Größenänderungen und das Hinzufügen von Verfügbarkeitszonen. Das ist die Grenze: Auch Rolling verhindert den Neustart der einzelnen Instanz nicht, es verhindert nur, dass alle gleichzeitig neu starten.

Slots und Tausch (swap)

Ein Bereitstellungsslot ist eine lebende App mit eigenem Hostnamen im selben App-Service-Plan. Voraussetzung sind die Stufen Standard, Premium oder Isolated; die Zahl der Slots hängt von der Stufe ab (bei Standard fünf). Microsoft nennt als Vorteile:

  • Sie prüfen Änderungen im Slot, bevor Sie sie in die Produktion tauschen.
  • Sie wärmen alle Instanzen des Slots vor dem Tausch auf; das beseitigt Ausfallzeit, und die Umleitung des Verkehrs verwirft keine Anfragen.
  • Nach dem Tausch hält der Slot die vorige Produktionsfassung; fällt etwas auf, tauschen Sie sofort zurück.
  • Slots kosten nichts extra (der Plan zählt).

Was beim Tausch geschieht (Auszug der Schritte): App Service wendet zuerst die Einstellungen des Ziels (zum Beispiel des Produktions-Slots) auf alle Instanzen der Quelle an: slot-spezifische Einstellungen und Verbindungszeichenfolgen, Einstellungen der kontinuierlichen Bereitstellung und der Authentifizierung. Das startet alle Instanzen der Quelle neu. Es wartet, bis alle Instanzen den Neustart abgeschlossen haben; scheitert eine, macht der Tausch alle Änderungen an der Quelle rückgängig und bricht ab. Dann wird warmgelaufen: Ohne weitere Angabe fragt App Service die Wurzel der Anwendung (/) ab, und eine Instanz gilt als warm, sobald sie irgendeine HTTP-Antwort liefert. Erst wenn alle Instanzen der Quelle warm sind, tauschen beide Slots ihre Routingregeln. Die ganze Vorbereitung geschieht in der Quelle; das Ziel bleibt online. Deshalb soll die Produktion immer das Ziel sein.

Was getauscht wird und was nicht: Getauscht werden unter anderem Frameworkeinstellungen, App-Einstellungen, Verbindungszeichenfolgen, eingebundene Speicher, Handler-Zuordnungen, öffentliche Zertifikate und WebJobs-Inhalt. Nicht getauscht werden unter anderem Protokolleinstellungen (nur HTTPS, TLS-Version), Veröffentlichungsendpunkte, benutzerdefinierte Domänen, nicht öffentliche Zertifikate, Skalierungseinstellungen, IP-Einschränkungen, Always On, Diagnoseprotokolle, CORS, verwaltete Identitäten und die Einbindung in ein virtuelles Netz. Ein App-Setting können Sie am Slot festhalten (Deployment slot setting), so dass es nicht mit dem Inhalt wandert; das ist für Werte wie die Adresse der Datenbank der jeweiligen Umgebung der Normalfall.

Das Warmlaufen steuern: Reicht die Wurzel nicht, geben Sie eine eigene Seite an. Entweder in der Web.config mit applicationInitialization, oder mit App-Settings: WEBSITE_SWAP_WARMUP_PING_PATH (Pfad, der mit Schrägstrich beginnt, Voreinstellung /), WEBSITE_SWAP_WARMUP_PING_STATUSES (kommagetrennte Statuscodes, zum Beispiel 200,202; liefert die Seite einen anderen Code, stoppen Warmlaufen und Tausch; voreingestellt ist jeder Code gültig) und WEBSITE_WARMUP_PATH (wird bei jedem Neustart der Seite abgefragt, nicht nur beim Tausch). Der Tausch wartet pro Anfrage 90 Sekunden und versucht es bis zu fünf Mal; scheitern alle, bricht er ab.

Tausch mit Vorschau (swap with preview, mehrphasig): App Service führt den ersten Schritt aus (Einstellungen des Ziels auf die Quelle, Neustart) und hält an. Jetzt prüfen Sie die Quelle mit den Einstellungen der Produktion. Dann vollenden Sie den Tausch oder brechen ab; beim Abbrechen setzt App Service die Einstellungen der Quelle zurück. Das geht nicht, wenn in einem der Slots die Authentifizierung der Seite eingeschaltet ist.

PowerShell
az webapp deployment slot swap --resource-group <gruppe> --name <app> --slot staging --target-slot production --action preview
az webapp deployment slot swap --resource-group <gruppe> --name <app> --slot staging --target-slot production --action swap
az webapp deployment slot swap --resource-group <gruppe> --name <app> --slot staging --target-slot production --action reset

Die erste Zeile startet die Vorschau, die zweite vollendet den Tausch, die dritte bricht ab. Ohne --action tauscht der Befehl in einem Schritt. Zurücktauschen heißt: dieselben beiden Slots sofort noch einmal tauschen. Auto-Tausch tauscht nach jedem Push in den Slot selbsttätig, sobald er warm ist; er ist bei Web-Apps unter Linux und Web App for Containers nicht verfügbar, und Microsoft rät, ihn zuerst an einem Nicht-Produktions-Ziel zu erproben. Wichtig für den Entwurf: Die alten Produktionsinstanzen werden im letzten Schritt recycelt; was dort läuft (lange Vorgänge), bricht ab. Schreiben Sie die Anwendung fehlertolerant.

In der Pipeline

Azure Pipelines hat für beides Aufgaben. Bereitstellen in den Slot, danach tauschen:

YAML
- task: AzureWebApp@1
  inputs:
    azureSubscription: <Dienstverbindung>
    appType: webApp
    appName: <app>
    deployToSlotOrASE: true
    resourceGroupName: <gruppe>
    slotName: staging
    package: $(Pipeline.Workspace)/drop/*.zip

- task: AzureAppServiceManage@0
  inputs:
    azureSubscription: <Dienstverbindung>
    WebAppName: <app>
    ResourceGroupName: <gruppe>
    SourceSlot: staging
    SwapWithProduction: true

AzureAppServiceManage@0 kennt auch die Aktionen für den Tausch mit Vorschau (Start Swap With Preview, Complete Swap, Cancel Swap) und das Löschen eines Slots. In GitHub Actions rufen Sie dieselben az-Befehle in run-Schritten auf, nach dem Anmelden mit OpenID Connect (K3, Lektion 3.7.5); die Aktion azure/webapps-deploy hat für Slots eine eigene Eingabe, deren Namen Sie in ihrer Dokumentation nachlesen. Den Tausch legen Sie in beiden Welten in die Stufe, die die Genehmigung der Produktion trägt (Lektion 4.7), und den Rückweg als eigenen, von Hand startbaren Lauf.