Open-Source Chaos-Engineering mit Litmus.

08.12.2021 Tom Trapp
Cloud DevOps chaos-engineering sre k8s devops framework handson

Fehler oder Ausfälle im produktiven System führen oft zu Stress, Ärger und Missgunst. Fehler oder Ausfälle bewusst herbeizuführen und die Systeme dadurch stabiler und weniger anfällig zu machen führt immer zu Erfolg, Freude, Ansehen und Verbesserung!

Rückblick

Bereits in einem früheren TechUp hat Raffi über unsere We Celebrate Failure Kultur berichtet. Grundsätzlich geht darum, eine aktive Fehlerkultur zu leben, an Fehlern zu wachsen und Schlüsse daraus zu ziehen.

Im Cloud Umfeld gibt es sogenannte Chaos Engineering Tools wie beispielsweise Gremlin oder Litmus. Wenn Sie mehr über die theoretischen Hintergründe oder über Gremlin an sich erfahren wollen lege ich Ihnen das TechUp Wie Sie eine 'We Celebrate Failure'-Kultur mit Chaos Engineering in ihr Daily Business einführen. sehr ans Herzen!

Mit Gremlin haben wir bereits einen closed-source, enterprise-facing Player im Chaos Engineering Teil der altbekannten CNCF Landscape kennengelernt. Heute wollen wir den Schritt in richtig Open Source Chaos Engineering wagen.

Litmus

Litmus ist ein open-source, CNCF Sandbox Chaos Engineering Projekt, welches direkt von der Cloud Native Computing Foundation (CNCF) entwickelt wird. Seit 2018 sorgen über 150 Contributors für regelmäßige Updates und Releases. Das Ziel, ein CNCF Incubating Project zu werden wird klar kommuniziert und verfolgt.

Litmus selbst startete als complete framwork for finding weaknesses in Kubernetes platforms and applications running on Kubernetes, betitelt sich nun aber mehr als Cloud Native Chaos Engineering platform. Nichtsdestotrotz kann Litmus nur in einem Kubernetes Cluster verwendet werden, es gibt aber Anbindungen für andere Resource wie AWS, GCP oder Azure.

Ihre aktuelle Mission lautet:

To help identify weaknesses & potential outages in cloud-native systems by inducing chaos tests in a controlled way.

Zu den bekannten Contributors gehören unter anderem ChaosNative, Intuit, Amazon, RedHat und Container Solutions.

Erst im August dieses Jahres wurde die berühmt-berüchtigte Version 2.0.0 veröffentlicht. Bei der Version 2 handelte es sich um einen Release mit sehr vielen, weitgehenden Feature-Erweiterungen. Grundlegend kann man sagen, dass bei Version 2 sehr viele enterprise-facing Funktionen dazu kamen. Hervorzugehen sind zwei grundsätzliche Neuerungen, neu gibt es ein GitOps Pattern mit einer Integration mit Argo Workflows und eine neue WebUi. So lässt sich nun das komplette Chaos via WebUi und nicht mehr nur via CLI steuern.

Litmus selbst setzt hier vollständig auf den Prinzipien des Cloud native Chaos Engineering chaosnative.com/ auf, welche beispielsweise folgende Eigenschaften beinhalten:

  • Open Source
  • Community Collaboration
  • Open API
  • GitOps
  • Open Observability

Bevor wir uns Hands-On an Litmus wagen, wollen wir die einzelnen Komponenten und Features kennenlernen.

Chaos Experiments

Einfach gesagt beinhaltet ein Chaos Experiment die Anweisungen für das eigentliche Chaos. Die Kubernetes Custom Resource definiert Parameter wie das Image, die nötigen Permissions usw.

Ein klassisches Beispiel hier wäre ein sogenanntes pod-delete Experiment, welches einen bestimmten Pod abschalten. So kann man beispielsweise die Ausfallsicherheit prüfen.

Aktuell gibt es über 50 Experiments in unterschiedlichen Gruppe wie generic, cordns, kube-aws, kafka, gcp und weitere.

