目次
はじめに
grasysの新井です。
直近の案件でkafkaを触る機会があったので、dockerでどうやって動かすのかをまとめてみました。
対象読者
- kafkaを初めて触る人
- dockerでkafkaを動かしてみたい人
構成図

- producer
topicへデータを追加するクライアント。 - consumer
topicからデータを取得するクライアント。 - broker
実際にtopicに追加されたデータが格納されているノード。 - topic
データ保管先、受信先を表すカテゴリ名。 - partition
topicに対するメッセージを処理する単位。 - controller
kafkaクラスタを管理するノード。
brokerとは違いユーザデータは持たない。
環境
- mac
- docker, docker compose
❯ docker -v
Docker version 28.1.1, build 4eba377
❯ docker compose version
Docker Compose version v2.35.1-desktop.1
事前準備
- docker composeで使用するcompose.yamlを用意する
services:
controller-1:
image: apache/kafka:4.0.0-rc4
container_name: controller-1
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
controller-2:
image: apache/kafka:4.0.0-rc4
container_name: controller-2
environment:
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
controller-3:
image: apache/kafka:4.0.0-rc4
container_name: controller-3
environment:
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
broker-1:
image: apache/kafka:4.0.0-rc4
container_name: broker-1
ports:
- 29092:9092
environment:
KAFKA_NODE_ID: 4
KAFKA_PROCESS_ROLES: broker
KAFKA_LISTENERS: 'PLAINTEXT://:19092,PLAINTEXT_HOST://:9092'
KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://broker-1:19092,PLAINTEXT_HOST://localhost:29092'
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
depends_on:
- controller-1
- controller-2
- controller-3
broker-2:
image: apache/kafka:4.0.0-rc4
container_name: broker-2
ports:
- 39092:9092
environment:
KAFKA_NODE_ID: 5
KAFKA_PROCESS_ROLES: broker
KAFKA_LISTENERS: 'PLAINTEXT://:19092,PLAINTEXT_HOST://:9092'
KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://broker-2:19092,PLAINTEXT_HOST://localhost:39092'
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
depends_on:
- controller-1
- controller-2
- controller-3
broker-3:
image: apache/kafka:4.0.0-rc4
container_name: broker-3
ports:
- 49092:9092
environment:
KAFKA_NODE_ID: 6
KAFKA_PROCESS_ROLES: broker
KAFKA_LISTENERS: 'PLAINTEXT://:19092,PLAINTEXT_HOST://:9092'
KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://broker-3:19092,PLAINTEXT_HOST://localhost:49092'
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
depends_on:
- controller-1
- controller-2
- controller-3
ハンズオン
1、コンテナを立ち上げる
$ docker compose up -d
broker: 3, controller: 3のコンテナが起動している
$ docker compose ps
2、topicを作成してみる
まずはtopicがないことをkcatで確認する
$ docker compose exec broker-1 /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--list
topicを作成する
$ docker compose exec broker-1 /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--create \
--topic my-test-topic \
--partitions 3 \
--replication-factor 3
–partitions:
topic内に作成するpartition数を指定できる。(この場合3つのpartitionが作成される)
–replication-factor:
leader partition含めて、いくつのpartitionの複製を作成するか指定している。(この場合3つreplicaが作成される)
注意: replicaはbroker数より多く作成することはできない。
(今回の場合4以上は作成することができない。)

作成されたtopicを確認する
$ docker compose exec broker-1 /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--list
my-test-topic
my-test-topicというトピックが作成できている。
$ docker compose exec broker-1 /opt/kafka/bin/kafka-topics.sh \
--describe \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--topic my-test-topic
Topic: my-test-topic TopicId: dbdyZPl9Q4uV2YApDyhkmw PartitionCount: 3 ReplicationFactor: 3 Configs:
Topic: my-test-topic Partition: 0 Leader: 6 Replicas: 6,4,5 Isr: 6,4,5 Elr: LastKnownElr:
Topic: my-test-topic Partition: 1 Leader: 4 Replicas: 4,5,6 Isr: 4,5,6 Elr: LastKnownElr:
Topic: my-test-topic Partition: 2 Leader: 5 Replicas: 5,6,4 Isr: 5,6,4 Elr: LastKnownElr:
partition:
実際に作成されたパーティションが表示されている。
0始まりでインクリメントされていく。
leader:
リーダーパーティションが表示されている。
producerからtopicへpublish(追加)されたデータは、このパーティションに追加され、follow replicaに複製される。
またこのパーティションからconsumerはデータをsubscribe(取得)する。
Replicas:
リーダーパーティションを含めた複製パーティションが表示されている。
Isr:
In-Sync-Replicaが表示されている。
leader partitionと同期が取られているfollow replicaがわかる。
(今回の場合、全てのfollow replicaで同期が取られている。)
Elr:
Excluded Replicas(除外されたレプリカ)が表示される。
一時的な同期遅延でISRから除外されたレプリカなど。
LastKnownElr:
最後に認識された除外されたレプリカが表示される。
3、kafkaコマンドでsubscribeできる状態にしてみる
kafkaコマンドでsubscribeする
$ docker compose exec broker-1 /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--topic my-test-topic
まだtopicにデータが追加されていないため、何も表示されない。
4、topicへデータを追加してみる
ターミナルの別windowでproducerを立ち上げる
$ docker compose exec broker-1 /opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--topic my-test-topic
topicへデータを追加してみる。
# producer
❯ docker compose exec broker-1 /opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--topic my-test-topic
>fdsafsa
>fdsafdsa
>fdsa
>fdsa
>fdsadfsaf
>dsa
# consumer
❯ docker compose exec broker-1 /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server broker-1:19092,broker-2:19092,broker-3:19092 \
--topic my-test-topic
fdsafsa
fdsafdsa
fdsa
fdsa
fdsadfsaf
すると、topicからconsumerが追加されたデータを取得して表示されるのがわかる。
終わりに
今回はkafkaをdockerで動かす方法をまとめてみました。
これ以外にも、Commit Offsetの仕組みやkafka exporterやJMXでのメトリクス表示、上記以外のkafkaコマンド、apache pulsarやRabbitMQなどとの違い、kafka管理部分であるzoo keeperとkraftの違い、kafka uiなどのGUIベースでの表示/操作方法、kafka stream、strimziでのk8s上での運用方法などなどまだまだ気になることはたくさんあります!
今後はこのあたりも随時調べていければと思います。

