Eine Rollout-Story, die alles beeinflusste

Eine Rollout-Story, die alles beeinflusste
Feinde der Realität um 12f-2

Ende April, während die White Walkers Winterfell belagerten, passierte uns etwas Interessanteres: Wir führten einen ungewöhnlichen Rollout durch. Grundsätzlich führen wir (wie alle anderen auch) ständig neue Funktionen in die Produktion ein. Aber dieser war anders. Das Ausmaß war so groß, dass sich alle möglichen Fehler, die wir machen könnten, auf alle unsere Dienste und Benutzer auswirken würden. Dadurch haben wir alles planmäßig, innerhalb der geplanten und angekündigten Ausfallzeit, ohne Folgen für den Vertrieb umgesetzt. Im Artikel geht es darum, wie uns das gelungen ist und wie jeder es zu Hause wiederholen kann.

Ich werde jetzt nicht die architektonischen und technischen Entscheidungen beschreiben, die wir getroffen haben, oder erklären, wie das alles funktioniert. Dabei handelt es sich eher um Randnotizen darüber, wie einer der schwierigsten Rollouts ablief, den ich beobachtet habe und an dem ich direkt beteiligt war. Ich erhebe keinen Anspruch auf Vollständigkeit oder technische Details; möglicherweise erscheinen sie in einem anderen Artikel.

Hintergrund + um welche Funktionalität handelt es sich?

Wir bauen eine Cloud-Plattform Mail.ru Cloud-Lösungen (MCS), wo ich als technischer Direktor arbeite. Und jetzt ist es an der Zeit, IAM (Identity and Access Management) zu unserer Plattform hinzuzufügen, das eine einheitliche Verwaltung aller Benutzerkonten, Benutzer, Passwörter, Rollen, Dienste und mehr ermöglicht. Warum es in der Cloud benötigt wird, ist eine offensichtliche Frage: Alle Benutzerinformationen werden darin gespeichert.

Normalerweise beginnt der Bau solcher Dinge gleich zu Beginn eines Projekts. Aber historisch gesehen waren die Dinge bei MCS etwas anders. MCS wurde in zwei Teilen gebaut:

  • Openstack mit eigenem Keystone-Autorisierungsmodul,
  • Hotbox (S3-Speicher) basierend auf dem Mail.ru Cloud-Projekt,

um die dann neue Dienste entstanden.

Im Wesentlichen handelte es sich dabei um zwei unterschiedliche Arten von Genehmigungen. Außerdem haben wir einige separate Mail.ru-Entwicklungen verwendet, zum Beispiel einen allgemeinen Mail.ru-Passwortspeicher sowie einen selbst geschriebenen OpenID-Connector, dank dem SSO (End-to-End-Autorisierung) im Horizon-Panel bereitgestellt wurde von virtuellen Maschinen (native OpenStack UI).

IAM zu entwickeln bedeutete für uns, alles in einem einzigen System zu verbinden, ganz unserem eigenen. Gleichzeitig werden wir unterwegs keine Funktionalität verlieren, sondern eine Grundlage für die Zukunft schaffen, die es uns ermöglicht, es ohne Refactoring transparent weiterzuentwickeln und hinsichtlich der Funktionalität zu skalieren. Auch zu Beginn hatten Benutzer ein Vorbild für den Zugriff auf Dienste (zentrales RBAC, rollenbasierte Zugriffskontrolle) und einige andere Kleinigkeiten.

Die Aufgabe erwies sich als nicht trivial: Python und Perl, mehrere Backends, unabhängig geschriebene Dienste, mehrere Entwicklungsteams und Administratoren. Und was am wichtigsten ist: Es gibt Tausende von Live-Benutzern im Kampfproduktionssystem. All dies musste geschrieben und vor allem ohne Verluste umgesetzt werden.

Was werden wir einführen?

