web-dev-qa-db-ja.com

DockerSwarmでマルチノードを構築するKafka cluster

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クラスターを構成したいと思います。

どうやってやるの?

11
Knows Not Much

2017年11月28日編集:

Kafkaはlistener.security.protocol.mapconfig に追加しました。これにより、クラスターの内部と外部のどちらにいるかに応じて異なるリスナーアドレスとプロトコルを設定でき、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
7
Richard Mathie

前のアプローチはいくつかの質問を提起します:

  1. ZookeeperノードのIDを指定するにはどうすればよいですか?
  2. kafkaノードとzookeeperノードのIDを指定するにはどうすればよいですか?

#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
Fabio Fumarola

考慮すべき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

現在、すべてのオプションを説明することはできませんが、機能するのは構成です。

2
Vanuan

server.propertiesでbroker.id = -1を設定して、kafkaがブローカーIDを自動生成できるようにします。Swarmモードで役立ちます。

1
nelson