Apache Kafka en local avec docker-compose

TL; DR:

curl -O https://gist.githubusercontent.com/nfroidure/720e83d6796a7c276f69ec8ad27fd7e9/raw/0bb69bbb8e8d97dd31f5b9dc3655fd6407910480/docker-compose.yml
docker-compose up
    

La data devient le centre de toute innovation, au fil de mes expériences professionnelles, il en est de plus en plus question. C'est donc naturellement que je me suis mis à utiliser le message queuing puis le stream processing.

D'abord avec Kinesis par simplicité, mais ce système ne gère pas les topics et est propriétaire ce qui est gênant pour rester cloud agnostique alors j'ai décidé de passer sous Kafka dans ma nouvelle aventure technologique chez DiagRAMS ;).

Le hic, c'est qu'il n'existe pas d'image Docker officielle, donc aucune documentation sur la façon de l'utiliser, d'où ce petit article qui vous aidera peut-être à éviter de passer trop de temps sur votre setup en local.

Configurer docker-compose

Si, comme moi, vous ne jurez que par docker-compose pour le dev en local, alors voici ma petite recette perso !

Tout d'abord, j'ai choisi d'utiliser les images Docker de Bitnami à défaut d'images officielles (n'hésitez pas à proposer les votre en commentaire).

J'ai également déclaré explicitement le réseau que je souhaite utiliser et ceci pour deux raisons :

  • je souhaite maîtriser les plages IP utilisées par Docker afin d'éviter les collisions avec mes VPC (ce qui m'a causé pas mal de fil à retordre lors du setup de ma connexion VPN...),
  • Apache Kafka utilise un système de diffusion des brokers et pour pouvoir s'y connecter en local, c'est mieux de connaître l'adresse IP de ces derniers pour pouvoir les insérer dans la variable d'environnement KAFKA_ADVERTISED_LISTENERS prévue à cet effet.

Le résultat est le suivant :

Vous pouvez ajouter plus de brokers, il suffira alors d'adapter les variables d'environnement, mais en local, c'est rarement utile.

Se connecter avec Kafdrop

On peut ajouter l'UI de Kafdrop directement au docker-compose, mais c'est quelquechose que j'évite pour ne pas avoir un environnement de développement trop gourmand en RAM.

De plus, ça peut être bien de pouvoir, sélectivement, démarrer Kafdrop pour le Kafka local, mais aussi pour voir ce qu'il se passe sur le Kafka de production.

Pour toutes ces raisons, et aussi car c'est plus écologique, je démarre directement Kafdrop quand j'en ai besoin via la ligne de commande :

  docker run --rm -p 9000:9000 \
  -e KAFKA_BROKERCONNECT="10.5.0.1:9092" \
  -e JVM_OPTS="-Xms32M -Xmx256M" --network myapp \
  -e SERVER_SERVLET_CONTEXTPATH="/" \
  obsidiandynamics/kafdrop:latest

Notez bien le --network myapp qui permet à Kafdrop d'être sur le même réseau que le reste.

Je vous mets également la commande pour la production car cette dernière est sûrement en SSL et vous devrez donc y ajouter un peu de config comme suit :

  docker run --rm -p 9000:9000 \
  -e KAFKA_BROKERCONNECT=$(node -e "process.stdout.write($(terraform output kafka_bootstrap_brokers))") \
  -e JVM_OPTS="-Xms128M -Xmx2G" -e KAFKA_PROPERTIES=$(echo security.protocol=SSL | base64) \
  -e SERVER_SERVLET_CONTEXTPATH="/" \
  obsidiandynamics/kafdrop:latest

Comme vous pouvez le voir, je récupère directement les brokers Kafka depuis mes states Terraform. Libre à vous d'en faire autant ou de les mettre à la main.

Utiliser les scripts Kafka

En lisant la documentation de Kafka, vous devrez probablement utiliser les scripts mis à disposition par Kafka, voici, par exemple, comment créer un topic avec docker-compose.

docker-compose exec kafka /opt/bitnami/kafka/bin/kafka-topics.sh \
  --create \
  --bootstrap-server localhost:9092 \
  --replication-factor 1 \
  --partitions 1 \
  --topic users

La liste des commandes s'obtient facilement ainsi

docker-compose exec kafka ls /opt/bitnami/kafka/bin

Kafka est une technologie sympa, je pense qu'elle est en revanche mal comprise, ce n'est qu'un système de gestion d'évènements, pas l'alpha et l'omega de la gestion massive de données.

Enfin, en terme de documentation, tous les chemins mènent à Confluent et je trouve cela regrettable qu'il n'y ait pas plus de documentation indépendante, d'où cet article, car l'intérêt d'utiliser du libre est limité si on depend d'un seul acteur cloud. Bref, j'attends vos retours d'expérience également ;).