Eine Rollout-Geschichte, die alles betraf


Feinde der Wirklichkeit von 12f-2

Ende April, als die weißen Wanderer Winterfell belagerten, passierte uns etwas Interessanteres, machten wir einen ungewöhnlichen Roll-out. Im Prinzip rollen wir ständig neue Funktionen in das Produkt (wie alle anderen auch). Aber dieser war nicht wie alle anderen. Das Ausmaß war so bemessen, dass potenzielle Fehler, die wir machen könnten, alle unsere Dienste und Benutzer betreffen würden. Infolgedessen haben wir alles planmäßig in der geplanten und angekündigten Ausfallzeit ohne Konsequenzen für den Verkauf eingeführt. Der Artikel handelt davon, wie wir dies erreicht haben und wie diejenigen, die dies wünschen, dies zu Hause wiederholen können.

Ich werde jetzt nicht unsere architektonischen und technischen Entscheidungen beschreiben, sondern erklären, wie alles funktioniert. Dies sind eher Randbemerkungen darüber, wie einer der schwierigsten Rollouts stattgefunden hat, den ich beobachtet habe und an dem ich direkt teilgenommen habe. Ich gebe nicht vor, vollständige oder technische Details zu sein, vielleicht erscheinen sie in einem anderen Artikel.

Hintergrund + welche Art von Funktionalität ist das?


Wir bauen die Cloud-Plattform Mail.ru Cloud Solutions (MCS) auf, auf der ich als CTO arbeite. Und jetzt ist es an der Zeit, eine Verbindung zu unserer Plattform IAM (Identity and Access Management) herzustellen, die eine einheitliche Verwaltung aller Benutzerkonten, Benutzer, Kennwörter, Rollen, Dienste und mehr bietet. Warum es in der Cloud benötigt wird, ist eine offensichtliche Frage: Es speichert alle Benutzerinformationen.

Normalerweise beginnen solche Dinge zu Beginn eines Projekts aufzubauen. Aber MCS war historisch gesehen etwas anders. MCS wurde in zwei Teilen gebaut:

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

um welche neue Dienste erschienen dann.

Im Wesentlichen handelte es sich dabei um zwei verschiedene Arten von Genehmigungen. Außerdem haben wir einige separate Mail.ru-Entwicklungen verwendet, beispielsweise den allgemeinen Mail.ru-Kennwortspeicher sowie einen selbstgeschriebenen OpenID-Connector, der SSO (Pass-Through-Autorisierung) im Horizon-Bereich virtueller Maschinen (native UI OpenStack) aktiviert.

IAM zu machen bedeutete für uns, all dies in einem einzigen System zu kombinieren, ganz unserem eigenen. Verlieren Sie gleichzeitig keine Funktionalität, schaffen Sie eine Reserve für die Zukunft, die es uns ermöglicht, sie transparent zu ändern, ohne sie umzugestalten, und sie hinsichtlich der Funktionalität zu skalieren. Ebenfalls zu Beginn erschienen die Benutzer als Vorbild für den Zugriff auf Dienste (zentraler RBAC, rollenbasierte Zugriffskontrolle) und einige andere Kleinigkeiten.

Die Aufgabe erwies sich als nicht trivial: Python und Perl, mehrere Backends, unabhängig geschriebene Services, mehrere Entwicklungsteams und Administratoren. Und vor allem Tausende von Live-Benutzern im Kampfproduktionssystem. All dies musste geschrieben und vor allem ohne Verluste eingeführt werden.

Was werden wir ausrollen?


