Kafka in Produktion: von null zum Profi (Teil 2)

Kafka in Produktion – wir bauen einen skalierbaren, sicheren und Enterprise-tauglichen Message Bus auf der Google Cloud Platform
opensight.ch - roman hüsler
Inhaltsverzeichnis
- Teil 1 – Kafka-Einzelinstanz mit Docker
- Teil 2 – Kafka-Einzelinstanz mit Authentifizierung (SASL)
- Teil 3 – Kafka-Cluster mit TLS-Authentifizierung und ACLs
- Teil 4 – Enterprise-Authentifizierung und Zugriffskontrolle (OAuth 2.0)
- Teil 5 – Produktiver Kafka-Cluster auf Google Cloud mit Strimzi
- Teil 6 – Observability und Data Governance mit Strimzi (folgt)
TL;DR
Ich empfehle zwar, die Blogposts zu lesen, aber ich weiss, dass manche direkt zur «Single Source of Truth» springen: zum Code. Das ist ungefähr so, wie an einem Freitag ungetestet zu deployen.
Bitte sehr:
Einführung
Apache Kafka ist eine leistungsfähige Event-Streaming-Plattform, doch der Betrieb in Produktion ist eine ganz andere Herausforderung. Wir beginnen mit den Grundlagen, aber das hier ist kein Spielplatz: Schritt für Schritt bauen wir einen Message Bus in Enterprise-Qualität, der Hochverfügbarkeit, Sicherheit und Skalierbarkeit für echte Workloads bietet.
Ich bin selbst kein Kafka-Spezialist, ich lerne unterwegs. Wie so oft bei den opensight-Blogs können Sie mich auf meinem Weg von null zum Profi begleiten.
In dieser Blogserie gehen wir mit Kafka über die Grundlagen hinaus. Wir entwerfen ein produktionsreifes Kafka-Cluster-Deployment, das folgende Eigenschaften hat:
- Skalierbar – bewältigt wachsende Last ohne Performance-Engpässe.
- Sicher – setzt Authentifizierung (Plain, SCRAM, OAUTH), Autorisierung (ACL, OAUTH) und Verschlüsselung (TLS) durch.
- Sauber strukturiert – inklusive Schema Registry für eine ordentliche Data Governance.
- Enterprise-tauglich – mit den Funktionen, die eine ereignisgesteuerte Architektur in einer grossen Umgebung braucht.
SASL-Plaintext-Authentifizierung
Um in Kafka Authentifizierung zu konfigurieren, sind einige Anpassungen an der Konfigurationsdatei server.properties nötig. In diesem Setup setzen wir Simple Authentication and Security Layer (SASL) ein, um vor dem Kafka-Broker eine Client-Authentifizierung zu erzwingen.
SASL ist ein flexibles Authentifizierungs-Framework und unterstützt mehrere Mechanismen, wodurch sich unterschiedliche Authentifizierungsanbieter einbinden lassen. Weitere SASL-Modi schauen wir uns in späteren Beiträgen dieser Serie an.

Deployment
Bei SASL Plaintext werden Benutzer und Passwörter direkt in der Kafka-Konfiguration gespeichert.