In der Vergangenheit waren viele Experimente in Ansible geschrieben, diese wurden zum grössten Teil mit Version 2 auf Go Lang portiert. Dank einer SDK, welche aktuell für Go, Python und Ansible verfügbar ist lassen sich eigene Experiments schreiben.

Probes

Probes sind im Litmus Umfeld modulare Prüfungen, um den Zustand des Chaoses zu bewerten. Grundsätzlich können diese Checks für normale Health-Checks benutzt werden. Sie bestimmen, ob ein Experiment erfolgreich war oder ob es ungewollte Auswirkungen wie einen Ausfall einer Schnittstelle gab.

Aktuell gibt es vier unterschiedliche Arten von Probes:

  • httpProbe – Aufruf einer URL, prüfen des Ergebnisses (z.B. anhand des HttpStatusCodes)
  • cmdProbe – Ausführen eines Shell Commands, Exit Code wird beachtet
  • k8sProbe – Ausführen einer CRUD Operation gegen native oder custom Kubernetes Ressourcen
  • promProbe – Ausführen einer PromQL Query und Prometheus Metrics zu matchen

Selbstverständlich können verschiedene Probes kombiniert werden.

Hier ist zu beachten, dass man z. B. bei einer httpProbe den korrekten Endpunkt vom Kubernetes Service verwendet. Ist diese Probe falsch definiert, kann es schnell zu verfälschten Ergebnissen kommen.

Chaos Workflow

Ein Chaos Workflow ist ein Set an unterschiedlichen Chaos Operationen, welche gemeinsam ein Szenario im Kubernetes Cluster bilden. Diese Steps können entweder nacheinander oder parallel ausgeführt werden. Hinter all dem Steck ein Argo CD Workflow, welcher mehrere Experimente beinhaltet.

Grundlegend gibt es zwei Arten, normale Workflows, welche nur einmal laufen oder sogenannte CronWorkflows, welche automatisiert zu einer definierten Schedule laufen. So lässt sich ChaosEngineering zum Beispiel fest einplanen und automatisieren. Dies macht aus unterschiedlichsten Punkten Sinn, grundsätzlich sollte Chaos Engineering immer ein iterativer, wiederkehrender Prozesse sein. Mit einem Workflow können nicht nur Experiments installiert und damit Chaos ausgelöst werden, es gibt auch Steps, welche das Chaos wieder rückgängig machen können.

Ein solcher Workflow kann entweder per YAML geschrieben werden oder mittels der GUI im Chaos Center zusammengebaut werden.

Chaos Result

Ein Chaos Result stellt das eigentliche Resultat des Chaos Experiments dar. Hierbei handelt es sich ebenfalls um eine Kubernetes Custom Resource Definition, welche Informationen wie den Status usw. beinhaltet. Diese CR wird zur Laufzeit von unterschiedlichen Pods oder CronJobs aus aktualisiert, sodass immer der aktuellste Stand des einzelnen Experiments darin enthalten ist. Ausserdem wird es nicht als Teil des normalen Clean-Up Prozesses gelöscht und kann für weitere Auswertungen genutzt werden.

Chaos Hub

Das Chaos Hub fugiert als öffentlicher Market Place für Litmus Chaos Experiment. Konkret werden hier YAML Files für die sogenannten Litmus Chaos Experiments gehosted. Neben dem öffentlichen Hub gibt es auch eine Möglichkeit, einen oder mehrere privat Hubs zu betreiben und zu nutzen.

Technisch gesehen handelt es sich sowohl bei einem public als auch bei einem privaten Chaos Hub um ein Git Repository, welches angebunden wird.

Chaos Center

Der ChaosCenter ist das Herzstück von Litmus, er stellt die Single Source of Truth für die Kontrolle aller unterschiedlichen Chaos Aktivitäten dar.