Wenn es sehr unhöflich ist, haben wir dies in 4 Monaten vorbereitet:

  • Sie machten mehrere neue Dämonen, die Funktionen aggregierten, die zuvor in verschiedenen Teilen der Infrastruktur funktionierten. Anderen Diensten wurde ein neues Backend in Form dieser Dämonen verschrieben.
  • Wir haben unser eigenes zentrales Repository mit Passwörtern und Schlüsseln erstellt, das für alle unsere Dienste verfügbar ist und bei Bedarf frei geändert werden kann.
  • Von Grund auf haben sie 4 neue Backends für Keystone geschrieben (Benutzer, Projekte, Rollen, Rollenzuweisungen), die tatsächlich ihre Basis ersetzten und jetzt als ein einziges Repository unserer Benutzerkennwörter fungieren.
  • Wir haben allen unseren Openstack-Diensten beigebracht, ihre Richtlinien einem Richtliniendienst eines Drittanbieters zuzuweisen, anstatt diese Richtlinien lokal von jedem Server zu lesen (ja, standardmäßig funktioniert Openstack so!).

Eine solch große Änderung erfordert große, komplexe und vor allem synchrone Änderungen in mehreren Systemen, die von verschiedenen Entwicklungsteams geschrieben wurden. Nach der Montage sollte das gesamte System funktionieren.

Wie kann man solche Änderungen einführen und nicht vermasseln? Zuerst haben wir uns entschlossen, ein wenig in die Zukunft zu schauen.

Rollout-Strategie


  • Die Einführung wäre in mehreren Schritten möglich, dies würde jedoch die Entwicklungszeit um das Dreifache verlängern. Außerdem hätten wir für einige Zeit eine vollständige Desynchronisation der Daten in den Datenbanken. Ich müsste meine eigenen Synchronisationstools schreiben und lange mit mehreren Data Warehouses leben. Und das birgt eine Vielzahl von Risiken.
  • Alles, was sie transparent für den Benutzer vorbereiten konnten, wurde im Voraus erledigt. Es hat 2 Monate gedauert.
  • Wir haben uns mehrere Stunden Ausfallzeit gegönnt - nur für Benutzeroperationen, um Ressourcen zu erstellen und zu ändern.
  • Für die Arbeit aller bereits erstellten Ressourcen waren Ausfallzeiten nicht akzeptabel. Wir haben geplant, dass die Ressourcen bei der Einführung ohne Ausfallzeiten funktionieren und sich auf die Kunden auswirken.
  • Um die Auswirkungen auf unsere Kunden zu verringern, haben wir uns entschlossen, am Sonntagabend den Rollout durchzuführen, falls etwas schief geht. Nachts verwalten weniger Kunden virtuelle Maschinen.
  • Wir haben alle unsere Kunden gewarnt, dass während des für die Einführung ausgewählten Zeitraums kein Servicemanagement verfügbar sein wird.

Exkurs: Was ist Roll-out?


<Vorsicht Philosophie>

Jeder IT-Spezialist kann leicht beantworten, was Rollout ist. Sie legen CI / CD ein und automatisch wird alles an das Produkt geliefert. :) :)

Das ist natürlich wahr. Die Schwierigkeit besteht jedoch darin, dass mit modernen Tools zur Automatisierung der Codebereitstellung das Verständnis des Rollens selbst verloren geht. Wie vergisst man die epische Erfindung des Rades bei modernen Fahrzeugen? Alles ist so automatisiert, dass die Einführung oft ohne Realisierung des gesamten Bildes erfolgt.

Und das ganze Bild ist wie folgt. Der Rollout besteht aus vier großen Aspekten:

  1. Codezustellung, einschließlich Datenänderung. Zum Beispiel ihre Migration.
  2. Code-Rollback - die Möglichkeit, zurückzukehren, wenn etwas schief geht. Zum Beispiel durch die Erstellung von Backups.
  3. Die Zeit jedes Rollout- / Rollback-Vorgangs. Man muss 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 eine erfolgreiche Einführung berücksichtigt werden. Normalerweise bewerten sie nur den ersten, bestenfalls den zweiten Punkt, und dann wird der Rollout als erfolgreich angesehen. Aber der dritte und vierte sind noch wichtiger. Welchem ​​Benutzer wird es gefallen, wenn der Rollout 3 Stunden statt einer Minute dauert? Oder wenn etwas Überflüssiges den Rollout beeinflusst? Oder führt eine Ausfallzeit eines Dienstes zu unvorhersehbaren Konsequenzen?

