EC2 で Docker を立ち上げ、上記の構成で下記を構築します。
- Kafka cluster (Broker × 3, ZooKeeper × 3)
- Kafka client (Producer × 1, Consumer × 1)
- Kafka UI
検証した環境は以下です。
- AMI: Amazon Linux 2023
- インスタンスタイプ: t2.xlarge
- ボリュームサイズ: 20 (GiB)
- ルートボリューム: gp3
- Docker: 20.10.25
- Docker Compose: v2.4.1
【手順】
- マネージメントコンソール画面から EC2 インスタンスを起動
(Kafka cluster を構築するため、大きめのインスタンスタイプとストレージがおすすめ)
AMI: Amazon Linux 2023
インスタンスタイプ: t2.xlarge
ボリュームサイズ: 20 (GiB)
ルートボリューム: gp3
- EC2 インスタンスの SSH 接続
chmod 400 <your key>.pem
ssh -i "<your key>.pem" ec2-user@<your ec2 ip>.ap-northeast-1.compute.amazonaws.com
- EC2 のパッケージの更新
sudo yum update -y
【手順】
- Docker のインストール
sudo yum install -y docker
- バージョンの確認
docker --version
>>> Docker version 20.10.25, build b82b9f3
【手順】
- ディレクトリの作成
sudo mkdir -p /usr/local/lib/docker/cli-plugins
- ファイルのダウンロード
VER=2.4.1
sudo curl -L https://github.com/docker/compose/releases/download/v${VER}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
- シンボリックリンクを設定
sudo ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/bin/docker-compose
- バージョンの確認
docker-compose --version
>>> Docker Compose version v2.4.1
【手順】
- Docker daemon の起動
sudo service docker start
- 現在ログインしているユーザーをdockerグループへ追加
sudo gpasswd -a $(whoami) docker
- docker.sock にグループでの書き込み権限を付与
sudo chgrp docker /var/run/docker.sock
- docker daemonを再起動
sudo service docker restart
- EC2 の SSH 接続をログアウト & 再度ログインで sudo なしで docker コマンドを実行可能
【手順】
- git のインストール
sudo yum install git -y
- GitHub のリポジトリを clone
git clone https://github.com/SeongHaedu/Apache-Kafka-on-EC2.git
cd Apache-Kafka-on-EC2
【手順】
- docker-compose の実行
複数のコンテナを立ち上げ、複数のサーバーが同一ネットワークにいる環境を仮想的に作成
docker compose up -d
- 各々のコンテナの IP address の確認
私の実行環境では以下のような IP address が割り振られた
docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }} {{range .NetworkSettings.Networks}} {{.IPAddress}}{{end}}' | sed 's#^/##' | sort -k 2
>>>broker-1 172.18.0.2
>>>broker-2 172.18.0.3
>>>broker-3 172.18.0.4
>>>kafka-ui 172.18.0.5
>>>producer 172.18.0.6
>>>consumer 172.18.0.7
※ 以降の作業は複数のターミナルで EC2 インスタンスへログインしての作業をおすすめします
(3 つの Broker、1 つの Kafka ui、Producer、Consumer、および SSH tunnel 用として合計 7 つのターミナルを立ち上げておくと楽でした)
kafka
とclient
の直下の各々のディレクトリに存在する、.env.template
を.env
ファイルとしてコピーして保存する。
$ tree -a ./kafka
kafka
├── broker-1
│ ├── .env
│ ├── .env.template
│ ├── compose.kafka.yml
│ └── compose.zookeeper.yml
├── broker-2
│ ├── .env
│ ├── .env.template
│ ├── compose.kafka.yml
│ └── compose.zookeeper.yml
├── broker-3
│ ├── .env
│ ├── .env.template
│ ├── compose.kafka.yml
│ └── compose.zookeeper.yml
└── ui
├── .env
├── .env.template
├── compose.cmak.yml
...
└── compose.ui.yml
$ tree -a ./client
├── consumer
│ ├── .env
│ ├── .env.template
│ ├── main.py
│ └── requirements.txt
└── producer
├── .env
├── .env.template
├── main.py
└── requirements.txt
.env
ファイルにbroker-1
、brocker-2
、およびbrocker-3
の IP アドレスを反映する
例えば、私の環境の broker-1
では、 .env
ファイルを次のように編集した
BROKER1=172.18.0.2
BROKER2=172.18.0.3
BROKER3=172.18.0.4
ZOOKEEPER_SERVER_ID=1
ZOOKEEPER_SERVERS=zookeeper-1:2888:3888;${BROKER2}:2888:3888;${BROKER3}:2888:3888
KAFKA_BROKER_ID=1
KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://${BROKER1}:9092
KAFKA_ZOOKEEPER_CONNECT=${BROKER1}:2181,${BROKER2}:2181,${BROKER3}:2181
※ BROKER1
、BROKER2
、および BROKER3
以外の記述は、各々の .env ファイルによって異なる
これで準備完了
各々のフォルダは後ほど起動するコンテナにそれぞれ volume がマウントされている
-
Apache Kafka を動作させるには Apache ZooKeeper と接続をします
-
各ホストで Kafka を起動して cluster を構成します
ZooKeeper を broker-1
、broker-2
、broker-3
で起動し、 クラスターを構成する
【手順】
- Broker のコンテナへの接続
ZooKeeper の起動順序は特に指定はない
Broker の各々のコンテナへの接続
例えば、brocker-1
の場合は以下のようにコマンドを実行
docker exec -it broker-1 sh
- ZooKeeper の起動
接続したコンテナで下記のコマンドを実行
docker compose -f ./src/compose.zookeeper.yml up -d
- 上記手順を
broker-2
、broker-3
の各々のコンテナでも実行
Kafka を broker-1
、broker-2
、broker-3
で起動し、cluster を構成する
【手順】
- Broker のコンテナへの接続(ZooKeeper cluster の作成の手順で接続ずみの場合スキップ)
Kafka も同様に起動順序について特に指定はない
Broker の各々のコンテナに入る
例えば、brocker-1
の場合は以下のようにコマンドを実行
docker exec -it broker-1 sh
- Kafka の起動
接続したコンテナで下記のコマンドを実行
docker compose -f ./src/compose.kafka.yml up -d
- 上記手順を
broker-2
、broker-3
の各々のコンテナでも実行
Kafka UI の起動
Kafka の中でも一番使いやすいと言われている Kafka UI を起動します
【手順】
- UI 起動用のコンテナへの接続
docker exec -it kafka-ui sh
- Kafka UI の起動
接続したコンテナで下記のコマンドを実行
docker compose -f ./src/compose.ui.yml up -d
- ローカル PC のターミナルから EC2 インスタンスに SSH tunnel
sudo ssh -L 8888:localhost:8888 -i "<your key>.pem" ec2-user@<your ec2 ip>.ap-northeast-1.compute.amazonaws.com
localhost:8888
へアクセスすると Kafka UI が表示
kafka-python を使って、producer と consumer の client を作成します
左が producer、真ん中が consumer、右が Kafka UI です
Producer が送信した文字列を consumer が受信していることを確認できます
【手順】
- Producer のコンテナへの接続
docker exec -it producer sh
- ライブラリをインストール
pip install -r /src/requirements.txt
- Producer を起動
--bootstrap-servers
の部分は自身の環境の Broker の IP address を記入して実行
python /src/main.py --topic haedu-topic --bootstrap-servers 172.18.0.2:9092,172.18.0.3:9092,172.18.0.4:9092
【手順】
- Consumer のコンテナへの接続
docker exec -it consumer sh
- ライブラリをインストール
pip install -r /src/requirements.txt
- Consumer を起動
--bootstrap-servers
の部分は自身の環境の Broker の IP address を記入して実行
python /src/main.py --topic haedu-topic --bootstrap-servers 172.18.0.2:9092,172.18.0.3:9092,172.18.0.4:9092
demo.mov
-
Producer 側のターミナルで任意の文字列を入力し、Enter で Kafka cluster にメッセージを送信します
-
Consumer 側のターミナルで Kafka cluster のメッセージを読み込み、メッセージが出力されます
-
Kafka UI で、 Kafka cluster に到達したメッセージを確認できます
また、 --group-id
で consumer group ID を指定できます
指定して実行すると Kafka UI の consumer 一覧に表示されるようになります
Q. Producer から Broker へメッセージが届いていない
A. Kafka クラスターが立ち上がっていない可能性、があるので、broker-1
、broker-2
、broker-3
に再度接続し、実行してください
詳細の手順については、ZooKeeper cluster の作成、および Kafka cluster の作成 をご覧ください
Q. Kafka UI に接続できない
A. Kafka UI のコンテナが立ち上がっていない可能性、および SSH tunnel が確立されていない可能性が考えられるので、ご確認ください
全てのコンテナを落とし、EC2 インスタンスを削除して終了です
docker compose down
お疲れ様でした!!