Willkommen, Habr!
Zu seiner Zeit haben wir als erste das Thema auf den russischen Markt gebracht seine Entwicklung. Besonders interessant fanden wir das Thema der Interaktion zwischen Kafka und . Ein Überblick (und ziemlich vorsichtig) zu diesem Thema erschien im Blog des Unternehmens Confluent bereits im Oktober letzten Jahres unter der Autorenschaft von Gwen Shapiro. Heute möchten wir Ihre Aufmerksamkeit auf einen aktuelleren Artikel von Johann Gyger lenken, der, obwohl er im Titel nicht ohne Fragezeichen auskommt, das Thema aus einem konkreteren Blickwinkel betrachtet und den Text mit interessanten Links ergänzt. Bitte entschuldigen Sie uns den freien Übersetzungsversuch von „chaos monkey“, wenn Sie können!
Einführung
Kubernetes ist für die Arbeit mit zustandslosen Lasten konzipiert. In der Regel werden solche Arbeitslasten in Form einer Microservices-Architektur dargestellt, sie sind leichtgewichtig, gut horizontal skalierbar, folgen den Prinzipien der 12-Faktor-Anwendungen, ermöglichen den Einsatz von automatischen Schaltern (circuit breaker) und Chaos-Monkeys.
Kafka hingegen fungiert im Wesentlichen als verteilte Datenbank. Somit muss man bei der Arbeit mit ihn sich mit Zustand befassen, der deutlich schwerer wiegt als ein Microservice. Kubernetes unterstützt workloads mit Zustand, aber wie Kelsey Hightower in zwei seiner Tweets anmerkt, ist mit ihnen vorsichtig umzugehen:
Einige glauben, wenn Kubernetes auf eine zustandsbehaftete Last angewandt wird, wird es zu einer vollständig verwalteten Datenbank, die mit RDS konkurrieren kann. Das ist nicht der Fall. Vielleicht gelingt es, wenn man genügend Mühe investiert, zusätzliche Komponenten anfügt und ein Team von SRE-Ingenieuren einbezieht, ein RDS über Kubernetes zu erstellen.
Ich empfehle immer, bei der Ausführung zustandsbehafteter Lasten auf Kubernetes außergewöhnlich vorsichtig zu sein. Die meisten, die sich fragen, „Kann ich zustandsbehaftete Lasten auf Kubernetes ausführen“, haben nicht genügend Erfahrung mit Kubernetes, und oft auch nicht mit der spezifischen Last, nach der gefragt wird.
Sollte man Kafka auf Kubernetes ausführen? Eine Gegenfrage: Wird Kafka besser ohne Kubernetes funktionieren? Deshalb möchte ich in diesem Artikel hervorheben, wie Kafka und Kubernetes sich gegenseitig ergänzen und welche Fallstricke beim Zusammenspiel dieser beiden Technologien auftreten können.
Ausführungszeit
Lass uns über eine grundlegende Sache sprechen – die Ausführungsumgebung an sich.
Prozess
Kafka-Broker sind CPU-freundlich. TLS kann einige Kosten verursachen. Dabei können Kafka-Clients die CPU stärker belasten, wenn sie Verschlüsselung verwenden, was sich jedoch nicht auf die Broker auswirkt.
Speicher
Kafka-Broker nehmen Speicher in Anspruch. Die JVM-Haupthaltestgröße sollte normalerweise auf 4-5 GB begrenzt werden, aber Sie benötigen auch viel Systemspeicher, da Kafka den Seiten-Cache sehr aktiv nutzt. Stellen Sie in Kubernetes die Containerlimits für Ressourcen und Anfragen entsprechend ein.
Datenspeicherung
Die Datenspeicherung in Containern ist flüchtig – Daten gehen bei einem Neustart verloren. Für Kafka-Daten kann ein Volume verwendet werden emptyDir, und der Effekt wird ähnlich sein: Die Daten Ihres Brokers gehen nach dem Herunterfahren verloren. Ihre Nachrichten können jedoch als Replikate von anderen Brokern erhalten bleiben. Daher muss der ausgefallene Broker nach dem Neustart zunächst alle Daten replizieren, was einige Zeit in Anspruch nehmen kann.
Deshalb sollte man ein dauerhaftes Datenspeicher verwenden. Lassen Sie es ein nicht-lokales, dauerhaftes Speichersystem mit XFS oder genauer gesagt ext4 sein. Verwenden Sie kein NFS. Ich warne Sie. NFS-Versionen v3 oder v4 werden nicht funktionieren. Kurz gesagt, der Kafka-Broker wird abbrechen, wenn er das Datenverzeichnis aufgrund eines Problems mit den „dummen Umbenennungen“, die bei NFS auftreten, nicht löschen kann. Falls ich Sie bis jetzt nicht überzeugt habe, lesen Sie bitte sehr aufmerksam . Der Datenspeicher sollte nicht lokal sein, damit Kubernetes flexibler einen neuen Knoten nach einem Neustart oder einer Neuplatzierung auswählen kann.
Netzwerk
Wie bei den meisten verteilten Systemen hängt die Leistung von Kafka stark davon ab, dass die Netzwerklatenzen minimal und die Bandbreiten maximal sind. Versuchen Sie nicht, alle Broker auf demselben Knoten zu platzieren, da die Verfügbarkeit dadurch verringert wird. Wenn ein Kubernetes-Knoten ausfällt, fällt der gesamte Kafka-Cluster aus. Verteilen Sie auch den Kafka-Cluster nicht über ganze Rechenzentren. Das Gleiche gilt für den Kubernetes-Cluster. Ein guter Kompromiss in diesem Fall ist, verschiedene Verfügbarkeitszonen auszuwählen.
Konfiguration
Übliche Manifeste
Auf der Kubernetes-Website gibt es darüber, wie man ZooKeeper mit Hilfe von Manifesten konfiguriert. Da ZooKeeper Teil von Kafka ist, ist es sinnvoll, hiermit zu beginnen, um herauszufinden, welche Konzepte von Kubernetes hier anwendbar sind. Nachdem Sie dies verstanden haben, können Sie dieselben Konzepte auch im Kafka-Cluster anwenden.
- Pod: Pod – das ist die kleinste deploybare Einheit in Kubernetes. Im Pod befindet sich Ihre Arbeitslast, und der Pod selbst entspricht einem Prozess in Ihrem Cluster. Im Pod gibt es einen oder mehrere Container. Jeder ZooKeeper-Server im Ensemble und jeder Broker im Kafka-Cluster wird in einem separaten Pod betrieben.
- StatefulSet: StatefulSet ist ein Kubernetes-Objekt, das mit mehreren zustandsbehafteten Arbeitslasten arbeitet, wobei solche Arbeitslasten Koordination erfordern. StatefulSets bieten Garantien hinsichtlich der Reihenfolge der Pods und ihrer Einzigartigkeit.
- Headless-Dienste: Dienste ermöglichen es, Pods von Clients durch einen logischen Namen zu trennen. Kubernetes ist in diesem Fall für die Lastverteilung zuständig. Bei staatlichen Arbeitslasten, wie bei ZooKeeper und Kafka, müssen die Clients jedoch Informationen mit einer bestimmten Instanz austauschen. Hier kommen die headless-Dienste ins Spiel: In diesem Fall hat der Client immer noch einen logischen Namen, aber es ist nicht notwendig, direkt auf den Pod zuzugreifen.
- Volumen für die langfristige Speicherung: solche Volumen sind erforderlich, um eine nicht lokale blockbasierte langfristige Speicherung zu konfigurieren, die oben erwähnt wurde.
Auf stellt ein umfassendes Set an Manifesten zur Verfügung, mit denen Sie bequem mit Kafka auf Kubernetes beginnen können.
Helm-Diagramme
Helm ist ein Paketmanager für Kubernetes, der mit Paketmanagern für Betriebssysteme wie yum, apt, Homebrew oder Chocolatey verglichen werden kann. Damit lassen sich vordefinierte Softwarepakete, die in Helm-Diagrammen beschrieben sind, einfach installieren. Ein gut gestaltetes Helm-Diagramm erleichtert die komplexe Aufgabe, alle Parameter zur Nutzung von Kafka auf Kubernetes richtig zu konfigurieren. Es gibt mehrere Kafka-Diagramme: das offizielle befindet sich , es gibt eines von , ein weiteres von .
Operatoren
Da Helm bestimmte Mängel aufweist, gewinnt ein weiteres Werkzeug, die Kubernetes-Operatoren, zunehmend an Beliebtheit. Ein Operator verpackt nicht nur Software für Kubernetes, sondern ermöglicht es Ihnen auch, diese Software bereitzustellen und zu verwalten.
In der Liste werden zwei Operatoren für Kafka erwähnt. Einer von ihnen ist . Mit Hilfe von Strimzi ist es ein Kinderspiel, innerhalb weniger Minuten ein Kafka-Cluster aufzubauen. Praktisch keine Konfiguration ist erforderlich, darüber hinaus bietet der Operator einige angenehme Funktionen, wie z. B. Punkt-zu-Punkt-TLS-Verschlüsselung innerhalb des Clusters. Confluent bietet ebenfalls .
Leistung
Es ist sehr wichtig, die Performance zu testen, indem Sie Ihrem installierten Kafka-Exemplar Kontrollpunkte hinzufügen. Solche Tests helfen Ihnen, potenzielle Engpässe zu erkennen, bevor Probleme auftreten. Glücklicherweise bietet Kafka bereits zwei Werkzeuge zum Testen der Leistung an: kafka-producer-perf-test.sh und kafka-consumer-perf-test.sh. Verwenden Sie sie aktiv. Zur Referenz können Sie die Ergebnisse, die in von Jay Kreps beschrieben sind, überprüfen oder sich an von Stéphane Maarek über Amazon MSK orientieren.
Operationen
Überwachung
Transparenz im System ist sehr wichtig - andernfalls verstehen Sie nicht, was darin vor sich geht. Heutzutage gibt es eine solide Palette von Tools für die Überwachung basierend auf cloud-nativen Metriken. Zwei beliebte Werkzeuge zu diesem Zweck sind Prometheus und Grafana. Prometheus kann Metriken von allen Java-Prozessen (Kafka, Zookeeper, Kafka Connect) sehr einfach über den JMX-Exporter sammeln. Wenn Sie die cAdvisor-Metriken hinzufügen, bekommen Sie ein umfassenderes Bild davon, wie Ressourcen in Kubernetes genutzt werden.
Strimzi bietet ein sehr praktisches Beispiel für ein Grafana-Dashboard für Kafka. Es visualisiert wichtige Metriken, zum Beispiel zu nicht replizierten Partitionen oder zu denen, die offline sind. Alles ist sehr übersichtlich. Diese Metriken werden durch Informationen zur Ressourcennutzung und Leistung sowie Stabilitätsindikatoren ergänzt. So erhalten Sie eine grundlegende Überwachung des Kafka-Clusters völlig kostenlos!