Akt 1..n, Vorbereitung auf die Freilassung


Zuerst dachte ich daran, unsere Meetings kurz zu beschreiben: das gesamte Team, seine Teile, jede Menge Diskussionen über Kaffeepunkte, Streitigkeiten, Tests, Brainstorms. Dann dachte ich, dass es überflüssig wäre. Daraus bestehen immer vier Monate Entwicklungszeit, insbesondere wenn Sie nicht etwas schreiben, das ständig geliefert werden kann, sondern ein großes Merkmal eines lebenden Systems. Dies betrifft alle Dienste, aber Benutzer sollten nichts außer der "einen Schaltfläche in der Weboberfläche" ändern.

Unser Verständnis für die Einführung hat sich von jedem neuen Meeting an erheblich geändert. Zum Beispiel wollten wir unsere gesamte Abrechnungsbasis aktualisieren. Sie berechneten jedoch die Zeit und stellten fest, dass dies in einer angemessenen Roll-out-Zeit nicht möglich war. Wir haben fast eine zusätzliche Woche gebraucht, um die Abrechnungsdatenbank zu speichern und zu archivieren. Und als die erwartete Rollout-Geschwindigkeit danach nicht funktionierte, bestellten sie ein zusätzliches, stärkeres Eisen, bei dem sie die gesamte Basis schleppten. Nicht, dass wir dies nicht früher tun wollten, aber die derzeitige Notwendigkeit der Einführung ließ uns keine Optionen.

Wenn einer von uns Zweifel hatte, dass die Einführung die Verfügbarkeit unserer virtuellen Maschinen beeinträchtigen könnte, verbrachten wir eine Woche damit, Tests und Experimente durchzuführen, den Code zu analysieren und ein klares Verständnis dafür zu erlangen, dass dies in unserer Produktion nicht passieren würde, und selbst die zweifelhaftesten Leute stimmten dem zu.

In der Zwischenzeit führten die Techniker ihre unabhängigen Experimente durch, um den Kunden Anweisungen zum Verbinden zu schreiben, die sich nach der Einführung ändern sollten. Sie arbeiteten an einer benutzerfreundlichen UX, bereiteten Anweisungen vor und gaben persönliche Ratschläge.

Wir haben alle möglichen Roll-out-Vorgänge automatisiert. Jede Operation wurde per Skript ausgeführt, selbst die einfachste, führte ständig Tests durch. Sie diskutierten darüber, wie der Dienst am besten deaktiviert werden kann - senken Sie den Dämon oder blockieren Sie den Zugriff auf den Dienst mit einer Firewall. Für jede Phase der Einführung wurde eine Checkliste mit Teams erstellt, die ständig aktualisiert wurde. Wir haben das Gantt-Diagramm für alle Rollout-Arbeiten mit Zeitangaben erstellt und ständig aktualisiert.

Und so ...

Letzter Akt vor dem Rollout


... es ist Zeit auszurollen.

Wie das Sprichwort sagt, kann ein Kunstwerk nicht fertiggestellt werden, nur um die Arbeit daran zu beenden. Es ist notwendig, eine willensstarke Anstrengung zu unternehmen, um zu verstehen, dass Sie nicht alles finden, aber zu glauben, dass Sie alle vernünftigen Annahmen getroffen, alle möglichen Fälle berücksichtigt, alle kritischen Fehler geschlossen und alle Teilnehmer alles getan haben, was sie konnten. Je mehr Code Sie einführen, desto schwieriger ist es, sich davon zu überzeugen (außerdem versteht jeder, dass es unmöglich ist, alles vorherzusehen).

Wir haben uns für die Einführung entschieden, als wir davon überzeugt waren, dass wir alles getan haben, um alle Risiken für unsere Benutzer zu schließen, die mit unerwarteten Auswirkungen und Ausfallzeiten verbunden sind. Das heißt - alles kann schief gehen, außer:

  1. Der Einfluss (der uns heilig ist, der wertvollste) auf die Benutzerinfrastruktur,
  2. Funktionalität: Die Nutzung unseres Dienstes nach der Einführung sollte dieselbe sein wie zuvor.

Ausrollen



Zwei rollen, 8 stören nicht

Wir nehmen uns Ausfallzeiten für alle Anfragen von Benutzern innerhalb von 7 Stunden. 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 - eine Reserve für einen möglichen Rollback von Änderungen.

Für jede Aktion wurde ein Gantt-Diagramm erstellt, wie viel Zeit es dauert, was nacheinander abläuft, was parallel ausgeführt wird.


Ein Ausschnitt aus dem Gantt-Rollout-Diagramm, einer der früheren Versionen (ohne parallele Ausführung). Das wertvollste Synchronisationswerkzeug

Alle Teilnehmer haben ihre Rolle bei der Einführung, welche Aufgaben sie erledigen und für welche sie verantwortlich sind. Wir versuchen, jede Stufe automatisch zu machen, zurückzusetzen, Feedback zu sammeln und erneut zu rollen.

Chronik der Ereignisse


Also kamen am Sonntag, den 28. April, um 22 Uhr 15 Leute zur Arbeit. Neben den wichtigsten Teilnehmern kamen einige nur, um das Team zu unterstützen, wofür sie sich besonders bedanken.

Unabhängig davon ist es erwähnenswert, dass unser Schlüsseltester im Urlaub ist. Es ist unmöglich, ohne Tests auszurollen, wir arbeiten an Optionen. Eine Kollegin erklärt sich bereit, uns außerhalb des Urlaubs zu testen, wofür sie vom gesamten Team unermesslich dankbar ist.

00:00. Hör auf
Wir stoppen Benutzeranfragen, hängen das Typenschild auf, sagen sie, technische Arbeit. Überwachung schreit, aber alles ist normal. Wir überprüfen, dass nichts gefallen ist, außer dass es fallen sollte. Und wir beginnen mit der Arbeit an der Migration.

Jeder hat einen gedruckten Rollout-Plan für die Punkte, jeder weiß, wer was zu welchem ​​Zeitpunkt tut. Nach jeder Aktion überprüfen wir die Zeiten, die sie nicht überschreiten, und alles läuft nach Plan. Diejenigen, die derzeit nicht direkt am Rollout beteiligt sind, bereiten sich darauf vor, indem sie ein Online-Spielzeug (Xonotic, Typ 3 Kwaki) starten, um die Kollegen nicht zu stören. :) :)

02:00 Uhr Ausgerollt
Eine angenehme Überraschung: Wir haben die Einführung eine Stunde früher abgeschlossen, da unsere Datenbanken und Migrationsskripte optimiert wurden. Der universelle Schrei "ausgerollt!" Alle neuen Funktionen im Produkt, aber bisher können nur wir die Schnittstelle sehen. Jeder geht in den Testmodus, sortiert in Haufen und beginnt zu schauen, was am Ende passiert ist.

Es hat nicht sehr gut geklappt, wir verstehen dies nach 10 Minuten, wenn nichts verbunden ist und in den Projekten der Teammitglieder nicht funktioniert. Schnelle Synchronisierung, Äußerung unserer Probleme, Priorisierung, Aufteilung in Teams und Debuggen.

2:30 Uhr morgens Zwei große Probleme gegen vier Augen
Wir finden zwei große Probleme. Wir haben festgestellt, dass Kunden einige verbundene Dienste nicht sehen und es Probleme mit Partnerkonten geben wird. Beide sind für einige Randfälle mit unvollständigen Migrationsskripten verknüpft. Wir müssen es jetzt reparieren.

Wir schreiben Abfragen, die dies beheben, mindestens 4 Augen. Wir rollen auf das Pre-Gate, um sicherzustellen, dass sie funktionieren und nichts kaputt machen. Sie können weiter rollen. Parallel dazu beginnen unsere üblichen Integrationstests, bei denen einige weitere Probleme festgestellt werden. Alle von ihnen sind klein, müssen aber auch repariert werden.

