Willkommen, Habr!
Wir waren die Ersten, die das Thema auf den russischen Markt gebracht haben, und verfolgen weiterhin . Ein Überblick (und ziemlich vorsichtig) zu diesem Thema erschien bereits im Blog der Firma Confluent im Oktober letzten Jahres unter der Federführung von Gwen Shapiro. Heute möchten wir Ihre Aufmerksamkeit auf einen neueren Artikel von Johann Gyger im April lenken, der, obwohl er nicht ohne Fragezeichen im Titel auskommt, das Thema in einem konkreteren Rahmen betrachtet und den Text mit interessanten Links ergänzt. Bitte entschuldigen Sie uns die freie Übersetzung von „chaos monkey“, wenn Sie können! Kubernetes ist für den Betrieb von zustandslosen Workloads konzipiert. Diese werden normalerweise in Form einer Mikroservice-Architektur dargestellt, sind leichtgewichtig, gut horizontal skalierbar, folgen den Prinzipien von 12-Factor-Apps, ermöglichen die Verwendung von automatischen Abschaltern (circuit breaker) und Chaosmonkeys. Zu diesem Thema veröffentlichte das Unternehmen Confluent bereits im Oktober letzten Jahres einen Blogbeitrag von Gwen Shapiro. Heute möchten wir Ihre Aufmerksamkeit auf einen neueren Artikel von Johann Gyger aus dem April lenken. Obwohl er in seinem Titel nicht ohne ein Fragezeichen auskommt, behandelt er das Thema mit einem konkreteren Ansatz und ergänzt den Text mit interessanten Links. Bitte entschuldigen Sie unsere freie Übersetzung von „chaos monkey“, wenn Sie können!
Einführung
Kubernetes ist für den Betrieb von zustandslosen Workloads konzipiert. In der Regel zeigen sich solche Workloads in Form von Microservice-Architekturen, die leichtgewichtig sind, sich gut horizontal skalieren lassen, den Prinzipien von 12-Faktor-Anwendungen entsprechen, den Einsatz von Circuit Breakern unterstützen und mit Chaosmonkeys arbeiten.
Kafka, der sich auf der anderen Seite befindet, fungiert im Wesentlichen als verteilte Datenbank. Daher müssen Sie beim Arbeiten mit ihm den Zustand berücksichtigen, der weitaus komplexer ist als bei einem Mikrodienst. Kubernetes unterstützt zustandsbehaftete Workloads, aber wie Kelsey Hightower in zwei seiner Tweets anmerkt, sollte man mit ihnen vorsichtig umgehen:
Einige denken, dass, wenn man Kubernetes auf einen zustandsbehafteten Workload anwendet, es sich in eine vollständig verwaltete Datenbank verwandelt, die mit RDS konkurrieren kann. Das ist nicht der Fall. Vielleicht, wenn man genug Aufwand betreibt, zusätzliche Komponenten integriert und ein Team von SRE-Ingenieuren hinzuzieht, kann man RDS auf Kubernetes einrichten.
Ich empfehle immer, beim Ausführen zustandsbehafteter Workloads auf Kubernetes äußerst vorsichtig zu sein. Die meisten, die sich fragen: "Kann ich zustandsbehaftete Workloads auf Kubernetes ausführen?", haben nicht genügend Erfahrung mit Kubernetes und oft auch nicht mit dem spezifischen Workload, nach dem sie fragen.
Sollte man Kafka also auf Kubernetes ausführen? Eine Gegenfrage: Würde Kafka besser ohne Kubernetes laufen? Deshalb möchte ich in diesem Artikel betonen, wie Kafka und Kubernetes sich gegenseitig ergänzen und welche Fallstricke bei ihrer Kombination auftreten können.
Laufzeit
Lassen Sie uns über eine grundlegende Sache sprechen – das Konzept der Laufzeitumgebung an sich.
Prozess
Kafka-Broker sind CPU-effizient. TLS kann einige Kosten verursachen. Gleichzeitig können Kafka-Clients die CPU stärker belasten, wenn sie Verschlüsselung nutzen, doch dies hat keine Auswirkungen auf die Broker.
Speicher
Kafka-Broker verbrauchen viel RAM. Die JVM-Heap-Größe sollte normalerweise auf 4–5 GB begrenzt werden, aber Sie benötigen auch viel Systemspeicher, da Kafka intensiv den Seiten-Cache nutzt. Stellen Sie in Kubernetes entsprechend Ressourcenlimits und -anforderungen für die Container ein.
Datenspeicher
Der Datenspeicher in Containern ist flüchtig – Daten gehen beim Neustart verloren. Für Kafka-Daten können Sie ein Volume verwenden. emptyDir, und der Effekt wird ähnlich sein: die Daten Ihres Brokers gehen nach der Beendigung verloren. Ihre Nachrichten können dennoch als Replikate bei anderen Brokern gespeichert bleiben. Daher muss der ausgefallene Broker nach dem Neustart als Erstes alle Daten replizieren, und dieser Prozess kann einige Zeit in Anspruch nehmen.
Das ist der Grund, warum Sie einen langfristigen Datenspeicher verwenden sollten. Dies sollte ein nicht-lokales Langzeitdatenspeicher mit dem XFS-Dateisystem oder genauer gesagt, ext4 sein. Vermeiden Sie NFS. Ich habe gewarnt. NFS-Versionen v3 oder v4 werden nicht funktionieren. Kurz gesagt, der Kafka-Broker wird beendet, wenn er das Verzeichnis mit den Daten aufgrund von 'dummen Umbenennungen', die in NFS auftreten, nicht löschen kann. Wenn ich Sie bis jetzt nicht überzeugt habe, lesen Sie bitte . Der Datenspeicher sollte nicht-lokal sein, damit Kubernetes flexibler einen neuen Knoten nach einem Neustart oder einer Relokation auswählen kann.
Netzwerk
Wie bei den meisten verteilten Systemen hängt die Leistung von Kafka stark davon ab, dass die Netzwerkverzögerungen minimal und die Bandbreite maximal sind. Versuchen Sie nicht, alle Broker auf demselben Knoten zu platzieren, da dies die Verfügbarkeit verringern kann. Wenn ein Kubernetes-Knoten ausfällt, fällt auch der gesamte Kafka-Cluster aus. Verteilen Sie den Kafka-Cluster auch nicht über ganze Rechenzentren. Dasselbe gilt für den Kubernetes-Cluster. Ein guter Kompromiss in diesem Fall ist, verschiedene Verfügbarkeitszonen zu wählen.
Konfiguration
Übliche Manifeste
Auf der Website von Kubernetes gibt es wie man ZooKeeper mit Manifesten konfiguriert. Da ZooKeeper Teil von Kafka ist, ist dies ein guter Ausgangspunkt, um sich mit den in Kubernetes verwendeten Konzepten vertraut zu machen. Wenn Sie dies verstanden haben, können Sie dieselben Konzepte auch für den Kafka-Cluster nutzen.
- Unter: Ein Pod ist die kleinste implementierbare Einheit in Kubernetes. In einem Pod befindet sich Ihre Arbeitslast, während der Pod selbst dem Prozess in Ihrem Cluster entspricht. Ein Pod kann einen oder mehrere Container enthalten. Jeder ZooKeeper-Server in einem Ensemble und jeder Broker in einem Kafka-Cluster wird in einem eigenen Pod betrieben.
- StatefulSet: Ein StatefulSet ist ein Kubernetes-Objekt, das mit mehreren zustandsbehafteten Arbeitslasten arbeitet, die Koordination erfordern. StatefulSets bieten Garantien hinsichtlich der Reihenfolge und der Einzigartigkeit der Pods.
- Headless-Dienste: Dienste ermöglichen es, Pods von Clients über einen logischen Namen zu trennen. Kubernetes übernimmt in diesem Fall die Lastenverteilung. Bei der Arbeit mit zustandsbehafteten Arbeitslasten, wie bei ZooKeeper und Kafka, müssen Clients jedoch mit einer bestimmten Instanz kommunizieren. Hier kommen die Headless-Dienste ins Spiel: In diesem Fall hat der Client zwar weiterhin einen logischen Namen, muss aber nicht direkt auf den Pod zugreifen.
- Volumen für die langfristige Speicherung: Solche Volumes sind für die Konfiguration von nicht-lokalen Blockspeicherlösungen erforderlich, die oben erwähnt wurden.
Auf bietet eine umfassende Sammlung von Manifesten, die Ihnen den Einstieg mit Kafka auf Kubernetes erleichtern.
Helm-Diagramme
Helm ist ein Paketmanager für Kubernetes, vergleichbar mit Paketmanagern für Betriebssysteme wie yum, apt, Homebrew oder Chocolatey. Damit können Sie vorab definierte Softwarepakete installieren, die in Helm-Diagrammen beschrieben sind. Ein gut ausgewähltes Helm-Diagramm vereinfacht die komplexe Aufgabe, wie man alle Parameter für die Nutzung von Kafka auf Kubernetes korrekt konfiguriert. Es gibt mehrere Kafka-Diagramme: das offizielle befindet sich , es gibt eines von , und eines von .
Operatoren
Da Helm bestimmte Nachteile aufweist, gewinnt ein weiteres Tool an Popularität: Kubernetes-Operatoren. Ein Operator verpackt nicht nur Software für Kubernetes, sondern ermöglicht auch deren Bereitstellung und Verwaltung.
In der Liste werden zwei Operatoren für Kafka erwähnt. Einer von ihnen ist . Mit Strimzi ist es ein Kinderspiel, in wenigen Minuten ein Kafka-Cluster aufzusetzen. Praktisch keine Konfiguration ist notwendig, zudem bietet der Operator einige nützliche Funktionen wie die End-to-End TLS-Verschlüsselung innerhalb des Clusters. Auch Confluent bietet .
Leistung
. Es ist äußerst wichtig, die Leistung des installierten Kafka-Clusters mit Kontrollpunkten zu testen. Solche Tests helfen, potenzielle Engpässe zu identifizieren, bevor Probleme auftreten. Glücklicherweise stehen in Kafka bereits zwei Tools zur Verfügung, um die Leistung zu testen: kafka-producer-perf-test.sh und kafka-consumer-perf-test.sh. Nutzen Sie diese aktiv. Zur Orientierung können Sie die Ergebnisse in von Jay Kreps nachlesen oder sich an von Stéphane Maarek über Amazon MSK orientieren.
Operationen
Überwachung
Transparenz im System ist von entscheidender Bedeutung – otherwise müssen Sie verstehen, was darin geschieht. Heute stehen solide Werkzeuge zur Verfügung, die Cloud-native-metrikbasierte Überwachung ermöglichen. Zwei beliebte Tools zu diesem Zweck sind Prometheus und Grafana. Prometheus kann Metriken von allen Java-Prozessen (Kafka, Zookeeper, Kafka Connect) ganz einfach mit dem JMX-Exporter sammeln. Wenn Sie die Metriken von cAdvisor hinzufügen, erhalten Sie ein vollständigeres Bild davon, wie Ressourcen in Kubernetes genutzt werden.
Strimzi bietet ein sehr benutzerfreundliches Grafana-Dashboard-Beispiel für Kafka. Es visualisiert wichtige Metriken, wie z.B. nicht replizierte Partitionen oder solche, die offline sind. Alles ist sehr klar. Diese Metriken werden durch Informationen über Ressourcennutzung und Leistung sowie Stabilitätsindikatoren ergänzt. So erhalten Sie eine grundlegende Überwachung des Kafka-Clusters zum Nulltarif!