Diese Web-UI ist Teil der eigentlichen Installation und lässt sich in einem Kubernetes Cluster einfach via Ingress, NodePort oder LoadBalancer verfügbar machen. Seit ver Version 2 erfreut sich diese UI grosser Beliebtheit, da sämtliche Administration, Auswertung usw. nicht mehr per CLI, wie in Version 1, gemacht werden muss. Durch die Multi-Cloud Fähigkeit mittels Chaos Agents kann der ChaosCenter unabhängig vom eigentliche Ziel-Chaos-Cluster deployed und genutzt werden.

Neben den Funktionalitäten für die Workflowerstellung und Ausführen bietet das ChaosCenter auch einen RBAC Administrationsbereich, eine Sektion für Monitoring & Observability sowie weitere Konfigurationsmöglichkeiten wie z.B. GitOps.

Chaos Agent

Der ChaosAgent fungiert als Prozess, welcher im Zielcluster, in dem Chaos ausgelöst werden soll, installiert wird und läuft. Hier gibt es zwei Arten von Agent, den Self und den External Agent. Beim Self Agent wird das Chaos in das "lokale" Cluster injected, wo auch der ChaosCenter deployed ist. Dies ist der simple Use Case, wo Litmus im selben Cluster wie die eigentliche Applikation installiert ist.

Mit dem External Agent lassen sich weitere Cluster bei unterschiedlichen Cloud-Providern (Multi Cloud) anbinden. Hierfür wird mit der hauseigene litmusctl ein Agent im entsprechenden Zielcluster installiert.

Chaos Observability

Unter diesem Bereich versteht man alle Metriken und Statistiken, welche bei einem Chaos Durchlauf so gesammelt werden, Litmus bietet hier die Möglichkeit, all diese Daten in einem Prometheus Format zu exportieren.

Hands On

Installation

Um Litmus nun ausprobieren zu können benötigen wir ein Kubernetes Cluster, wir in unserem Fall nutzen miniKube. Leider müssen wir aufgrund eines Fehlers eine veraltete Kubernetes Version nutzen (< v1.22.x):

minikube start --kubernetes-version v1.21.6

Nachdem unser Kubernetes Cluster läuft, wollen wir Litmus via Helm Chart in einen speziellen Namespace installieren.

kubectl create ns litmus
helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
helm install litmuschaos  --namespace litmus litmuschaos/litmus

Anschliessend können wir via kubectl get pods -n litmus prüfen, ob unsere drei Litmus Pods laufen. Hier sehen wir nun direkt drei Pods, ein Frontend, ein Server und eine MongoDB. Litmus nutzt die MongoDB hier um alle relevanten Daten, Logs usw. zum eigentlichen Chaos zu speichern. Das Frontend stellt den eigentlichen Chaos-Center dar und der Server Pod fungiert als API Zentrale.

Chaos Center

Sobald diese alle Running sind, wollen wir uns das ChaosCenter Dashboard genauer anschauen. Hierfür nutzen wir die NodePort Adresse des litmusportal-frontend-service, mit MiniKube müssen wir hier aber erst noch mit folgendem Befehl einen Tunnel aufmachen:

minikube service --url litmuschaos-frontend-service -n litmus

Anschliessend können wir uns dann mit den Daten admin/litmus einloggen und sind erfolgreich im Chaos-Center gelandet! Litmus Chaos Center

Mit dem ersten Login startet Litmus einige weitere Pods, welche fürs Chaos benötigt werden. Technisch gesehen wurde ein Litmus Projekt (im Dashboard oben links) angelegt. All diese Pods werden für den Chaos Self Service benötigt, zusätzlich wird der Self Agent im Cluster installiert.

Glücklicherweise bietet Litmus ein komplettes Demoprojekt an, welches per Self Service installiert werden kann.

Dies können wir starten, in dem wir über den Button Schedule a workflow einen neuen Workflow starten. Als Agent nutzen wir hier unseren Self Agent, anschliessend wählen wir den vordefinierten Chaos-Workflow podtato-head vom Litmus ChaosHub aus.

Im vierten Schritt wollen wir uns dann unsere Probe genauer anschauen. Hier sehen wir beispielsweise, dass eine Variable für den Namespace genutzt wird und das Deployment mit dem Label name=podtato-main das Chaos abbekommen soll. In den Einstellungen der httpProbe sehen wir dann weitere Informationen wie die URL, die eingestellten Timeouts und Intervalle und den erwarteten Response-Code von 200.