03:00 Uhr -2 Probleme +2 Probleme
Die beiden vorherigen großen Probleme sind behoben, fast alle kleineren auch. Alle, die nicht mit Korrekturen beschäftigt sind, arbeiten aktiv in ihren Konten und berichten, was sie finden. Wir priorisieren, verteilen nach Befehlen und lassen am Morgen unkritisch.

Wenn Sie die Tests erneut ausführen, werden zwei neue große Probleme festgestellt. Nicht alle Servicerichtlinien sind korrekt angekommen, daher werden einige Benutzeranforderungen nicht authentifiziert. Plus ein neues Problem mit Partnerkonten. Wir beeilen uns zu sehen.

03:20. Notsynchronisation
Ein neues Problem wurde behoben. Zum zweiten arrangieren wir eine Notsynchronisation. Wir verstehen, was passiert: Das vorherige Update hat ein Problem behoben, aber ein anderes erstellt. Wir machen eine Pause, um herauszufinden, wie man es richtig und ohne Konsequenzen macht.

03:30 Uhr Sechs Augen
Wir sind uns bewusst, wie der Endzustand der Basis aussehen sollte, damit alles für alle Partner gut ist. Wir schreiben eine Anfrage in 6 Augen, rollen auf der Vorstange, testen, rollen auf dem Stoß.

04:00. Alles arbeitet
Alle Tests bestanden, keine kritischen Probleme sind sichtbar. Von Zeit zu Zeit funktioniert etwas in einem Team nicht, wir reagieren schnell. Meistens ist der Alarm falsch. Aber manchmal hat etwas nicht erreicht, irgendwo funktioniert eine separate Seite nicht. Wir sitzen, reparieren, reparieren, reparieren. Ein separates Team startet das letzte große Feature - die Abrechnung.

04:30. Punkt ohne Rückkehr
Der Punkt ohne Wiederkehr nähert sich, dh der Zeitpunkt, zu dem wir, wenn wir mit dem Zurückrollen beginnen, die uns gegebenen Ausfallzeiten nicht einhalten werden. Es gibt Probleme mit der Abrechnung, die alles weiß und aufschreibt, aber hartnäckig kein Geld von Kunden abschreiben will. Es gibt mehrere Fehler auf einzelnen Seiten, Aktionen und Status. Die Hauptfunktionalität funktioniert, alle Tests bestehen erfolgreich. Wir entscheiden, dass der Rollout stattgefunden hat, wir werden nicht zurückrollen.

06:00 Uhr Wir öffnen überhaupt in der Benutzeroberfläche
Fehler sind behoben. Einige nicht betroffene Benutzer bleiben für später übrig. Wir öffnen die Schnittstelle für alle. Wir beschwören weiterhin die Abrechnung, warten auf das Feedback der Benutzer und überwachen die Ergebnisse.

07:00 Uhr Probleme beim Laden der API
Es wird deutlich, dass wir eine etwas falsch geplante Auslastung unserer API haben und diese Auslastung testen, wodurch das Problem nicht identifiziert werden konnte. Infolgedessen schlagen 5% der Anforderungen fehl. Wir mobilisieren und suchen nach einem Grund.

Abrechnung ist hartnäckig, will auch nicht arbeiten. Wir beschließen, es auf später zu verschieben, um Änderungen in einem ruhigen Modus vorzunehmen. Das heißt, alle darin enthaltenen Ressourcen werden akkumuliert, aber Abschreibungen von Kunden werden nicht bestanden. Dies ist natürlich ein Problem, aber im Vergleich zur allgemeinen Einführung scheint es nicht grundlegend zu sein.

08:00. API korrigieren
Wir haben einen Fix für die Ladung herausgebracht, der ausfällt. Wir fangen an nach Hause zu gehen.

