GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux-Fehlerbehebung:Navigieren in einem perfekten Sturm

Eines der schwierigsten Probleme bei DevOps sind diejenigen, die ihre eigene Untersuchung aktiv blockieren. Im Kampf um den Meistertitel sind die Probleme, die sporadisch auftreten, am zweithäufigsten. Dieser Artikel ist eine Abenteuergeschichte aus einer Zeit, als das Upstream-System Continuous Integration/Continuous Deployment (CI/CD) von Podman beides gleichzeitig erlebte.

Ein perfekter Sturm

Es war einmal, dass die Podman-Testautomatisierung aus ihrer „Big-Boy“-Hose herauswuchs. Dies geschah vor Jahren, als praktisch alle CI/CD-Systeme containerbasiert waren. Podman ist ein Verwaltungs- (und Debugging-) Tool für Container (und Pods), das innerhalb eines Containers nicht vollständig ausgeführt werden kann. Vielleicht noch schlimmer, die Mehrheit der Commodity-Automatisierungsdienste unterstützte nur Ubuntu. Dies wurde schnell zu einem absoluten Nichtstarter, da Podman auf virtuellen Maschinen (VMs) ausgeführt werden musste. Es musste auch mit mehreren Distributionen laufen, einschließlich der Upstream-Distribution von Red Hat, Fedora.

Nach Erfahrung mit CI/CD-Workflows, die unter ein Cloud-sdk + SSH (und/oder Ansible)-Setup für den Cloud-Zugriff gepfropft wurden, scheint die erhöhte Komplexität immer Probleme zu verursachen. Dann stolperte ich eines Tages über Cirrus-CI. Cirrus-CI ist ein Git-zentriertes Automatisierungstool, das Container und VMs mit einer Vielzahl von Cloud-Anbietern orchestrieren kann. Dadurch konnte das Podman-Team den Cloud-Service unabhängig von seiner Orchestrierung bezahlen und verwalten. Wir konnten die volle Kontrolle über die VMs und Protokolldaten behalten, wobei Cirrus-CI nur die Orchestrierung verwaltete.

Der gesamte Arbeitsablauf sieht ungefähr so ​​aus:

  1. Ein Entwickler reicht vorgeschlagene Codeänderungen stromaufwärts in das Git-Repository von Podman ein.
  2. Cirrus-CI bemerkt, liest eine Konfigurationsdatei und startet dann die erforderlichen VMs in unserer Cloud.
  3. Native Cloud-Metadatendienste verwalten die Skriptausführung und melden sich bei Cirrus-CI zurück.
  4. Cirrus-CI fährt die VMs herunter und gibt dem Entwickler Pass/Fail-Feedback.
  5. Änderungen werden vorgenommen und der Zyklus wiederholt sich, bis der Code akzeptiert wird.

Seit Jahren funktioniert dieser Workflow nahezu fehlerfrei, wobei sich die meisten Probleme auf Tests und Skripte konzentrierten – Fehler, die das Podman-Team problemlos handhabt. Selten führen Probleme innerhalb von Cirrus-CI, dem Internet und/oder unserem Cloud-Anbieter dazu, dass VMs verwaisen (nicht entfernt werden können). Ansonsten war das Support-Personal von Cirrus Labs fantastisch, sehr zugänglich, mit erstklassiger Reaktionsfähigkeit und Verantwortlichkeit.

Dann, eines Tages im Oktober 2020, nachdem eine Reihe frisch aktualisierter VM-Images (d. h. das Festplatten-Image, das für jede neue VM-Instanz kopiert wurde) rotiert wurden, begannen scheinbar zufällige Jobs fehlzuschlagen. Eine erste Untersuchung der Skriptausgabe ergab keine Informationen. Buchstäblich würde die gesamte Ausgabe plötzlich aufhören, ohne erkennbares Muster in Bezug auf andere Fehler. Wie erwartet würde Cirrus-CI die VM sorgfältig bereinigen und den daraus resultierenden Fehler dem Entwickler zur Klärung vorlegen. Oft war die erneute Ausführung des fehlgeschlagenen Jobs ohne Zwischenfälle erfolgreich.

