Am frühen Morgen des 19. Mai (EDT) stürzte quay.io ab. Die Katastrophe betraf sowohl die Verbraucher von quay.io als auch Open Source-Projekte, die quay.io als Plattform zum Erstellen und Verteilen von Software verwendeten. Red Hat schätzt das Vertrauen beider.
Das Team der SRE-Ingenieure sprang sofort ein und versuchte, den Quay-Service so schnell wie möglich zu stabilisieren. Währenddessen konnten Kunden jedoch keine neuen Bilder mehr und nur gelegentlich vorhandene Bilder abrufen. Aus einem unbekannten Grund wurde die Datenbank quay.io gesperrt, nachdem der Dienst auf die volle Kapazität skaliert wurde.
„ Was hat sich geändert? "- Dies ist die erste Frage, die normalerweise in solchen Fällen gestellt wird. Wir haben festgestellt, dass der OpenShift Dedicated-Cluster (auf dem quay.io ausgeführt wird) kurz vor dem Problem mit der Aktualisierung auf Version 4.3.19 begonnen hat. Da quay.io unter Red Hat OpenShift Dedicated (OSD) ausgeführt wird, waren regelmäßige Updates an der Tagesordnung und verursachten nie Probleme. Darüber hinaus haben wir in den letzten sechs Monaten Quay-Cluster mehrmals ohne Betriebsunterbrechung aktualisiert.
Während wir versuchten, den Dienst wiederherzustellen, begannen andere Ingenieure, einen neuen OSD-Cluster mit der vorherigen Version der Software vorzubereiten, um im Bedarfsfall alles darauf bereitzustellen.
Ursachenanalyse
Das Hauptsymptom des Absturzes war eine Lawine von Zehntausenden von Datenbankverbindungen, die die MySQL-Instanz effektiv unbrauchbar machten. Dies machte es schwierig, das Problem zu diagnostizieren. Wir haben die maximale Anzahl von Verbindungen von Kunden begrenzt, um das SRE-Team bei der Bewertung des Problems zu unterstützen. Wir haben keinen ungewöhnlichen Datenverkehr zur Datenbank festgestellt: Tatsächlich betrafen die meisten Anfragen Lesevorgänge und nur wenige Schreibvorgänge.
Wir haben auch versucht, ein Muster im Datenbankverkehr zu identifizieren, das diese Lawine verursachen könnte. Es war jedoch nicht möglich, Muster in den Protokollen zu finden. Während wir darauf warteten, dass der neue Cluster mit OSD 4.3.18 fertig ist, haben wir immer wieder versucht, die quay.io-Pods zu starten. Jedes Mal, wenn der Cluster voll ausgelastet war, fror die Datenbank ein. Dies bedeutete, dass die RDS-Instanz zusätzlich zu allen quay.io-Pods neu gestartet werden musste.
Am Abend haben wir den Dienst im schreibgeschützten Modus stabilisiert und das Maximum an nicht wesentlichen Funktionen (z. B. Speicherbereinigung im Namespace) deaktiviert, um die Belastung der Datenbank zu verringern. Die Hänge hörten auf, aber der Grund wurde nie gefunden . Der neue OSD-Cluster war bereit, und wir haben den Dienst migriert, den Datenverkehr verbunden und die Überwachung fortgesetzt.
Quay.io lief stabil auf dem neuen OSD-Cluster, daher gingen wir zurück zu den Datenbankprotokollen, konnten jedoch keine Korrelation finden, die die Sperren erklärt. OpenShift-Ingenieure haben mit uns zusammengearbeitet, um festzustellen, ob die Änderungen in Red Hat OpenShift 4.3.19 möglicherweise zu Quay-Problemen geführt haben. Es wurde jedoch nichts gefunden und das Problem konnte im Labor nicht reproduziert werden .
Zweiter Fehler
Am 28. Mai, kurz vor Mittag EDT, stürzte quay.io erneut mit demselben Symptom ab: Die Datenbank wurde blockiert. Wieder haben wir unsere ganze Kraft in die Untersuchung gesteckt. Zunächst musste der Dienst wiederhergestellt werden. Doch dieses Mal, RDS und ein Neustart quay.io Schoten nicht führen zu nichts Neustart wieder ein Lawine von Verbindungen fegte die Basis. Aber warum?
Quay ist in Python geschrieben und jeder Pod arbeitet als einzelner monolithischer Container. Viele parallele Tasks werden gleichzeitig in der Container-Laufzeit ausgeführt. Wir benutzen eine Bibliothek
geventuntergunicornWebanfragen zu verarbeiten. Wenn Quay eine Anfrage erhält (über unsere eigene API oder über die Docker-API), wird ihr ein Gevent-Worker zugewiesen. In der Regel muss dieser Mitarbeiter mit der Datenbank kommunizieren. Nach dem ersten Fehler stellten wir fest, dass Gevent-Mitarbeiter mit den Standardeinstellungen eine Verbindung zur Datenbank herstellten.
Angesichts der erheblichen Anzahl von Quay-Pods und Tausenden von eingehenden Anforderungen pro Sekunde könnte die große Anzahl von Datenbankverbindungen die MySQL-Instanz theoretisch überfordern. Dank der Überwachung war bekannt, dass Quay durchschnittlich 5.000 Anfragen pro Sekunde verarbeitet. Die Anzahl der Verbindungen zur Datenbank war ungefähr gleich. 5.000 Verbindungen mit einem Rand passen in die Funktionen unserer RDS-Instanz (was nicht über Zehntausende gesagt werden kann).Aus irgendeinem Grund gab es unerwartete Spitzen bei der Anzahl der Verbindungen , wir konnten jedoch keine Korrelation mit den eingehenden Anforderungen feststellen.
Dieses Mal waren wir entschlossen, die Ursache des Problems zu finden und zu beheben, nicht nur einen Neustart. An der Quay-Codebasis wurden Änderungen vorgenommen, um die Anzahl der Datenbankverbindungen für jeden Gevent- Worker zu begrenzen . Diese Nummer wurde zu einem Parameter in der Konfiguration: Es wurde möglich, sie "on the fly" zu ändern, ohne ein neues Container-Image zu erstellen. Um herauszufinden, wie viele Verbindungen tatsächlich verarbeitet werden müssen, haben wir mehrere Tests mit einer Staging-Umgebung durchgeführt, in der unterschiedliche Werte festgelegt wurden, um festzustellen, wie sich dies auf Lasttestszenarien auswirken würde. Infolgedessen stellte sich heraus, dassQuay wirft 502 Fehler aus, wenn die Anzahl der Verbindungen 10.000 überschreitet.
Wir haben diese neue Version sofort für die Produktion bereitgestellt und mit der Überwachung des Datenbankverbindungsplans begonnen. In der Vergangenheit wurde die Basis nach etwa 20 Minuten blockiert. Nach 30 störungsfreien Minuten hatten wir Hoffnung und eine Stunde später Zuversicht. Wir haben den Datenverkehr zum Post auf der Site wiederhergestellt und mit der Postmortem-Analyse begonnen.
Nachdem wir es geschafft hatten, das Problem zu umgehen, das zur Blockierung führte, konnten wir die wahren Ursachen nicht herausfinden . Es wurde bestätigt, dass es sich nicht um Änderungen in OpenShift 4.3.19 handelte, wie dies auch in Version 4.3.18 der Fall war, die zuvor problemlos mit Quay zusammenarbeitete.
Es lauerte eindeutig noch etwas im Cluster.
Ausführliche Studie
Quay.io verwendet seit sechs Jahren ohne Probleme die Standardeinstellungen für die Verbindung zur Datenbank. Was hat sich geändert? Es ist klar, dass der Verkehr zu quay.io die ganze Zeit über stetig gewachsen ist. In unserem Fall sah alles so aus, als ob ein bestimmter Schwellenwert erreicht wurde, der als Auslöser für eine Lawine von Verbindungen diente. Wir haben die Datenbankprotokolle nach dem zweiten Absturz weiter untersucht, aber keine Muster oder offensichtlichen Beziehungen gefunden.
In der Zwischenzeit hat das SRE-Team an Verbesserungen der Beobachtbarkeit von Abfragen und des allgemeinen Servicezustands von Quay gearbeitet. Es wurden neue Metriken und Dashboards bereitgestellt , die zeigen, welche Teile von Quay von Kunden am meisten nachgefragt werden.
Quay.io hat bis zum 9. Juni gut funktioniert. Am Morgen (über EDT) konnten wir erneut einen signifikanten Anstieg der Anzahl der Datenbankverbindungen feststellen. Diesmal gab es keine Ausfallzeiten , da die Anzahl der neuen Parameter begrenzt war und die MySQL-Bandbreite nicht überschritten werden konnte. Etwa eine halbe Stunde lang bemerkten viele Benutzer jedoch, dass quay.io langsam war. Mit den hinzugefügten Überwachungstools haben wir schnell alle möglichen Daten gesammelt. Plötzlich tauchte ein Muster auf.
Kurz vor dem Verbindungssprung wurde eine große Anzahl von Anforderungen an die App Registry API gesendet... App Registry ist eine wenig bekannte Funktion von quay.io. Sie können damit Dinge wie Helmdiagramme und Container speichern, die reich an Metadaten sind. Die meisten Benutzer von quay.io verwenden diese Funktion nicht, Red Hat OpenShift verwendet sie jedoch aktiv. OperatorHub in OpenShift speichert alle Operatoren in der App-Registrierung. Diese Carrier bilden die Grundlage für das OpenShift-Workload-Ökosystem und das partnerorientierte Betriebsmodell (unter Tag 2).
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 Popularität von OpenShift 4 hat auch die Anzahl der Cluster auf der ganzen Welt zugenommen. Jeder dieser Cluster lädt Operatorinhalte, um den integrierten OperatorHub unter Verwendung der App-Registrierung in quay.io als Backend auszuführen. Auf der Suche nach der Ursache des Problems haben wir die Tatsache übersehen, dass mit zunehmender Popularität von OpenShift auch die Belastung einer der selten verwendeten quay.io-Funktionen zunahm .
Wir haben den Anforderungsverkehr der App-Registrierung analysiert und den Registrierungscode untersucht. Sofort wurden Fehler aufgedeckt, aufgrund derer Abfragen an die Datenbank suboptimal gebildet wurden. Sie verursachten unter leichter Last keine Probleme, aber als sie zunahmen, wurden sie zu einer Quelle von Problemen. Es stellte sich heraus, dass die App-Registrierung zwei problematische Endpunkte hatte, die nicht gut auf eine Zunahme der Last reagierten: Der erste gab eine Liste aller Pakete im Repository an, der zweite gab alle Blobs für ein Paket zurück.
Beseitigung der Ursachen
In der nächsten Woche haben wir den Code der App-Registrierung selbst und ihrer Umgebung optimiert. Offensichtlich wurden ineffiziente SQL-Abfragen überarbeitet, unnötige Aufrufe des Befehls wurden eliminiert
tar(er wurde jedes Mal ausgeführt, wenn ein Blob abgerufen wurde) und das Caching wurde hinzugefügt, wo immer dies möglich war. Anschließend haben wir umfangreiche Leistungstests durchgeführt und die Leistung der App-Registrierung vor und nach den Änderungen verglichen.
API-Anforderungen, die früher bis zu einer halben Minute dauerten, wurden jetzt in Millisekunden abgeschlossen . Wir haben die Änderungen an der Produktion in der nächsten Woche eingeführt und quay.io ist seitdem stabil. Während dieser Zeit gab es am App Registry-Endpunkt mehrere Verkehrsspitzen, aber die vorgenommenen Verbesserungen haben Datenbankausfälle verhindert.
Was haben wir gelernt?
Es ist klar, dass jeder Dienst versucht, Ausfallzeiten zu vermeiden. In unserem Fall glauben wir, dass die jüngsten Abstürze dazu beigetragen haben, quay.io besser zu machen. Für uns selbst haben wir einige wichtige Lektionen herausgenommen, die wir teilen möchten:
- Daten darüber, wer Ihren Service nutzt und wie, sind nicht überflüssig . Da Quay „einfach funktioniert hat“, mussten wir nie Zeit damit verbringen, den Verkehr zu optimieren und die Last zu verwalten. All dies führte zu einem falschen Sicherheitsgefühl, das der Dienst unbegrenzt skalieren konnte.
- , — . Quay , . , — , .
- Bewerten Sie die Auswirkungen der einzelnen Servicefunktionen . Kunden haben die App-Registrierung selten verwendet, daher hatte dies für unser Team keine Priorität. Wenn einige Funktionen des Produkts kaum genutzt werden, "tauchen" ihre Fehler selten auf und Entwickler hören auf, den Code zu überwachen. Es ist leicht, der Täuschung zum Opfer zu fallen, dass dies so sein sollte - bis diese Funktion plötzlich im Zentrum eines massiven Vorfalls steht.
Was weiter?
Die Arbeit zur Gewährleistung der Stabilität des Dienstes hört nie auf und wir verbessern sie ständig. Das Verkehrsaufkommen auf quay.io wächst weiter und wir erkennen an, dass wir die Verantwortung haben, alles zu tun, um dem Vertrauen unserer Kunden gerecht zu werden. Daher arbeiten wir derzeit an folgenden Aufgaben:
- , RDS.
- RDS. . , ( ); .
- . , .
- firewall’ - (WAF), , quay.io.
- , Red Hat OpenShift App Registry (Operator Catalogs), , quay.io.
- Die Unterstützung der Artefaktspezifikationen der Open Container Initiative (OCI) könnte ein langfristiger Ersatz für die App-Registrierung sein. Es wird derzeit als native Quay-Funktionalität implementiert und steht den Benutzern zur Verfügung, wenn die Spezifikation selbst fertiggestellt ist.
All dies ist Teil der laufenden Investition von Red Hat in quay.io, während wir von einem kleinen Startup-ähnlichen Team zu einer ausgereiften Plattform wechseln, die von SRE angetrieben wird. Wir wissen, dass sich viele unserer Kunden bei ihrer täglichen Arbeit auf quay.io verlassen (einschließlich Red Hat!) Und versuchen, so offen wie möglich über die jüngsten Störungen und die laufenden Verbesserungsbemühungen zu sein.
PS vom Übersetzer
Lesen Sie auch in unserem Blog: