Post Mortem auf Quay.io Nichtverfügbarkeit

Notiz. übersetzen: Anfang August sprach Red Hat öffentlich über die Lösung von Barrierefreiheitsproblemen, auf die Benutzer seines Dienstes in den vergangenen Monaten gestoßen waren Quay.io (Es basiert auf einer Registrierung für Container-Images, die das Unternehmen zusammen mit dem Kauf von CoreOS erhalten hat.) Unabhängig von Ihrem Interesse an dieser Dienstleistung als solcher ist der Weg, den die SRE-Ingenieure des Unternehmens zur Diagnose und Beseitigung der Unfallursachen eingeschlagen haben, aufschlussreich.

Post Mortem auf Quay.io Nichtverfügbarkeit

Am frühen Morgen des 19. Mai (Eastern Daylight Time, EDT) stürzte der Dienst quay.io ab. Der Unfall betraf sowohl quay.io-Konsumenten als auch Open-Source-Projekte, die quay.io als Plattform zum Erstellen und Verteilen von Software nutzten. Red Hat schätzt das Vertrauen beider.

Ein Team von SRE-Ingenieuren schaltete sich sofort ein und versuchte, den Quay-Service so schnell wie möglich zu stabilisieren. Während sie dies taten, verloren die Kunden jedoch die Fähigkeit, neue Bilder zu übertragen, und konnten nur gelegentlich vorhandene Bilder abrufen. Aus einem unbekannten Grund wurde die quay.io-Datenbank blockiert, nachdem der Dienst auf volle Kapazität skaliert wurde.

«Was hat sich geändert?„ – das ist meist die erste Frage, die in solchen Fällen gestellt wird. Uns ist aufgefallen, dass kurz vor dem Problem mit der Aktualisierung des OpenShift Dedicated-Clusters (auf dem quay.io läuft) auf Version 4.3.19 begonnen wurde. Da quay.io auf Red Hat OpenShift Dedicated (OSD) läuft, waren regelmäßige Updates Routine und verursachten nie Probleme. Darüber hinaus haben wir in den letzten sechs Monaten die Quay-Cluster mehrmals ohne Betriebsunterbrechung aktualisiert.

Während wir versuchten, den Dienst wiederherzustellen, begannen andere Ingenieure mit der Vorbereitung eines neuen OSD-Clusters mit der vorherigen Version der Software, damit sie im Falle eines Vorfalls alles darauf bereitstellen konnten.

Ursachenanalyse

Das Hauptsymptom des Ausfalls war eine Lawine von Zehntausenden Datenbankverbindungen, die die MySQL-Instanz praktisch funktionsunfähig machte. Dies machte es schwierig, das Problem zu diagnostizieren. Wir haben die maximale Anzahl von Verbindungen von Kunden begrenzt, um dem SRE-Team bei der Bewertung des Problems zu helfen. Wir haben keinen ungewöhnlichen Datenverkehr zur Datenbank festgestellt: Tatsächlich wurden die meisten Anfragen gelesen und nur wenige geschrieben.

Wir haben auch versucht, ein Muster im Datenbankverkehr zu identifizieren, das diese Lawine verursachen könnte. Wir konnten jedoch keine Muster in den Protokollen finden. Während wir darauf warteten, dass der neue Cluster mit OSD 4.3.18 fertig war, versuchten wir weiterhin, quay.io-Pods zu starten. Jedes Mal, wenn der Cluster seine volle Kapazität erreichte, fror die Datenbank ein. Dies bedeutete, dass neben allen quay.io-Pods auch die RDS-Instanz neu gestartet werden musste.

Am Abend stabilisierten wir den Dienst im schreibgeschützten Modus und deaktivierten so viele nicht wesentliche Funktionen wie möglich (z. B. Namespace-Garbage Collection), um die Belastung der Datenbank zu verringern. Das Einfrieren hat aufgehört aber der Grund wurde nie gefunden. Der neue OSD-Cluster war fertig und wir haben den Dienst migriert, den Datenverkehr verbunden und die Überwachung fortgesetzt.

Quay.io funktionierte stabil auf dem neuen OSD-Cluster, daher gingen wir zurück zu den Datenbankprotokollen, konnten aber keinen Zusammenhang finden, der die Blockaden erklären würde. OpenShift-Ingenieure haben mit uns zusammengearbeitet, um herauszufinden, ob Änderungen in Red Hat OpenShift 4.3.19 Probleme mit Quay verursachen könnten. Es wurde jedoch nichts gefunden, und Unter Laborbedingungen konnte das Problem nicht reproduziert werden.