Um es ganz grob auszudrücken, haben wir in etwa 4 Monaten Folgendes vorbereitet:

  • Wir haben mehrere neue Daemons erstellt, die Funktionen aggregierten, die zuvor in verschiedenen Teilen der Infrastruktur funktionierten. Dem Rest der Dienste wurde in Form dieser Dämonen ein neues Backend verschrieben.
  • Wir haben unseren eigenen zentralen Speicher für Passwörter und Schlüssel geschrieben, der für alle unsere Dienste verfügbar ist und bei Bedarf frei geändert werden kann.
  • Wir haben von Grund auf vier neue Backends für Keystone geschrieben (Benutzer, Projekte, Rollen, Rollenzuweisungen), die tatsächlich die Datenbank ersetzt haben und nun als einziges Repository für unsere Benutzerkennwörter fungieren.
  • Wir haben allen unseren Openstack-Diensten beigebracht, sich für ihre Richtlinien an einen Richtliniendienst eines Drittanbieters zu wenden, anstatt diese Richtlinien lokal von jedem Server zu lesen (ja, so funktioniert Openstack standardmäßig!)

Eine solche umfassende Überarbeitung erfordert große, komplexe und vor allem synchrone Änderungen in mehreren Systemen, die von verschiedenen Entwicklungsteams geschrieben wurden. Nach dem Zusammenbau sollte das gesamte System funktionieren.

Wie kann man solche Änderungen umsetzen, ohne es zu vermasseln? Zuerst beschlossen wir, ein wenig in die Zukunft zu blicken.

Rollout-Strategie

  • Es wäre möglich, das Produkt in mehreren Schritten auszurollen, allerdings würde sich dadurch die Entwicklungszeit um das Dreifache verlängern. Darüber hinaus kam es für einige Zeit zu einer vollständigen Desynchronisierung der Daten in den Datenbanken. Sie müssten Ihre eigenen Synchronisierungstools schreiben und lange Zeit mit mehreren Datenspeichern leben. Und daraus entstehen vielfältige Risiken.
  • Alles, was für den Nutzer transparent aufbereitet werden konnte, wurde im Vorfeld erledigt. Es hat 2 Monate gedauert.
  • Wir haben uns mehrere Stunden Ausfallzeit gegönnt – nur für Benutzeroperationen zum Erstellen und Ändern von Ressourcen.
  • Für den Betrieb aller bereits erstellten Ressourcen waren Ausfallzeiten nicht akzeptabel. Wir haben geplant, dass die Ressourcen während des Rollouts ohne Ausfallzeiten und ohne Auswirkungen auf die Kunden funktionieren sollten.
  • Um die Auswirkungen für unsere Kunden zu verringern, wenn etwas schief geht, haben wir uns entschieden, die Einführung am Sonntagabend vorzunehmen. Weniger Kunden verwalten virtuelle Maschinen nachts.
  • Wir haben alle unsere Kunden gewarnt, dass das Service Management während des für die Einführung ausgewählten Zeitraums nicht verfügbar sein wird.

Exkurs: Was ist ein Rollout?

<Vorsicht, Philosophie>

Was ein Rollout ist, kann jeder IT-Spezialist leicht beantworten. Sie installieren CI/CD und alles wird automatisch an den Store geliefert. 🙂

Natürlich ist das wahr. Die Schwierigkeit besteht jedoch darin, dass bei modernen Tools zur Automatisierung der Codebereitstellung das Verständnis für den Rollout selbst verloren geht. Wie man das Epische der Erfindung des Rades vergisst, wenn man sich den modernen Transport anschaut. Alles ist so automatisiert, dass der Rollout oft durchgeführt wird, ohne das Gesamtbild zu verstehen.

Und das ganze Bild ist so. Der Rollout besteht aus vier Hauptaspekten:

  1. Lieferung des Codes, einschließlich Datenänderung. Zum Beispiel ihre Migrationen.
  2. Beim Code-Rollback handelt es sich um die Möglichkeit, einen Fehler zu beheben, wenn etwas schiefgeht. Zum Beispiel durch die Erstellung von Backups.
  3. Zeitpunkt jedes Rollout-/Rollback-Vorgangs. Sie müssen den Zeitpunkt jeder Operation der ersten beiden Punkte verstehen.
  4. Betroffene Funktionalität. Es ist notwendig, sowohl die erwarteten positiven als auch die möglichen negativen Auswirkungen zu bewerten.