Quelle:
All dies wäre gut durch ein Client-Monitoring (Metriken zu Consumer und Producer) sowie ein Monitoring der Verzögerung zu ergänzen (dafür gibt es ) und ganzheitliches Monitoring – hierfür nutzen Sie .
Protokollierung
Logging ist eine weitere sehr wichtige Aufgabe. Stellen Sie sicher, dass alle Container in Ihrer Kafka-Installation in stdout und stderr, und sorgen Sie dafür, dass Ihr Kubernetes-Cluster alle Logs in einer zentralen Logging-Infrastruktur aggregiert, zum Beispiel in .
Healthcheck
Kubernetes verwendet 'Liveness'- und 'Readiness'-Probes, um zu überprüfen, ob Ihre Pods ordnungsgemäß funktionieren. Wenn der Liveness-Check fehlschlägt, stoppt Kubernetes diesen Container und startet ihn automatisch neu, sofern die Neustart-Richtlinie entsprechend konfiguriert ist. Wenn der Readiness-Check fehlschlägt, isoliert Kubernetes diesen Pod von der Bearbeitung von Anfragen. In solchen Fällen ist also kein manuelles Eingreifen mehr erforderlich, was ein großer Vorteil ist.
Rollout von Updates
StatefulSets unterstützen automatische Updates: Bei Wahl der RollingUpdate-Strategie wird jeder Kafka-Pod nacheinander aktualisiert. So können Ausfallzeiten auf null reduziert werden.
Skalierung
Das Skalieren des Kafka-Clusters ist eine herausfordernde Aufgabe. Allerdings ist es in Kubernetes sehr einfach, Pods auf eine bestimmte Anzahl von Replikaten zu skalieren, was bedeutet, dass Sie deklarativ so viele Kafka-Broker definieren können, wie Sie möchten. Die schwierigste Aufgabe in diesem Fall ist die Neuzuweisung der Partitionen nach dem Hochskalieren oder vor dem Herunterskalieren. Auch hierbei kann Ihnen Kubernetes helfen.
Administration
Die Aufgaben, die mit der Administration Ihres Kafka-Clusters verbunden sind, insbesondere das Erstellen von Topics und das Neuzuordnen von Partitionen, können mit den vorhandenen Shell-Skripten über die Befehlszeilenschnittstelle in Ihren Pods durchgeführt werden. Diese Lösung ist jedoch nicht besonders elegant. Strimzi unterstützt die Verwaltung von Topics über einen anderen Operator. Hier gibt es noch Verbesserungsbedarf.
Backup und Wiederherstellung
Die Verfügbarkeit von Kafka hängt nun auch von der Verfügbarkeit von Kubernetes ab. Wenn Ihr Kubernetes-Cluster ausfällt, wird im schlimmsten Fall auch der Kafka-Cluster ausfallen. Murphy's Gesetz besagt, dass dies zwangsläufig geschehen wird und Sie Daten verlieren werden. Um das Risiko dieser Art zu verringern, sollten Sie ein durchdachtes Backup-Konzept entwickeln. Sie können MirrorMaker verwenden, eine andere Option besteht darin, dafür S3 zu nutzen, wie in diesem von Zalando.
Fazit
Bei der Arbeit mit kleinen oder mittleren Kafka-Clustern ist es auf jeden Fall sinnvoll, Kubernetes zu verwenden, da es zusätzliche Flexibilität bietet und die Arbeit mit Operatoren erleichtert. Wenn Sie sehr strenge nichtfunktionale Anforderungen in Bezug auf Latenz und/oder Durchsatz haben, sollten Sie möglicherweise eine andere Bereitstellungsoption in Betracht ziehen.
Quelle: habr.com