Quelle:
Das Ganze könnte durch die Überwachung von Clients (Metriken zu Verbrauchern und Produzenten) sowie durch die Überwachung der Latenzzeit ergänzt werden (dafür gibt es ) und durch eine durchgängige Überwachung – verwenden Sie dafür .
Protokollierung
Logging ist eine weitere grundlegende Aufgabe. Stellen Sie sicher, dass alle Container in Ihrer Kafka-Installation protokolliert werden, stdout und stderrund sorgen Sie dafür, dass Ihr Kubernetes-Cluster alle Protokolle in einer zentralen Logging-Infrastruktur aggregiert, wie zum Beispiel in .
Überprüfung der Funktionsfähigkeit
Kubernetes verwendet „Liveness“- und „Readiness“-Sonden, um zu überprüfen, ob Ihre Pods ordnungsgemäß funktionieren. Wenn die Liveness-Prüfung fehlschlägt, beendet Kubernetes diesen Container und startet ihn automatisch neu, sofern die Restart-Policy entsprechend festgelegt ist. Bei einem Fehlschlag der Readiness-Prüfung isoliert Kubernetes diesen Pod von eingehenden Anfragen. In solchen Fällen ist kein manuelles Eingreifen mehr erforderlich, was einen großen Vorteil darstellt.
Rollout von Updates
StatefulSets unterstützen automatische Updates: Bei der Wahl der Strategie RollingUpdate wird jeder Kafka-Pod nacheinander aktualisiert. So kann die Dauer von Ausfallzeiten auf null reduziert werden.
Skalierung
Das Skalieren eines Kafka-Clusters ist eine anspruchsvolle Aufgabe. In Kubernetes hingegen ist es sehr einfach, Pods auf eine bestimmte Anzahl von Replikaten zu skalieren. Das bedeutet, dass Sie deklarativ so viele Kafka-Broker definieren können, wie Sie möchten. Die größte Herausforderung besteht in der Umverteilung der Partitionen nach einem Hochskalieren oder vor einem Herunterskalieren. Auch hier kann Ihnen Kubernetes helfen.
Administration
Aufgaben, die mit der Verwaltung Ihres Kafka-Clusters zusammenhängen, insbesondere die Erstellung von Topics und die Umverteilung von Partitionen, können durch die vorhandenen Shell-Skripte durchgeführt werden, indem Sie die Befehlszeilenschnittstelle in Ihren Pods öffnen. Diese Lösung ist jedoch nicht besonders elegant. Strimzi unterstützt die Verwaltung von Topics durch einen anderen Operator. Hier gibt es noch Verbesserungsbedarf.
Backup und Wiederherstellung
Die Verfügbarkeit von Kafka hängt künftig auch von der Verfügbarkeit von Kubernetes ab. Fällt Ihr Kubernetes-Cluster aus, wird im schlimmsten Fall auch der Kafka-Cluster ausfallen. Murphy's Gesetz besagt, dass dies zwangsläufig passieren wird, und Sie werden Daten verlieren. Um das Risiko zu minimieren, planen Sie ein robustes Backup-Konzept. Sie können MirrorMaker nutzen oder S3 für diese Zwecke einsetzen, wie in diesem beschrieben. von Zalando.
Fazit
Bei der Arbeit mit kleinen oder mittleren Kafka-Clustern ist der Einsatz von Kubernetes auf jeden Fall sinnvoll, da es zusätzliche Flexibilität bietet und die Zusammenarbeit mit Operatoren erleichtert. Sollten Sie sehr strenge nicht-funktionale Anforderungen an Latenz und/oder Durchsatz haben, könnte es sinnvoller sein, eine alternative Bereitstellungsmethode in Betracht zu ziehen.
Quelle: habr.com