Im nächsten Schritt können wir dann mit dem Reliability Score das Gewicht dieses Workflows definieren. Da wir das Chaos sofort auslösen und austesten wollen wählen wir Schedule now und starten so das Chaos.

Nun wurde im Menü Litmus Workflows ein sogenannter Run dieses Workflows gestartet. Über die Optionen können wir den Workflow im Details ansehen oder weitere Statistiken begutachten.

Litmus Chaos Center Details

Dieser Workflow sollte erfolgreich durchlaufen und zeigt uns somit, dass das Löschen eines (oder mehrerer) Pods keinen Impact auf die Stabilität und Verfügbarkeit unserer Applikation hat!

Der erste eigene Workflow

Nun wollen wir aber einen eigenen Workflow für eine, aus anderen TechUps bekannte, Demoanwendung definieren.

Hierfür nutzen wir wieder die edgey-corp-nodejs-Applikation aus unsere Telepresence TechUp (Check it out!).

Diese starten wir via kubectl im default Namespace und öffnen anschliessend den Port um den K8s Service erreichen zu können.

kubectl apply -f https://raw.githubusercontent.com/datawire/edgey-corp-nodejs/main/k8s-config/edgey-corp-web-app-no-mapping.yaml

minikube service --url verylargejavaservice

Nachdem die Pods gestartet sind, können wir kurz über die URL aus dem MiniKube Befehl die einwandfreie Funktionalität der Anwendung prüfen, indem wir diese Url im Browser aufrufen.

Anschliessend fügen wir ein Label hinzu, um unsere Pods und Deployments eindeutig erkennen zu können. Hierfür nutzen wir ein auf dem Pods bereits vorhandenen Label auch für das Deployment.

kubectl label deployment verylargejavaservice run=verylargejavaservice

Nun könnten wir zwar einen Workflow mit einer httpProbe mit der URL, welche wir via MiniKube im Browser aufrufen können, definieren. Dies würde aber aus dem Cluster raus nicht funktionieren, daher müssen wir erst die korrekte URL für unseren Service herausfinden und dies aus dem litmus Namespace heraus verifizieren. Technisch gesehen können wir hier nun entweder die interne IP der Services nehmen und wir nutzen den Kubernetes intern bekannten DNS Namen verylargejavaservice.default.svc.cluster.local.

Um einen kurzen Test zu machen, starten wir uns einen busybox Pod um einen curl aus dem litmus Namespace heraus absetzen zu können.

kubectl run curlpod --image=radial/busyboxplus:curl -n litmus --command -- /bin/sh -c "while true; do echo hi; sleep 10; done" 

kubectl exec -it curlpod -n litmus curl verylargejavaservice.default.svc.cluster.local:8080

Den zweiten Befehl können wir nach kurzer Wartezeit ausführen, bekommen wir als Antwort eine HTML Struktur mit dem Title Welcome to the EdgyCorp WebApp sieht alles gut aus.

Nun aber schnell zu unserem ersten eigenen Litmus Workflow. Wie bereits vorher starten wir einen neuen Workflow mit Schedule a workflow, wählen wieder den Self Agent und dann Create a new workflow using the experiments from ChaosHub.

Im vierten Schritt können wir nun ein Experiment hinzufügen und sehen hier einer Liste aller Experiment, welche aktuell auf dem öffentlichen ChaosHub verfügbar sind.

Der Einfachheit halber entscheiden wir uns wieder für das generic/pod-delete Szenario und konfigurieren dies wie folgt:

Litmus Chaos Center Own Workflow

Sehr angenehm ist hier, dass Litmus die Namespaces, Labels usw. aus dem Cluster kennt und uns Vorschläge gibt.

Für die Probe nutzen wir wieder eine httpProbe und wollen die Calls auf den zuvor geprüften DNS Namen machen. Als Response erwarten wir in jedem Fall einen HTTP Response-Code von 200 (Success).