All diese Aspekte müssen für einen erfolgreichen Rollout berücksichtigt werden. Meist wird nur der erste, bestenfalls der zweite Punkt bewertet und dann gilt der Rollout als erfolgreich. Aber der dritte und vierte sind noch wichtiger. Welcher Nutzer würde sich freuen, wenn der Rollout 3 Stunden statt einer Minute dauern würde? Oder wenn beim Rollout etwas Unnötiges beeinträchtigt wird? Oder führt der Ausfall eines Dienstes zu unvorhersehbaren Folgen?

Akt 1..n, Vorbereitung zur Veröffentlichung

Zuerst dachte ich daran, unsere Treffen kurz zu beschreiben: das gesamte Team, seine Teile, jede Menge Diskussionen bei Coffee Points, Argumente, Tests, Brainstorming. Dann dachte ich, es wäre unnötig. Daraus bestehen immer vier Monate Entwicklungszeit, insbesondere wenn man nicht etwas schreibt, das ständig geliefert werden kann, sondern ein großes Feature für ein Live-System. Das betrifft alle Dienste, für Nutzer soll sich aber bis auf „einen Button im Webinterface“ nichts ändern.

Unser Verständnis davon, wie die Einführung erfolgen sollte, änderte sich mit jedem neuen Meeting erheblich. Beispielsweise wollten wir unsere gesamte Abrechnungsdatenbank aktualisieren. Aber wir haben die Zeit berechnet und festgestellt, dass es unmöglich ist, dies in einer angemessenen Rollout-Zeit zu tun. Wir haben fast eine zusätzliche Woche gebraucht, um die Abrechnungsdatenbank zu teilen und zu archivieren. Und als die erwartete Rollout-Geschwindigkeit immer noch nicht zufriedenstellend war, bestellten wir zusätzliche, leistungsstärkere Hardware, wobei die gesamte Basis in die Länge gezogen wurde. Es ist nicht so, dass wir dies nicht schon früher tun wollten, aber die aktuelle Notwendigkeit der Einführung ließ uns keine Optionen.

Als einer von uns Zweifel hatte, dass der Rollout die Verfügbarkeit unserer virtuellen Maschinen beeinträchtigen könnte, führten wir eine Woche lang Tests, Experimente und Codeanalysen durch und erhielten die klare Zusage, dass dies in unserer Produktion nicht passieren würde, und selbst die skeptischsten Personen stimmten zu mit diesem.

In der Zwischenzeit führten die Jungs vom technischen Support eigene, unabhängige Experimente durch, um Anleitungen für Kunden zu Verbindungsmethoden zu schreiben, die sich nach dem Rollout ändern sollten. Sie arbeiteten an der User UX, erstellten Anleitungen und führten persönliche Beratungen durch.

Wir haben alle möglichen Rollout-Vorgänge automatisiert. Jeder Vorgang wurde per Skript ausgeführt, selbst der einfachste, und es wurden ständig Tests durchgeführt. Sie diskutierten über die beste Möglichkeit, den Dienst abzuschalten: den Daemon wegzulassen oder den Zugriff auf den Dienst mit einer Firewall zu blockieren. Wir haben für jede Phase des Rollouts eine Checkliste der Teams erstellt und diese ständig aktualisiert. Wir haben für alle Rollout-Arbeiten ein Gantt-Diagramm mit Zeitangaben erstellt und ständig aktualisiert.

Und so ...

Der letzte Akt vor der Einführung

...es ist Zeit zum Ausrollen.

Wie man so schön sagt, kann man ein Kunstwerk nicht fertigstellen, sondern nur die Arbeit daran beenden. Sie müssen eine Willensanstrengung anstrengen und verstehen, dass Sie nicht alles finden werden, aber auch davon überzeugt sein, dass Sie alle vernünftigen Annahmen getroffen, für alle möglichen Fälle gesorgt, alle kritischen Fehler behoben und alle Teilnehmer alles getan haben, was sie konnten. Je mehr Code Sie ausrollen, desto schwieriger ist es, sich davon zu überzeugen (außerdem versteht jeder, dass es unmöglich ist, alles vorherzusehen).

Wir entschieden uns für die Einführung, als wir davon überzeugt waren, dass wir alles Mögliche getan hatten, um alle Risiken für unsere Benutzer abzudecken, die mit unerwarteten Auswirkungen und Ausfallzeiten verbunden waren. Das heißt, alles kann schief gehen, außer:

  1. Auswirkungen auf die (uns heilige, wertvollste) Benutzerinfrastruktur,
  2. Funktionalität: Die Nutzung unseres Dienstes soll nach dem Rollout die gleiche sein wie davor.

Ausrollen

Eine Rollout-Story, die alles beeinflusste
Zwei würfeln, 8 stören nicht

Für alle Anfragen von Benutzern nehmen wir eine Ausfallzeit von 7 Stunden in Anspruch. Derzeit haben wir sowohl einen Rollout-Plan als auch einen Rollback-Plan.

  • Der Rollout selbst dauert ca. 3 Stunden.
  • 2 Stunden zum Testen.
  • 2 Stunden – Reserve für ein mögliches Rollback von Änderungen.

Für jede Aktion wurde ein Gantt-Diagramm erstellt, wie lange sie dauert, was nacheinander passiert, was parallel erledigt wird.

Eine Rollout-Story, die alles beeinflusste
Ein Teil eines Rollout-Gantt-Diagramms, eine der frühen Versionen (ohne parallele Ausführung). Das wertvollste Synchronisierungstool

Für alle Teilnehmer wird festgelegt, welche Rolle sie beim Rollout spielen, welche Aufgaben sie übernehmen und wofür sie verantwortlich sind. Wir versuchen, jede Phase zur Automatisierung zu bringen, sie auszurollen, wieder zurückzusetzen, Feedback zu sammeln und sie erneut auszurollen.

Chronik der Ereignisse

So kamen am Sonntag, dem 15. April, um 29 Uhr 10 Personen zur Arbeit. Zusätzlich zu den Hauptteilnehmern kamen einige, um das Team einfach zu unterstützen, wofür ihnen ein besonderer Dank gilt.

Erwähnenswert ist auch, dass unser Schlüsseltester im Urlaub ist. Eine Einführung ohne Tests ist nicht möglich, wir prüfen Optionen. Eine Kollegin erklärt sich bereit, uns aus dem Urlaub zu testen, wofür sie vom gesamten Team großen Dank erhält.

00:00. Stoppen
Wir stoppen Benutzeranfragen und hängen ein Schild mit der Aufschrift „Technische Arbeit“ auf. Die Überwachung schreit, aber alles ist normal. Wir prüfen, ob nichts anderes als das, was fallen sollte, heruntergefallen ist. Und wir beginnen mit der Arbeit zum Thema Migration.

Jeder hat Punkt für Punkt einen ausgedruckten Rollout-Plan, jeder weiß, wer was zu welchem ​​Zeitpunkt tut. Nach jeder Aktion überprüfen wir die Zeitvorgaben, um sicherzustellen, dass diese nicht überschritten werden und alles nach Plan verläuft. Diejenigen, die zum jetzigen Zeitpunkt nicht direkt am Rollout teilnehmen, bereiten sich mit der Einführung eines Online-Spielzeugs (Xonotic, Quacksalber vom Typ 3) vor, um ihre Kollegen nicht zu stören. 🙂

02:00. Rollt
Eine angenehme Überraschung: Aufgrund der Optimierung unserer Datenbanken und Migrationsskripte beenden wir den Rollout eine Stunde früher. Der allgemeine Ruf „ausgerollt!“ Alle neuen Funktionen sind in Produktion, aber bisher können wir sie nur in der Benutzeroberfläche sehen. Jeder geht in den Testmodus, ordnet sie in Gruppen ein und beginnt zu sehen, was am Ende passiert ist.

Es ist nicht so gut gelaufen, das merken wir erst nach 10 Minuten, wenn in den Projekten der Teammitglieder nichts mehr angeschlossen ist oder funktioniert. Schnelle Synchronisierung, wir äußern unsere Probleme, legen Prioritäten fest, teilen uns in Teams auf und beginnen mit dem Debuggen.

02:30. Zwei große Probleme gegen vier Augen
Wir finden zwei große Probleme. Wir stellten fest, dass Kunden einige verbundene Dienste nicht sehen würden und es zu Problemen mit Partnerkonten kommen würde. Beides ist auf unvollständige Migrationsskripte für einige Randfälle zurückzuführen. Wir müssen es jetzt beheben.