Konfigurations-Properties
Schauen wir uns an, welche Konfigurations-Properties wir anpassen müssen, um die SASL-Plaintext-Authentifizierung zu aktivieren.
advertised.listeners:PLAINTEXT://kafka:9092,SASL_PLAINTEXT://kafka:9095
(Doku) Zuerst aktivieren wir einen neuen Listener auf Port 9095, auf dem «Simple Authentication and Security Layer (SASL)» aktiv ist.security.inter.broker.protocol:SASL_PLAINTEXT
(Doku) Auch die Broker würden untereinander per SASL-Authentifizierung im Plaintext kommunizieren. Da wir aber nur einen Broker haben, bewirkt diese Einstellung hier nicht viel.sasl.enabled.mechanisms:PLAIN
(Doku) Aktiviert den Mechanismus Plain für die Passwort-Authentifizierung.ZOOKEEPER_SASL_ENABLED:false
Diese Umgebungsvariable ist spezifisch für das Confluent-Kafka-Image (cp-kafka). Ist sie gesetzt, wird sie beim Start von Kafka in den Kommandozeilenparameter-Dzookeeper.sasl.client=falseübersetzt. So versucht Kafka nicht, bei der Kommunikation mit ZooKeeper SASL-Authentifizierung zu verwenden. In diesem Setup läuft ZooKeeper ohne Authentifizierung.opts:-Djava.security.auth.login.config=/etc/kafka/configs/kafka_server_jaas.conf -Dzookeeper.sasl.client=false
Die Startoptionen von Kafka. Ich habezookeeper.sasl.client=falsehier noch einmal gesetzt, falls Sie ein anderes Kafka-Docker-Image verwenden. Ausserdem übergeben wir die Konfigurationsdateikafka_server_jaas.conf, in der die Zugangsdaten für die Authentifizierung hinterlegt sind. (Doku)
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="kafka"
password="changeit"
user_kafka="changeit";
};
Wie Sie sehen, ist ein Benutzer kafka mit dem Passwort changeit konfiguriert. Dieses Setup dient ausschliesslich der Authentifizierung am Kafka-Broker. Access Control Lists (ACLs) für die Autorisierung auf Topic-Ebene haben wir noch nicht umgesetzt; die Autorisierung konfigurieren wir in einem späteren Schritt.
KafkaUI
KafkaUI hat jetzt einige zusätzliche Properties, damit es sich am Kafka-Broker authentifizieren kann. Sehen Sie sich dazu den Abschnitt kafka-ui in der docker-compose.yml an.
version: "3.8"
services:
zookeeper:
image: "${ZOOKEEPER_IMAGE}"
container_name: zookeeper
restart: always
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ZOOKEEPER_MAX_CLIENT_CNXNS: 60
KAFKA_HEAP_OPTS: "-Xms512M -Xmx1024M"
ports:
- "2181:2181"
networks:
- kafka
kafka:
image: "${KAFKA_IMAGE}"
container_name: kafka
restart: always
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 100
KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092,SASL_PLAINTEXT://kafka:9095"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "PLAINTEXT:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT"
KAFKA_SECURITY_INTER_BROKER_PROTOCOL: SASL_PLAINTEXT
KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/configs/kafka_server_jaas.conf -Dzookeeper.sasl.client=false"
KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT_MS: 30000
ZOOKEEPER_SASL_ENABLED: "false"
ports:
- "9092:9092"
- "9095:9095"
volumes:
- "./kafka_config:/etc/kafka/configs"
networks:
- kafka
kafka-ui:
image: "${KAFKA_UI_IMAGE}"
container_name: kafka-ui
restart: always
depends_on:
- kafka
ports:
- "8089:8080"
environment:
KAFKA_CLUSTERS_0_NAME: local
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9095
KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL: SASL_PLAINTEXT
KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM: PLAIN
KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG: 'org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="changeit";'
networks:
- kafka
networks:
kafka:
driver: bridge
Kafka-Deployment mit SASL-Plaintext-Authentifizierung
Testen
Wie schon in Teil 1 empfohlen, lohnt es sich sehr, mit der Kafka UI zu experimentieren. Der Verbindungsstatus wird grün angezeigt, das Setup funktioniert also.
Zudem kann sich unsere Test-Applikation jetzt auch per SASL/PLAIN authentifizieren. In diesem Setup ist Kafka SASL auf Port 9095 erreichbar, und die Test-Applikation hat erfolgreich eine Verbindung aufgebaut. Das bestätigt unsere Authentifizierungskonfiguration zusätzlich.

Eine gute Methode, um zu prüfen, ob SASL/PLAIN korrekt konfiguriert ist, ist ein Test mit falschen Zugangsdaten. Bei einem falschen Passwort verweigert Kafka die Verbindung zu Recht. Ebenso wird die Verbindung abgelehnt, wenn die Authentifizierung auf "none" gesetzt und damit deaktiviert wird.

Werfen Sie während eines Verbindungsversuchs auch einen Blick in die Logs des Kafka-Containers:
docker logs kafka -fLogs des Kafka-Containers prüfen

Damit ist bestätigt, dass die SASL/PLAIN-Authentifizierung wie erwartet durchgesetzt wird: Unser Setup funktioniert!
Damit schliessen wir diesen Teil der Blogserie ab. In Teil 3 verlassen wir das Einzelinstanz-Deployment und bauen einen Kafka-Cluster mit drei Nodes auf. Ausserdem nutzen wir SSL (TLS) für die Authentifizierung und führen Zugriffskontrolle (ACL) ein, um die Sicherheit zu erhöhen. Bleiben Sie dran!