10 Uhr morgens Alle
Alles ist fest. Bei der Überwachung und wenn die Kunden ruhig sind, geht das Team nach und nach ins Bett. Die Abrechnung bleibt bestehen, wir werden sie morgen wiederherstellen.

Tagsüber gab es dann Rollouts, in denen die Protokolle, Benachrichtigungen, Rückkehrcodes und benutzerdefinierten Codes einiger unserer Kunden korrigiert wurden.

Der Rollout war also erfolgreich! Es könnte natürlich besser sein, aber wir haben Schlussfolgerungen darüber gezogen, was wir nicht genug hatten, um Perfektion zu erreichen.

Insgesamt


Innerhalb von zwei Monaten nach der aktiven Vorbereitung auf die Einführung wurden 43 Aufgaben erledigt, die einige Stunden bis zu mehreren Tagen dauerten.

Während des Rollouts:

  • neue und veränderte Dämonen - 5 Teile, die 2 Monolithen ersetzen;
  • Änderungen innerhalb der Datenbanken - Alle 6 unserer Datenbanken mit Benutzerdaten sind betroffen. Das Entladen von drei alten auf eine neue Datenbank ist abgeschlossen.
  • Frontend komplett überarbeitet;
  • die Anzahl der abgepumpten Codes - 33.000 Zeilen neuen Codes, ≈ 3.000 Zeilen Code in den Tests, ≈ 5.000 Zeilen Migrationscode;
  • Alle Daten sind intakt, keine einzige virtuelle Maschine des Kunden hat darunter gelitten. :) :)

Gute Praktiken für eine gute Einführung


Wir wurden in dieser schwierigen Situation von ihnen geführt. Im Allgemeinen ist es jedoch nützlich, sie bei jeder Einführung zu beobachten. Aber je schwieriger der Rollout, desto größer die Rolle, die sie spielen.

  1. Das erste, was Sie tun müssen, ist zu verstehen, wie sich Rollout auf Benutzer auswirken oder auswirken kann. Wird es Ausfallzeiten geben? Wenn ja, was ist dann Ausfallzeit? Wie wirkt sich das auf die Benutzer aus? Was sind die besten und schlechtesten Szenarien? Und schließen Sie die Risiken.
  2. Planen Sie alles. In jeder Phase müssen Sie alle Aspekte der Einführung verstehen:
    • Code-Lieferung;
    • Code-Rollback;
    • Zeit jeder Operation;
    • betroffene Funktionalität.
  3. Spielen Sie Szenarien, bis alle Roll-out-Phasen sowie die Risiken für jede Phase klar sind. Im Zweifelsfall können Sie eine Pause einlegen und die zweifelhafte Phase separat erkunden.
  4. Jede Phase kann und sollte verbessert werden, wenn dies unseren Benutzern hilft. Dies reduziert beispielsweise Ausfallzeiten oder beseitigt einige Risiken.
  5. Das Testen des Rollbacks ist viel wichtiger als das Testen der Codebereitstellung. Es muss überprüft werden, ob das System infolge des Rollbacks in seinen ursprünglichen Zustand zurückkehrt. Bestätigen Sie dies mit Tests.
  6. Alles, was automatisiert werden kann, muss automatisiert werden. Alles, was nicht automatisiert werden kann, muss auf dem Spickzettel vorab geschrieben werden.
  7. Erfolgskriterien aufzeichnen. Welche Funktionen sollten zu welchem ​​Zeitpunkt verfügbar sein? Wenn dies nicht der Fall ist, starten Sie einen Rollback-Plan.
  8. Und vor allem Menschen. Jeder sollte wissen, was er tut, wofür und was von seinen Aktionen bei der Einführung abhängt.

Und wenn in einem Satz, dann können Sie mit guter Planung und Ausarbeitung alles ausrollen, was Sie wollen, ohne Konsequenzen für den Verkauf. Auch das betrifft alle Ihre Dienstleistungen in prod.

Source: https://habr.com/ru/post/de453364/


All Articles