Diese Situation dauerte mehrere Wochen ohne Probleme – entsprechend den Infrastrukturausfällen in unserer Cloud, GitHub oder Cirrus. Das Problem trat eher selten auf, vielleicht eine Handvoll Fehlschläge pro Tag bei Hunderten von erfolgreichen Jobs. Die Fehlersuche war schwierig, und das ständige erneute Ausführen von Jobs konnte keine langfristige Problemumgehung sein. Abgesehen von regelmäßigen Vorfallberichten von meinem Team konnte ich kein allgemeines Muster der Ausfälle erkennen. Da die neuen VM-Images erhebliche Vorteile boten, wären auch die Kosten für ein Rollback hoch gewesen.

Bei fast jedem systemischen Problem wie diesem ist das Auffinden von Verhaltensmustern ein Schlüsselelement für eine erfolgreiche Fehlerbehebung. Da zuverlässiger beruflicher Erfolg der erwünschte Zustand ist, war es eine zwingende Voraussetzung, zumindest eine Ahnung oder einen Hinweis zu haben. Leider war unsere Fähigkeit, Muster zu beobachten, in diesem Fall durch die zufälligen Fehler und die äußerst wünschenswerte Funktion extrem eingeschränkt:Bereinigen ausgedienter Cloud-VMs, die echtes Geld verschwenden.

Eine einfache, wiederholte, manuelle Testausführung reproduzierte das Problem überhaupt nicht. Das Werfen von mehr CPU- und Speicherressourcen hat sich auch nicht auf das Verhalten ausgewirkt. Ich habe Tage damit verbracht, über Optionen nachzudenken und Brainstorming durchzuführen, um zusätzliche Daten zu den Fehlern zu sammeln. Schließlich fiel mir auf, dass ich eine Möglichkeit brauchte, die VM-Bereinigung selektiv zu unterbrechen, aber nur in Fällen, in denen die Tests nicht abgeschlossen werden konnten.

[ Das könnte Ihnen auch gefallen: Vom Systemadministrator zu DevOps ]

Mit anderen Worten, ich musste den erfolgreichen Testabschluss (nicht nur Bestanden/Nicht bestanden) irgendwie mit dem Zulassen der Bereinigung in Verbindung bringen. Da erinnerte ich mich an ein kleines Kontrollkästchen, das ich einmal gesehen hatte, als ich in der WebUI unserer Cloud herumstöberte:Löschschutz . Wenn dieses Flag gesetzt ist, beschwert sich Cirrus-CI lautstark, weil es daran gehindert wird, eine VM zu entfernen, aber ansonsten lässt es die Dinge ungestört.

Ich musste unseren Workflow so instrumentieren, dass die VMs selbst ihr eigenes Löschschutz-Flag setzen und zurücksetzen konnten. Etwa so:

  1. VM aktiviert den Löschschutz auf sich selbst.
  2. Tests durchführen.
  3. VM deaktiviert ihren eigenen Löschschutz.
  4. Cirrus-CI bereinigt die VM oder bereinigt sie nicht und macht einen Gestank darüber.

Auf diese Weise würde Cirrus-CI nach Abschluss der Tests die VM wie gewohnt problemlos entfernen. Wenn das Problem jedoch auftrat, wurden die Tests nicht abgeschlossen und Cirrus-CI lief in den (noch) aktivierten Löschschutz. Glücklicherweise war dieser Workflow durchaus über einfache Befehlszeilenoptionen für das Cloud-Management-Dienstprogramm zu realisieren, das ich auf den VMs installieren konnte.

Mit dieser Workflow-Instrumentierung war alles, was ich tun musste, die Testmatrix wiederholt auszulösen und darauf zu warten, dass verwaiste VMs auftauchten. Das Schicksal lächelte mich an diesem Tag an, weil sich das Problem fast augenblicklich reproduzierte. Ich habe es jedoch noch ein paar Mal ausgeführt, sodass ich mehr als ein paar verwaiste VMs untersuchen musste.

Unerwarteterweise wurde die Situation zu diesem Zeitpunkt noch interessanter:Ich konnte keine SSH-Verbindung zu den verwaisten VMs herstellen. Tatsächlich würden sie nicht einmal auf Pings von innerhalb oder außerhalb unserer Cloud reagieren. Ich habe auf einer VM einen Hard-Reset durchgeführt und die Systemprotokolle nach dem Hochfahren überprüft. Da war nichts. Reißverschluss. Nada. Nicht ein einziges Jota eines anderen Hinweises als das, was wir bereits wussten:Die Tests wurden einfach nicht mehr ausgeführt, tot, zusammen mit dem Rest des Systems.

