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

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-Verschlüsselung, 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.
Enterprise-Authentifizierung
Unternehmen möchten Benutzerkonten und Berechtigungen nicht in jedem einzelnen System separat verwalten. Stattdessen binden sie einen Identity Provider (IdP) an, um Authentifizierung und Autorisierung zu zentralisieren.
In dieser Anleitung zeige ich, wie ich Keycloak als Identity Provider für einen Apache-Kafka-Cluster konfiguriert habe. Selbstverständlich können Sie bei Bedarf einen anderen IdP verwenden. Mit Keycloak lassen sich Authentifizierung und Autorisierung in Kafka effizient verwalten, und die Zugriffskontrolle bleibt sicher.

Wird Apache Kafka an einen Identity Provider (IdP) wie Keycloak angebunden, kommt für die OAuth-2.0-Authentifizierung typischerweise der Client Credentials Flow zum Einsatz. Der Ablauf der Authentifizierung:
- Client-Authentifizierung:
Der Client, der sich mit Kafka verbinden will, authentifiziert sich zuerst mit seinen Client Credentials (Client-ID und Secret) beim OAuth-2.0-Server. - Access Token abrufen:
Nach erfolgreicher Authentifizierung stellt der OAuth-2.0-Server ein Access Token aus. Dieses Token enthält den Subject-Namen (sub) (z. B."client-1") und eine Liste von Berechtigungen (Scopes oder Permissions). - Verbindung zu Kafka:
Mit dem Access Token baut der Client anschliessend die Verbindung zum Kafka-Broker auf. - Token-Validierung durch den Kafka-Broker:
Der Kafka-Broker validiert das Token, um seine Echtheit sicherzustellen. In diesem Fall geschieht das über die Prüfung der Token-Signatur. Dazu holt sich der Broker den öffentlichen Schlüssel vom JWKS-Endpunkt (JSON Web Key Set) des Autorisierungsservers. So kann Kafka bestätigen, dass das Token von einem vertrauenswürdigen Identity Provider ausgestellt wurde. - Strimzi Keycloak Authorizer
(Doku) In diesem Setup läuft auf den Brokern der Strimzi Keycloak Authorizer. Er fragt jede Minute beim OAuth-Server die aktuellen Berechtigungen ab.
Im Kern werden Authentifizierung und Autorisierung an einen externen Identity Provider (IdP) wie Keycloak delegiert, statt direkt im Kafka-Cluster verwaltet zu werden. Das zentralisiert das Identitäts- und Zugriffsmanagement: Administratoren steuern Authentifizierung, Autorisierung und Token-Richtlinien direkt in Keycloak.
Übersicht
Mit der Integration der Enterprise-Authentifizierung ist unser Kafka-Deployment gewachsen und etwas komplexer geworden. Die Broker betreiben zwei Ports:
- SSL
19093,29093,39093
Verschlüsselung und SSL-(TLS-)Authentifizierung für die Kommunikation zwischen den Brokern im Cluster. Auch KafkaUI verbindet sich mit diesem internen Port. - SASL_SSL (Oauthbearer)
19092,29092,39092
Dieser Port ist für die Aussenwelt gedacht: Kafka-Clients verbinden sich darüber mit den Brokern und authentifizieren sich per OAuth 2.0.

Vorbereitungen
Bevor wir die Enterprise-Authentifizierung mit OAuth 2.0 in Kafka einrichten, bereiten wir unser «Mise en place» 🍽️ vor, damit alle nötigen Komponenten für eine reibungslose Konfiguration bereitstehen.
Eigenes Kafka-Docker-Image
Apache Kafka® bringt eine grundlegende OAuth2-Unterstützung in Form eines SASL-basierten Authentifizierungsmoduls mit, das den Abruf, den Austausch und die Validierung von Access Tokens als Zugangsdaten zwischen Client und Server übernimmt. Für den Praxiseinsatz braucht es Erweiterungen in Form von JAAS-Callback-Handlern, und genau die liefert Strimzi Kafka OAuth. Deshalb bauen wir uns jetzt ein eigenes Kafka-Image mit den nötigen Strimzi-OAuth-Bibliotheken.
FROM confluentinc/cp-kafka:latest
# Switch to root to install libraries
USER root
# Download and add Strimzi OAuth libraries
RUN curl -L -o /usr/share/java/kafka/strimzi-kafka-oauth-common-0.15.0.jar https://repo1.maven.org/maven2/io/strimzi/kafka-oauth-common/0.15.0/kafka-oauth-common-0.15.0.jar && \
curl -L -o /usr/share/java/kafka/strimzi-kafka-oauth-server-0.15.0.jar https://repo1.maven.org/maven2/io/strimzi/kafka-oauth-server/0.15.0/kafka-oauth-server-0.15.0.jar && \
curl -L -o /usr/share/java/kafka/strimzi-kafka-oauth-client-0.15.0.jar https://repo1.maven.org/maven2/io/strimzi/kafka-oauth-client/0.15.0/kafka-oauth-client-0.15.0.jar && \
curl -L -o /usr/share/java/kafka/kafka-oauth-keycloak-authorizer-0.15.0.jar https://repo1.maven.org/maven2/io/strimzi/kafka-oauth-keycloak-authorizer/0.15.0/kafka-oauth-keycloak-authorizer-0.15.0.jar
# Download and add Nimbus JOSE+JWT library
RUN curl -L -o /usr/share/java/kafka/nimbus-jose-jwt-10.0.1.jar https://repo1.maven.org/maven2/com/nimbusds/nimbus-jose-jwt/10.0.1/nimbus-jose-jwt-10.0.1.jar
# troubleshooting tools install
RUN dnf install -y net-tools
# Switch back to appuser
USER appuserDockerfile – eigenes Kafka-Image mit den Strimzi-OAuth-Bibliotheken

