KafkaのこのDockerイメージを見つけました
https://hub.docker.com/r/spotify/kafka/
リンクに記載されているコマンドを使用して、Dockerコンテナを簡単に作成できます
docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_Host=`boot2docker ip` --env ADVERTISED_PORT=9092 spotify/kafka
これはいい。しかし、Docker群で実行される「複数の」ノードKafkaクラスターを構成したいと思います。
どうやってやるの?
2017年11月28日編集:
Kafkaはlistener.security.protocol.map
を config に追加しました。これにより、クラスターの内部と外部のどちらにいるかに応じて異なるリスナーアドレスとプロトコルを設定でき、Dockerで発生する負荷分散やIP変換によってKafkaが混乱するのを防ぎます。 Wurstmeisterには、動作するDockerイメージ と例 ここにファイルを作成 があります。しばらく前に、いくつかのDockerマシンノードを群れとして設定してこれを試しましたが、機能しているようです。
tbhですが、オーバーレイネットワークにKafkaイメージをアタッチし、今すぐ操作したいときはいつでもKafkaコンソールコマンドを実行します。
お役に立てば幸いです
DockerSwarmモードを使用してDocker1.12でこれを試しています
ノードを作成する
docker-machine create -d virtualbox master
docker-machine create -d virtualbox slave
master_config=$(docker-machine config master | tr -d '\"')
slave_config=$(docker-machine config slave | tr -d '\"')
master_ip=$(docker-machine ip master)
docker $master_config swarm init --advertise-addr $master_ip --listen-addr $master_ip:2377
worker_token=$(docker $master_config swarm join-token worker -q)
docker $slave_config swarm join --token $worker_token $master_ip:2377
eval $(docker-machine env master)
動物園管理サービスを作成する
docker service create --name zookeeper \
--constraint 'node.role == manager' \
-p 2181:2181 \
wurstmeister/zookeeper
kafkaサービスを作成します
docker service create --name kafka \
--mode global \
-e 'KAFKA_PORT=9092' \
-e 'KAFKA_ADVERTISED_PORT=9092' \
-e 'KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092' \
-e 'KAFKA_ZOOKEEPER_CONNECT=tasks.zookeeper:2181' \
-e "HOSTNAME_COMMAND=ip r | awk '{ ip[\$3] = \$NF } END { print ( ip[\"eth0\"] ) }'" \
--publish '9092:9092' \
wurstmeister/kafka
何らかの理由で、これは入力またはユーザー定義のオーバーレイネットワーク内からのみ機能し、ゲストマシンのいずれかを介して接続しようとすると、接続がKafkaに切断されます。
アドバタイズされたIPを変更しても、状況は改善されません...
docker service create --name kafka \
--mode global \
-e 'KAFKA_PORT=9092' \
-e 'KAFKA_ADVERTISED_PORT=9092' \
-e 'KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092' \
-e 'KAFKA_ZOOKEEPER_CONNECT=tasks.zookeeper:2181' \
-e 'KAFKA_LOG_DIRS=/kafka/kafka-logs' \
-e "HOSTNAME_COMMAND=curl 192.168.99.1:5000" \
--publish '9092:9092' \
wurstmeister/kafka
Dockerの新しいメッシュネットワークと負荷分散がKafka接続に何らかの形で干渉している可能性があると思います。
ホストコンテナを取得するために、ローカルで実行されているflaskアプリがあります。
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/')
def hello_world():
return request.remote_addr
前のアプローチはいくつかの質問を提起します:
#kafka configs echo "broker.id=${ID} advertised.Host.name=${NAME} zookeeper.connect=${ZOOKEEPERS}" >> /opt/kafka/config/server.properties
オーバーレイネットワークではすべてが解決可能である必要があります。
さらに、この問題では ルートメッシュネットワークのためにKafkaサービスを作成してポートを公開できませんingress
を使用しないというコメントがあります通信網。
docker compose with swarm を使用してサービスを指定するのが最善のオプションだと思います。例を挙げて答えを編集します。
考慮すべき2つの懸念事項があります。ネットワークとストレージです。
Kafkaはステートフルサービスであるため、 クラウドネイティブストレージ が把握されるまで、グローバルデプロイメントモードを使用することをお勧めします。つまり、制約を満たす各スウォームノードには1つの=があります。 kafkaコンテナ。
もう1つの推奨事項は、公開ポートにHost
モードを使用することです。
各kafkaブローカーが実行中のホストを認識できるように、アドバタイズされたリスナーオプションを適切に設定することも重要です。swarmサービステンプレートを使用して、実際のホスト名を自動的に提供します。
また、公開されたポートがターゲットポートと異なることを確認してください。
kafka:
image: debezium/kafka:0.8
volumes:
- ./kafka:/kafka/data
environment:
- ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_MAX_MESSAGE_BYTES=20000000
- KAFKA_MESSAGE_MAX_BYTES=20000000
- KAFKA_CLEANUP_POLICY=compact
- LISTENERS=PLAINTEXT://:9092
- BROKER_ID=-1
- ADVERTISED_LISTENERS=PLAINTEXT://{{.Node.Hostname}}:11092
depends_on:
- zookeeper
deploy:
mode: global
ports:
- target: 9092
published: 11092
protocol: tcp
mode: Host
networks:
- kafka
現在、すべてのオプションを説明することはできませんが、機能するのは構成です。
server.propertiesでbroker.id = -1を設定して、kafkaがブローカーIDを自動生成できるようにします。Swarmモードで役立ちます。