Da es bereits mein Glückstag war, beschloss ich, es zu pushen, und stöberte erneut in der WebUI meiner Cloud herum. Schließlich fand ich eine weitere unglaublich praktische kleine Einstellung:Serial-console output log . Dies war im Grunde eine direkte Low-Level-Kommunikationsleitung direkt in den Kernel. Wenn etwas Schreckliches passieren würde, das für einen vollständigen Systemabsturz sorgen würde, würde der Kernel sicherlich aus seiner virtuellen seriellen Schnittstelle schreien. Bingo, Yahtzee und Huzzah!

[ 1203.905090] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 1203.912275] #PF: supervisor read access in kernel mode
[ 1203.917588] #PF: error_code(0x0000) - not-present page
[ 1203.922881] PGD 8000000124e2d067 P4D 8000000124e2d067 PUD 138d5e067 PMD 0
[ 1203.929939] Oops: 0000 [#1] SMP PTI
...blah...blah...blah
[ 1204.052766] Call Trace:
[ 1204.055440]  bfq_idle_extract+0x52/0xb0
[ 1204.059468]  bfq_put_idle_entity+0x12/0x60
[ 1204.063722]  bfq_bfqq_served+0xb0/0x190
[ 1204.067718]  bfq_dispatch_request+0x2c2/0x1070

Hallo, alter Freund! Es war in der Tat ein sehr glücklicher Tag!

Dies war eine Kernel-Panic, die ich ein Jahr zuvor gesehen hatte und an deren Behebung ich monatelang unermüdlich mit Upstream-Kernel-Engineering gearbeitet hatte. Es war ein Fehler im Speichersubsystem des Kernels, der dafür verantwortlich war, die Effizienz zu verbessern und sicherzustellen, dass wertvolle Nullen und Einsen auf die Festplatte geschrieben werden. In diesem Fall hat der Kernel, anstatt den Speicher zu beschädigen, eine White-Flag ausgeworfen und alles tot angehalten.

Nachdem ich fast genau dasselbe Problem schon einmal bearbeitet hatte, war mir die einzeilige Problemumgehung bereits bekannt. Es war nicht nötig, mein Team erneut durch monatelanges Debugging zu schleppen. Ich könnte die Wiederholung einfach melden und die Problemumgehung vertrauensvoll bereitstellen, da ich weiß, dass sie das Problem zu 100 % lösen würde:

echo mq-deadline > /sys/block/sda/queue/scheduler

Nun, ich empfehle nicht, diesen Befehl wohl oder übel auf jedem Linux-System auszuführen, das Sie besitzen. In diesem speziellen Fall wusste ich aus früherer Erfahrung, dass es absolut sicher war, den Pufferalgorithmus (auch als E/A-Aufzug bezeichnet) auszutauschen. Kein Podman-Entwickler würde die Änderung auch nur in den Testergebnissen bemerken.

[ Erste Schritte mit Containern? Schauen Sie sich diesen kostenlosen Kurs an. Containerisierte Anwendungen bereitstellen:Eine technische Übersicht. ]

Abschluss

Sollten Sie oder jemand, den Sie lieben, jemals selbst auf eine Kernel-Panic stoßen, empfehle ich Ihnen, sich diesen kürzlich erschienenen Artikel zu diesem Thema anzusehen. Ansonsten lautet die wichtigste Erkenntnis:Bei der blinden Fehlersuche ist die Lösung der Ursachen-Verschleierungs-Aspekte absolut entscheidend. Zweitens arbeitet man mit den Daten, um das Problem besser reproduzierbar zu machen. Sie werden es sehr schwierig haben, Letzteres ohne Hilfe von Ersterem zu tun.


Linux
  1. Fehlerbehebung bei langsamem WLAN unter Linux

  2. Fehlerbehebung bei Hardwareproblemen unter Linux

  3. Grundlagen des Linux-Systemadministrators:Fehlerbehebung bei Known_hosts-Fehlern

  4. 5 Linux-Befehle zur Fehlerbehebung im Netzwerk

  5. Fehlerbehebung und Debugging für Linux-Netzwerke?

Der perfekte Desktop - Linux Mint 17.1 (Rebecca)

Der perfekte Desktop - Linux Mint 16 (Petra)

Perfekter Fluxbox-Desktop auf Kali Linux

MEGA-Cloud-Speicher unter Linux installieren und verwenden

Ein Leitfaden für Anfänger zur Netzwerkfehlerbehebung unter Linux

Fehlerbehebung „Inakzeptables TLS-Zertifikat“-Fehler in Linux