Zweiter Misserfolg

Am 28. Mai, kurz vor Mittag EDT, stürzte quay.io erneut mit dem gleichen Symptom ab: Die Datenbank war blockiert. Und wieder haben wir unsere ganze Kraft in die Ermittlungen gesteckt. Zunächst musste der Dienst wiederhergestellt werden. Jedoch Diesmal hat ein Neustart von RDS und ein Neustart der quay.io-Pods nichts bewirkt: Eine weitere Lawine von Verbindungen hat die Basis überschwemmt. Aber warum?

Quay ist in Python geschrieben und jeder Pod fungiert als einzelner monolithischer Container. Die Containerlaufzeit führt viele parallele Aufgaben gleichzeitig aus. Wir nutzen die Bibliothek gevent unter gunicorn um Webanfragen zu bearbeiten. Wenn eine Anfrage bei Quay eingeht (über unsere eigene API oder über die Docker-API), wird ihr ein Gevent-Worker zugewiesen. Normalerweise sollte dieser Mitarbeiter die Datenbank kontaktieren. Nach dem ersten Fehler stellten wir fest, dass Gevent-Mitarbeiter mit Standardeinstellungen eine Verbindung zur Datenbank herstellten.

Angesichts der beträchtlichen Anzahl von Quay-Pods und Tausenden eingehender Anfragen pro Sekunde könnte eine große Anzahl von Datenbankverbindungen theoretisch die MySQL-Instanz überfordern. Dank der Überwachung war bekannt, dass Quay durchschnittlich 5 Anfragen pro Sekunde verarbeitet. Die Anzahl der Verbindungen zur Datenbank war ungefähr gleich. 5 Verbindungen lagen durchaus im Rahmen der Möglichkeiten unserer RDS-Instanz (von Zehntausenden kann man das nicht sagen). Aus irgendeinem Grund kam es zu unerwarteten Spitzen bei der Anzahl der VerbindungenAllerdings konnten wir keinen Zusammenhang mit eingehenden Anfragen feststellen.

Diesmal waren wir entschlossen, die Ursache des Problems zu finden und zu beseitigen und uns nicht auf einen Neustart zu beschränken. Zur Quay-Codebasis были внесены изменения, лимитирующие число подключений к БД для каждого worker’а gevent. Diese Nummer wurde zu einem Parameter in der Konfiguration: Es wurde möglich, sie im laufenden Betrieb zu ändern, ohne ein neues Container-Image zu erstellen. Um herauszufinden, wie viele Verbindungen realistischerweise gehandhabt werden könnten, haben wir mehrere Tests in einer Staging-Umgebung durchgeführt und dabei unterschiedliche Werte festgelegt, um zu sehen, wie sich dies auf Lasttestszenarien auswirken würde. Als Ergebnis wurde festgestellt, dass Quay beginnt mit der Ausgabe von 502-Fehlern, wenn die Anzahl der Verbindungen 10 überschreitet.

Wir haben diese neue Version sofort in der Produktion bereitgestellt und mit der Überwachung des Datenbankverbindungsplans begonnen. Früher wurde die Basis nach etwa 20 Minuten gesperrt. Nach 30 störungsfreien Minuten hatten wir Hoffnung und eine Stunde später Zuversicht. Wir haben den Verkehr auf der Website wiederhergestellt und mit der Post-Mortem-Analyse begonnen.

Nachdem es gelungen ist, das zur Blockierung führende Problem zu umgehen, Wir haben die wahren Gründe nicht herausgefunden. Es wurde bestätigt, dass es nicht mit Änderungen in OpenShift 4.3.19 zusammenhängt, da das Gleiche auch bei Version 4.3.18 passierte, die zuvor problemlos mit Quay funktionierte.

Offensichtlich lauerte noch etwas anderes in der Gruppe.

Ausführliche Studie