Das Image wurde erfolgreich gebaut und in mein privates Docker-Repository hochgeladen.
Keycloak-Setup
Für diese Blogserie betreibe ich einen Keycloak-Server in einem Docker-Container. Sie können aber jeden anderen Identity Provider Ihrer Wahl verwenden. Keycloak selbst steht in dieser Serie nicht im Mittelpunkt; ich zeige einfach meine Keycloak-Konfiguration, die Authentifizierung und Autorisierung für Kafka übernimmt.
Wir bereiten bereits einige Clients und Berechtigungen vor, die wir später zum Testen verwenden:
- client-1
Einen «client-1» zum Testen angelegt. Aktivieren Sieclient authenticationundauthorization. Kopieren Sie dasclient secretim Tab «Credentials» für später. - client-2
Einen «client-2» zum Testen angelegt. Aktivieren Sieclient authenticationundauthorization. Kopieren Sie dasclient secretim Tab «Credentials» für später. Gleiche Konfiguration wie client-1, nur der Name ist anders. - kafka-broker
Einen Client «kafka-broker» angelegt, damit die Kafka-Broker die Berechtigungen vom Keycloak-Server abrufen können. Auch beim Broker-Client sollteauthorizationaktiviert sein. Notieren Sie sich ebenfalls dasclient secret. Im Tab «Authorization» habe ich diescopesgemäss der Anleitung des Strimzi Kafka Keycloak Authorizers konfiguriert (Doku). Danach habe ich einigeresourcesangelegt, je einepolicyvom Typclientfür «client-1» und für «client-2» erstellt und schliesslich diepermissionswie im Bild gezeigt angelegt.





Galerie – Keycloak-Konfiguration
Den Abruf eines Autorisierungstokens habe ich so getestet:
# get authorization token for client-1
curl -X POST \
-d "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&client_id=client-1&client_secret=**********&audience=kafka-broker" \
"https://my-keycloakserver.ch/auth/realms/master/protocol/openid-connect/token"Bash – Autorisierungstoken für client-1 abrufen
Sie können das JWT inspizieren, indem Sie es auf jwt.io einfügen. Das Token sollte jetzt etwa die folgende Struktur haben. Achten Sie besonders auf das Attribut authorization.permissions, denn das verwendet später der Keycloak Authorizer.
In diesem Beispiel gewährt das Token die Berechtigungen Describe, Read, Write und Create für Topics nach dem Muster test*. Unsere Test-Client-Applikation arbeitet konkret mit dem Topic «test-topic».

Kafka-Deployment
KAFKA_ADVERTISED_LISTENERS:SASLSSL://kafka-1:19092,SSL://kafka-1:19093
Dieses Deployment hat zwei Listener: SSL mit Mutual TLS für die interne Nutzung, also die Kommunikation zwischen den Brokern im Cluster und mit kafka-ui, und SASL SSL mit OAuth für die Kommunikation mit externen Clients.KAFKA_INTER_BROKER_LISTENER_NAME:SSL
Die Broker kommunizieren intern nur über SSL (TLS).KAFKA_SASL_MECHANISM:OAUTHBEARER KAFKA_LISTENER_NAME_SASLSSL_SASL_ENABLED_MECHANISMS:OAUTHBEARER
Für die Authentifizierung (und Autorisierung) der Clients verwende ich den SASL-Mechanismus OAUTHBEARER.KAFKA_LISTENER_NAME_SASLSSL_OAUTHBEARER_SASL_SERVER_CALLBACK_HANDLER_CLASS:io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler
Legt den serverseitigen Callback-Handler für die OAuth-2.0-Authentifizierung fest. Mit dieser Klasse (von Strimzi) validiert Kafka die OAuth-Tokens der Clients.KAFKA_LISTENER_NAME_SASLSSL_OAUTHBEARER_SASL_LOGIN_CALLBACK_HANDLER_CLASS:io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
Legt den clientseitigen Callback-Handler für die OAuth-Authentifizierung fest. Kafka-Clients holen sich damit vor dem Verbindungsaufbau ein OAuth-Token.KAFKA_STRIMZI_AUTHORIZATION_TOKEN_ENDPOINT_URI KAFKA_STRIMZI_AUTHORIZATION_CLIENT_ID
Diese Einstellungen verwendet der Strimzi Keycloak Authorizer. Er verbindet sich jede Minute mit dem Token-Endpunkt, um eine aktuelle Liste (ein Token) der Berechtigungen für die aktiven Clients zu holen. Dafür nutzt er seine eigene Client-IDkafka-broker.
Testen
Auch diesmal hat die Test-App ein Update erhalten und kann sich jetzt per OAuth Bearer verbinden und autorisieren. Ich verwende client-1 und das zuvor in Keycloak erzeugte Secret. Die Test-App holt sich bei Keycloak ein Token mit den Berechtigungen, die wir oben im Abschnitt «Keycloak-Setup» definiert haben.

Fazit
Et voilà: Kafka läuft jetzt mit Enterprise-OAuth-2.0 und Keycloak! Das Team von Confluent verdient ein High Five für seine eleganten (wenn auch teuren) Tools. Kafka-Cluster zu skalieren ist allerdings kein Spaziergang, und ich bin nicht sicher, ob wir die automatische Umverteilung der Daten so gut hinbekommen wie sie.
Als Nächstes: Kubernetes auf GKE. Aufsatteln für den Cluster-Ritt!