Der Blog

Cheftests bei PagerDuty

von Ranjib Dey 14. November 2013 | 5 Minuten Lesezeit

Chef testing Bei PagerDuty wird unsere gesamte Computerinfrastruktur mithilfe von Chef automatisiert. Wir veröffentlichen sehr häufig Funktionen und Änderungen an unserer Chef-Codebasis – oft mehrmals am Tag – und daher ist es entscheidend, dass wir unseren Chef-Code testen, bevor wir ihn in unserer Produktionsumgebung bereitstellen. Wie wir gelernt haben, können Fehler durch nicht eingefrorene Abhängigkeiten, falsche Werte in der Konfigurationsdatei, Logikfehler, Bugs in zugrunde liegenden Bibliotheken usw. entstehen.

In diesem Beitrag gehen wir die fünf sequentiellen Testtools/-strategien durch, die wir zum Erstellen einer vorhersehbaren und stabilen Infrastruktur verwenden.

  1. Semantische Tests – In unserer Continuous Integration (CI)-Pipeline besteht der erste Schritt darin, ein Lint-Tool namens Foodcritic auszuführen, das unseren Chef-Code auf semantische Fehler prüft. Es ist schnell und ermöglicht eine einheitliche Qualitätskontrolle. Wir stoppen sofort, wenn es fehlschlägt. Derzeit führen wir Foodcritic nur für unsere Kochbücher aus (unser Berkshelf-Anbieterverzeichnis ist davon ausgeschlossen).
  2. Komponententests – Der zweite Schritt besteht darin, Unit-Tests über ChefSpec durchzuführen. Wir haben eine grundlegende Abdeckung (d. h. wir prüfen zumindest, ob der Knoten konvergiert) aller Rezepte und eine umfassende Abdeckung der PagerDuty-spezifischen Rezepte. Wir sind kürzlich zu ChefSpec 3 (Grüße an Seth Vargo für die Neufassung), das verkettbare Behauptungen, benutzerdefinierte Matcher und viele andere Verbesserungen bietet. Für einige der Kernkochbücher (z. B. iptables) haben wir benutzerdefinierte Matcher für die LWRPs desselben Kochbuchs. Im Allgemeinen halten wir unsere PagerDuty spezifischen Rezepte schlank, LWRPs schlank und eine Bibliothek, die den Großteil der Logik verkörpert. Bibliotheken werden mit rohem RSpec getestet. Im Allgemeinen behaupten wir angenommene Abhängigkeiten (d. h. die Spezifikation von pd-apache wird gegen „service['apache']“ behaupten) aus Community-Kochbüchern. Aufgrund der „ausgefeilten“ Angebote von Chef zur Attributpriorität kann es sehr schwierig sein, vorherzusagen, welches Attribut letztendlich verwendet wird, und ChefSpec bietet hierfür ein Sicherheitsnetz. Durch Unit-Tests können wir auch die Why-Run-Modi in unseren benutzerdefinierten LWRPs sicher implementieren. Dies war beim Refactoring kritischer Komponenten unglaublich hilfreich. Wir haben jetzt auch ein besseres Verständnis der Netzwerkabhängigkeiten, die wir mit einzelnen Suchaufrufen einführen.
  3. Funktionsprüfung – Wir verfügen über eine sehr kleine, aber noch nicht fertige Funktionstestsuite, die derzeit ca. 80 % unserer Infrastruktur abdeckt. Für jeden dieser Tests haben wir die Runlist-Elemente der obersten Ebene (d. h. Rollen, die direkt Knoten zugewiesen sind) auf einen Linux-Container der gleichen Plattform und Version (wir verwenden Ubuntu). Die Funktionstestsuite erstellt eine im Speicher Chef-Server (Grüße an John Keiser ), lädt alle Daten über unser Wiederherstellungsskript hoch , erzeugt den Container und führt dann einen messerbasierten Bootstrap unter Verwendung unserer Vorlage aus. Damit werden alle unsere Kochbücher, Rollen und Umgebungen ausgeführt. Wir verwenden einen benutzerdefinierten Handler, der die Ressourcennummern und andere Statistiken als Knotenattribute speichert. Wir rufen Chef zweimal auf und verwenden diese Metrikattribute, um zu prüfen, wie viele nicht-idempotente Ressourcen wir haben. Wir haben eine Handvoll nicht-idempotenter Ressourcen und unser Ziel ist es, diese auf Null zu bringen. Einige der Funktionstests umfassen auch die Wiederherstellung von Daten der Staging-Umgebung und die Konvergenz der Container dagegen. Dies hilft uns, eine echte Produktion oder eine Staging-ähnliche Konvergenz zu simulieren und uns gegen Konfigurationen zu behaupten, die umfangreiche Suchvorgänge beinhalten. Alle unsere Drittanbieterintegrationen (d. h. Datenhund Und Sumologisch ) werden als Teil dieses Schritts getestet. Dies gibt uns auch häufigeres Feedback zur Leistung externer APIs, da unsere Produktionsserver diese APIs ebenfalls nutzen. Nach den Behauptungen durchläuft der Container einen Tear-Down, bei dem wir alle unsere auf Knife basierenden externen Tear-Downs und auf Chef-Rezepten basierenden internen Tear-Down-Schritte testen können (z. B. Abmeldung externer Dienste oder DNS-Entfernung). Wir verwenden Vanilla rubin-lxc Bindungen zusammen mit RSpec, um das alles zu testen. Während die Funktionstests noch lokal ausgeführt werden, ist unser Endziel, dies in Jenkins zu integrieren.
  4. Integrationstests – Wir haben zwei Hauptumgebungen, in denen unser gesamter Chef-Code zusammen mit dem gesamten Anwendungscode getestet wird. Wir haben eine generische Staging-Umgebung, in der Funktionen bereitgestellt und ständig getestet werden. In der zweiten Umgebung werden diese Funktionen einem Belastungstest unterzogen. Beide Umgebungen sind logisch unabhängig, nutzen aber einige gemeinsame Dienste (z. B. AWS-Konto oder Chef-Server).
  5. Misserfolg am Freitag – Zusätzlich zu all diesen Softwaretests fügen wir an unseren Failure Fridays auch proaktiv Fehler in unseren Chef-Stack ein. In diesem Rahmen haben wir kürzlich Folgendes getestet: Timeouts des Chef-Servers, Verlust eines Chef-Servers und Wiederherstellung aus einem Backup und was mit Clients passiert, wenn der Chef-Server hohe Latenzen und Paketverluste aufweist (Spoiler-Alarm: alles wird langsamer). Weitere Informationen zu Failure Fridays finden Sie in Dougs Beitrag/Präsentation von den DevOpsDays London.

Wir haben einige wichtige Einzelheiten aus unseren Spezifikationen extrahiert und hier zur Verfügung gestellt:

spec code

Diese Lösungen basieren auf unseren aktuellen Einschränkungen durch verfügbare Tools und Technologien, die wir übernehmen und integrieren können. Viele dieser Tools sollten in ihre eigenen Codebasen integriert werden oder über eigene dedizierte Bibliotheken verfügen oder mit den entsprechenden Hauptalternativen zusammengeführt werden, sobald der zugrunde liegende Stack stabilisiert ist. Diese sollten jedoch einige konkrete Beispiele liefern, auf deren Grundlage wir diskutieren, Ideen entwickeln und Verbesserungen vornehmen können. Jedes Feedback dazu ist willkommen.

C hef war für unsere Computerinfrastruktur von entscheidender Bedeutung. Durch automatisierte Tests können wir kontinuierlich Code liefern. Durch die Verkürzung unserer Markteinführungszeit und die Verbesserung der Qualität unserer Releases können sich PagerDuty -Kunden auf unsere robuste, hochverfügbare Infrastruktur verlassen.