Wir schreiben Abfragen, die dies erfassen, mit mindestens 4 Augen. Wir testen sie während der Vorproduktion, um sicherzustellen, dass sie funktionieren und nichts kaputt machen. Du kannst weiterrollen. Gleichzeitig führen wir unsere regelmäßigen Integrationstests durch, die einige weitere Probleme aufdecken. Sie sind alle klein, aber sie müssen auch repariert werden.

03:00. -2 Probleme +2 Probleme
Die beiden vorherigen großen Probleme wurden behoben, und fast alle kleineren auch. Alle, die nicht mit den Fehlerbehebungen beschäftigt sind, arbeiten aktiv an ihren Konten und melden, was sie finden. Wir priorisieren, verteilen die Aufgaben auf die Teams und lassen unkritische Aufgaben für den Vormittag übrig.

Wir führen die Tests erneut durch und sie entdecken zwei neue große Probleme. Nicht alle Dienstrichtlinien sind korrekt angekommen, sodass einige Benutzeranfragen die Autorisierung nicht bestehen. Dazu ein neues Problem mit Partnerkonten. Lasst uns schnell nachsehen.

03:20. Notfallsynchronisierung
Ein neues Problem wurde behoben. Zum zweiten organisieren wir eine Notfallsynchronisierung. Wir verstehen, was passiert: Der vorherige Fix hat ein Problem behoben, aber ein anderes verursacht. Wir machen eine Pause, um herauszufinden, wie wir es richtig und ohne Konsequenzen machen können.

03:30. Sechs Augen
Wir verstehen, wie der Endzustand der Basis aussehen sollte, damit für alle Partner alles gut läuft. Wir schreiben eine Anfrage mit 6 Augen, rollen sie in der Vorproduktion aus, testen sie und rollen sie für die Produktion aus.

04:00. Alles arbeitet
Alle Tests bestanden, es sind keine kritischen Probleme erkennbar. Ab und zu klappt bei jemandem im Team etwas nicht, wir reagieren zeitnah. Meistens ist der Alarm falsch. Aber manchmal kommt etwas nicht an oder eine separate Seite funktioniert nicht. Wir sitzen, reparieren, reparieren, reparieren. Ein separates Team führt das letzte große Feature ein – die Abrechnung.

04:30. Punkt ohne Wiederkehr
Der Punkt, an dem es kein Zurück mehr gibt, naht, das heißt der Zeitpunkt, an dem wir, wenn wir mit dem Rollback beginnen, die uns gegebene Ausfallzeit nicht mehr einhalten können. Es gibt Probleme mit der Abrechnung, die alles weiß und aufzeichnet, sich aber hartnäckig weigert, Geld von Kunden abzuschreiben. Es gibt mehrere Fehler auf einzelnen Seiten, Aktionen und Status. Die Hauptfunktionalität funktioniert, alle Tests werden erfolgreich bestanden. Wir entscheiden, dass der Rollout stattgefunden hat und werden keinen Rollout durchführen.

06:00. Offen für alle in der Benutzeroberfläche
Fehler behoben. Einige, die den Benutzern nicht gefallen, bleiben für später übrig. Wir öffnen die Schnittstelle für alle. Wir arbeiten weiterhin an der Abrechnung, warten auf Benutzerfeedback und überwachen die Ergebnisse.

07:00. Probleme mit der API-Last
Es wird deutlich, dass wir die Auslastung unserer API leicht falsch geplant und diese Auslastung getestet haben, wodurch das Problem nicht identifiziert werden konnte. Infolgedessen schlagen ≈5 % der Anfragen fehl. Lasst uns mobilisieren und nach dem Grund suchen.

Die Abrechnung ist stur und will auch nicht funktionieren. Wir beschließen, es auf einen späteren Zeitpunkt zu verschieben, um die Änderungen in Ruhe durchführen zu können. Das heißt, alle Ressourcen werden darin angesammelt, Abschreibungen von Kunden erfolgen jedoch nicht. Das ist natürlich ein Problem, aber im Vergleich zum allgemeinen Rollout erscheint es unwichtig.