Litmus Chaos Center Own Workflow Probe

Wichtig ist hier, dass die Timeout entsprechend gesetzt sind, da die Probe sonst erkennt, dass Downtime vorliegt, obwohl eigentlich die Applikation "nur" zu langsam antwortet.

Die weiteren Schritte können wir alle mit Next bestätigen, im letzten Schritt können wir noch unser YAML genauer anschauen. Hier fällt sofort auf, dass es sich um ArgoCD Resource handelt. Bei einem GitOps Ansatz würde dieses YAML dann versioniert in ein Repository gepushed werden.

Ist unsere Applikation resilient?

Nachdem wir unseren Workflow angelegt haben wird dieser sofort gestartet. Nach kurzer Wartezeit sehen wir dann ernüchternd, dass das Resultat rot ist und wir einen Ausfall der Applikation hatten. Litmus Chaos Workflow failed

Über die Details des Workflows sehen wir die Logs sowie das Chaos Result und findet schnell raus, dass unsere httpProbe fehlgeschlagen ist.

Alleine durch das Ausführen des Befehls kubectl get deployments sehen wir den Grund für diesen Ausfall und die ausgebliebene Stabilität. Sehen Sie es auch?

In unserem Experiment haben wir einen Pod gelöscht, da unser Deployment aber nur eine Replica hat kam es zu einem Ausfall.

Nun wollen wir aber ein Erfolgserlebnis haben und wollen unsere Applikation stabiler machen, hierfür skalieren die das Deployment auf insgesamt zwei Pods mit folgendem Befehl hoch:

kubectl scale deployment verylargejavaservice --replicas 2

Nach kurzer Wartezeit sehen wir, das nun zwei Pods unseres Services laufen. Im Menüpunkt Litmus Workflows können wir nun im Tab Schedules ein Rerun anstossen, um unser Chaos erneut auszulösen.

Litmus Chaos Workflow success

Nun sehen wir, dass der Workflow eine 100 % Stabilität anzeigt und wir somit unsere Applikation erfolgreich getestet und verbessert haben! 🚀

Vor & Nachteile

Ein ganz klarer Vorteil ist der GitOps Ansatz von Litmus. Oft hat man eine tolle, gut funktionierende Web Ui um Ressourcen anzulegen oder zu verwalten, die Changes werden meist aber direkt im Cluster appliziert und nirgends persistiert. Litmus bietet hier die Einstellungsmöglichkeit, sämtliche Resource via GitOps Prozess in einem Repository als Single Source of Truth zu speichern. Ein weiterer Vorteil ist der Einsatz von ArgoCD Workflows under the hood. Dies macht Litmus zuverlässig und stabil und sort ebenso für einen Yaml-basierten Ansatz.

Grundsätzlich ist sicher auch der Open Source Ansatz mit bekannten Contributors und wirklich breitem Funktionsumfang ein Vorteil.

Ein klarer Nachteil ist aktuell sicherlich die Kompatibilität, Litmus war in unserem Test nicht mit der neuesten Kubernetes Version nutzbar, hier muss klar nachgelegt werden. Ausserdem hört man oft das Argument, dass Litmus "nur" für Chaos Engineering im Kubernetes Umfeld, nicht aber in der Infrastruktur eingesetzt werden sollte. Hier wird eventuell auch noch nachgebessert, beispielsweise könnten noch mehr Experiments für die eigentliche Infrastruktur wie AWS o. ä. angeboten werden.

Fazit

Litmus will Grosses erreichen, das steht fest!

Leider kam es beim Ausprobieren immer wieder zu Problemen, welche im Guide nicht direkt beschrieben waren. Diese werden aber sicherlich zeitnah behoben, dann steht einem Open Source Chaos Engineering mit Litmus nichts mehr im Wege.

Stay tuned!

Tom Trapp – Problemlöser, Innovator, Sportler. Am liebsten feilt Tom den ganzen Tag an der moderner Software und legt viel Wert auf objektiv sauberen, leanen Code.