Quay.io nutzte die Standardeinstellungen, um sechs Jahre lang problemlos eine Verbindung zur Datenbank herzustellen. Was hat sich geändert? Es ist klar, dass der Verkehr auf quay.io die ganze Zeit über stetig zugenommen hat. In unserem Fall sah es so aus, als sei ein Schwellenwert erreicht worden, der als Auslöser für eine Verbindungslawine diente. Wir haben die Datenbankprotokolle nach dem zweiten Fehler weiter untersucht, konnten jedoch keine Muster oder offensichtlichen Zusammenhänge feststellen.

In der Zwischenzeit hat das SRE-Team an Verbesserungen der Beobachtbarkeit von Anfragen und des allgemeinen Servicezustands von Quay gearbeitet. Neue Metriken und Dashboards wurden bereitgestellt, die zeigt, welche Teile des Kais von den Kunden am meisten nachgefragt werden.

Quay.io funktionierte bis zum 9. Juni einwandfrei. Heute Morgen (EDT) konnten wir erneut einen deutlichen Anstieg der Anzahl der Datenbankverbindungen feststellen. Diesmal gab es keine Ausfallzeiten, da der neue Parameter ihre Anzahl begrenzte und es ihnen nicht erlaubte, den MySQL-Durchsatz zu überschreiten. Allerdings bemerkten viele Benutzer etwa eine halbe Stunde lang eine langsame Leistung von quay.io. Mit den hinzugefügten Überwachungstools haben wir schnell alle möglichen Daten gesammelt. Plötzlich zeichnete sich ein Muster ab.

Kurz vor dem Anstieg der Verbindungen wurde eine große Anzahl von Anfragen an die App Registry API gestellt. App Registry ist eine wenig bekannte Funktion von quay.io. Es ermöglicht Ihnen, Dinge wie Helm-Diagramme und Container mit umfangreichen Metadaten zu speichern. Die meisten quay.io-Benutzer arbeiten nicht mit dieser Funktion, aber Red Hat OpenShift nutzt sie aktiv. OperatorHub speichert als Teil von OpenShift alle Operatoren in der App Registry. Diese Betreiber bilden die Grundlage für das OpenShift-Workload-Ökosystem und das partnerzentrierte Betriebsmodell (Tag-2-Betrieb).

Jeder OpenShift 4-Cluster verwendet Operatoren aus dem integrierten OperatorHub, um einen Katalog der für die Installation verfügbaren Operatoren zu veröffentlichen und Updates für die bereits installierten bereitzustellen. Mit der wachsenden Beliebtheit von OpenShift 4 ist auch die Anzahl der Cluster weltweit gestiegen. Jeder dieser Cluster lädt Betreiberinhalte herunter, um den integrierten OperatorHub auszuführen, wobei die App Registry in quay.io als Backend verwendet wird. Bei unserer Suche nach der Ursache des Problems haben wir übersehen, dass mit der zunehmenden Beliebtheit von OpenShift auch die Belastung einer der selten genutzten quay.io-Funktionen zunahm..

Wir haben den App Registry-Anfrageverkehr analysiert und einen Blick auf den Registrierungscode geworfen. Sofort wurden Mängel aufgedeckt, aufgrund derer Abfragen an die Datenbank nicht optimal gestaltet wurden. Bei geringer Belastung verursachten sie keine Probleme, bei zunehmender Belastung wurden sie jedoch zur Problemquelle. Es stellte sich heraus, dass App Registry zwei problematische Endpunkte hatte, die nicht gut auf steigende Last reagierten: Der erste lieferte eine Liste aller Pakete im Repository, der zweite gab alle Blobs für das Paket zurück.

Beseitigung von Ursachen

In der nächsten Woche haben wir damit verbracht, den Code der App Registry selbst und ihrer Umgebung zu optimieren. Offensichtlich ineffektive SQL-Abfragen wurden überarbeitet und unnötige Befehlsaufrufe eliminiert tar (es wurde jedes Mal ausgeführt, wenn Blobs abgerufen wurden), Caching wurde, wo immer möglich, hinzugefügt. Anschließend haben wir umfangreiche Leistungstests durchgeführt und die Geschwindigkeit der App Registry vor und nach den Änderungen verglichen.

API-Anfragen, die früher bis zu einer halben Minute dauerten, werden jetzt in Millisekunden erledigt. In der nächsten Woche haben wir die Änderungen in der Produktion implementiert und seitdem funktioniert quay.io stabil. Während dieser Zeit kam es zu mehreren starken Spitzen im Datenverkehr auf dem App Registry-Endpunkt, aber die vorgenommenen Verbesserungen verhinderten Datenbankausfälle.