08:00. API reparieren
Wir führten einen Fix für die Last aus, die Fehler verschwanden. Wir beginnen, nach Hause zu gehen.

10:00. Alle
Alles ist fest. Es ist ruhig in der Überwachung und beim Kunden schläft das Team nach und nach ein. Die Abrechnung bleibt bestehen, wir stellen sie morgen wieder her.

Im Laufe des Tages gab es dann Rollouts, bei denen Protokolle, Benachrichtigungen, Rückgabecodes und Anpassungen für einige unserer Kunden korrigiert wurden.

Der Rollout war also erfolgreich! Es könnte natürlich besser sein, aber wir haben daraus Rückschlüsse gezogen, was uns nicht reichte, um Perfektion zu erreichen.

Insgesamt

Während der zweimonatigen aktiven Vorbereitung des Rollouts wurden 2 Aufgaben erledigt, die zwischen einigen Stunden und mehreren Tagen dauerten.

Während des Rollouts:

  • neue und veränderte Dämonen – 5 Stück, ersetzen 2 Monolithen;
  • Änderungen innerhalb der Datenbanken – alle 6 unserer Datenbanken mit Benutzerdaten sind betroffen, es wurden Downloads von drei alten Datenbanken in eine neue durchgeführt;
  • komplett neu gestaltetes Frontend;
  • Menge des heruntergeladenen Codes – 33 Zeilen neuer Code, ≈ 3 Zeilen Code in Tests, ≈ 5 Zeilen Migrationscode;
  • Alle Daten sind intakt, die virtuelle Maschine eines einzigen Kunden wurde beschädigt. 🙂

Gute Praktiken für einen guten Rollout

Sie haben uns in dieser schwierigen Situation geführt. Aber im Allgemeinen ist es sinnvoll, sie bei jedem Rollout zu befolgen. Doch je komplexer der Rollout, desto größer ist ihre Rolle.

  1. Als Erstes müssen Sie verstehen, wie sich der Rollout auf die Benutzer auswirken kann oder wird. Wird es Ausfallzeiten geben? Wenn ja, wie hoch ist die Ausfallzeit? Welche Auswirkungen wird dies auf die Benutzer haben? Was sind die möglichen Best- und Worst-Case-Szenarien? Und decken Sie die Risiken ab.
  2. Planen Sie alles. In jeder Phase müssen Sie alle Aspekte der Einführung verstehen:
    • Code-Lieferung;
    • Code-Rollback;
    • Zeitpunkt jeder Operation;
    • beeinträchtigte Funktionalität.
  3. Spielen Sie die Szenarien durch, bis alle Phasen des Rollouts sowie die damit verbundenen Risiken offensichtlich werden. Wenn Sie Zweifel haben, können Sie eine Pause einlegen und die fragliche Phase separat untersuchen.
  4. Jede Stufe kann und sollte verbessert werden, wenn sie unseren Benutzern hilft. Dadurch werden beispielsweise Ausfallzeiten reduziert oder einige Risiken beseitigt.
  5. Rollback-Tests sind viel wichtiger als Code-Delivery-Tests. Es muss überprüft werden, ob das System durch das Rollback in den ursprünglichen Zustand zurückkehrt, und dies durch Tests bestätigt werden.
  6. Alles, was automatisiert werden kann, sollte automatisiert werden. Alles, was nicht automatisiert werden kann, sollte vorab auf einem Spickzettel notiert werden.
  7. Notieren Sie das Erfolgskriterium. Welche Funktionalität soll zu welchem ​​Zeitpunkt verfügbar sein? Wenn dies nicht der Fall ist, führen Sie einen Rollback-Plan aus.
  8. Und vor allem: Menschen. Jeder sollte sich darüber im Klaren sein, was er tut, warum und was von seinem Handeln im Rollout-Prozess abhängt.

Und in einem Satz: Mit guter Planung und Ausarbeitung können Sie alles umsetzen, was Sie wollen, ohne Konsequenzen für den Vertrieb. Sogar etwas, das sich auf alle Ihre Dienstleistungen in der Produktion auswirkt.

Source: habr.com

Kommentar hinzufügen