Was haben wir gelernt?

Es ist klar, dass jeder Dienst versucht, Ausfallzeiten zu vermeiden. In unserem Fall glauben wir, dass die jüngsten Ausfälle dazu beigetragen haben, quay.io besser zu machen. Wir haben einige wichtige Lektionen gelernt, die wir gerne weitergeben möchten:

  1. Daten darüber, wer Ihren Service wie nutzt, sind nie überflüssig. Da Quay „einfach funktionierte“, mussten wir nie Zeit damit verbringen, den Datenverkehr zu optimieren und die Auslastung zu verwalten. All dies erzeugte das falsche Sicherheitsgefühl, dass der Dienst unbegrenzt skalierbar sei.
  2. Wenn der Dienst ausfällt, Es hat oberste Priorität, es wieder zum Laufen zu bringen.. Da Quay während des ersten Ausfalls weiterhin unter einer gesperrten Datenbank litt, hatten unsere Standardverfahren nicht die beabsichtigte Wirkung und wir konnten den Dienst damit nicht wiederherstellen. Dies führte dazu, dass Zeit in die Analyse und Sammlung von Daten investiert werden musste, in der Hoffnung, die Grundursache zu finden – anstatt alle Anstrengungen auf die Wiederherstellung der Funktionalität zu konzentrieren.
  3. Bewerten Sie die Auswirkungen jeder Servicefunktion. Kunden nutzten App Registry selten, daher hatte dies für unser Team keine Priorität. Wenn einige Produktfunktionen kaum genutzt werden, treten ihre Fehler selten auf und Entwickler überwachen den Code nicht mehr. Man verfällt leicht der falschen Vorstellung, dass es so sein sollte – bis sich diese Funktion plötzlich im Mittelpunkt eines schwerwiegenden Vorfalls befindet.

Was kommt als nächstes?

Die Arbeit zur Gewährleistung der Stabilität des Dienstes hört nie auf und wir verbessern ihn ständig. Da das Verkehrsaufkommen auf quay.io weiter wächst, sind wir uns bewusst, dass wir die Verantwortung haben, alles zu tun, um dem Vertrauen unserer Kunden gerecht zu werden. Daher arbeiten wir derzeit an folgenden Aufgaben:

  1. Stellen Sie schreibgeschützte Datenbankreplikate bereit, um den Dienst bei Problemen mit der primären RDS-Instanz bei der Bewältigung des entsprechenden Datenverkehrs zu unterstützen.
  2. Aktualisieren einer RDS-Instanz. Die aktuelle Version selbst ist nicht das Problem. Wir wollen vielmehr einfach die falsche Spur beseitigen (die wir während des Scheiterns verfolgt haben); Durch die Aktualisierung der Software entfällt ein weiterer Faktor bei künftigen Ausfällen.
  3. Zusätzliches Caching im gesamten Cluster. Wir suchen weiterhin nach Bereichen, in denen Caching die Belastung der Datenbank verringern kann.
  4. Hinzufügen einer Web Application Firewall (WAF), um zu sehen, wer eine Verbindung zu quay.io herstellt und warum.
  5. Ab der nächsten Version werden Red Hat OpenShift-Cluster App Registry zugunsten von Operator-Katalogen aufgeben, die auf Container-Images basieren, die auf quay.io verfügbar sind.
  6. Ein langfristiger Ersatz für App Registry könnte die Unterstützung der Artefaktspezifikationen der Open Container Initiative (OCI) sein. Es ist derzeit als native Quay-Funktionalität implementiert und wird den Benutzern zur Verfügung stehen, wenn die Spezifikation selbst fertiggestellt ist.

All dies ist Teil der fortlaufenden Investition von Red Hat in quay.io, während wir uns von einem kleinen Team im „Startup-Stil“ zu einer ausgereiften SRE-basierten Plattform entwickeln. Wir wissen, dass sich viele unserer Kunden bei ihrer täglichen Arbeit auf quay.io verlassen (einschließlich Red Hat!), und wir versuchen, über aktuelle Ausfälle und laufende Verbesserungsbemühungen so transparent wie möglich zu sein.

PS vom Übersetzer

Lesen Sie auch auf unserem Blog:

Source: habr.com

Kommentar hinzufügen