基于docker swarm构建多节点kafka集群

j9per5c4  于 2021-06-07  发布在  Kafka
关注(0)|答案(4)|浏览(497)

我为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 swarm上运行的“多”节点kafka集群。
我该怎么做?

ckocjqey

ckocjqey1#

在server.properties中设置broker.id=-1以允许kafka自动生成broker id。在swarm模式下很有用。

fnvucqvd

fnvucqvd2#

编辑:28/11/2017:
Kafka补充道 listener.security.protocol.map 他们的配置。这允许您根据您在集群内还是集群外设置不同的侦听器地址和协议,并防止kafka被docker中发生的任何负载平衡或ip转换所迷惑。wurstmeister在这里有一个工作的docker图像和示例合成文件。我尝试了这一点,一段时间前与几个码头机节点设置为一个群体,它似乎工作。
tbh虽然我只是附加了一个Kafka图像覆盖网络和运行Kafka控制台命令时,我想与它现在互动。
希望有帮助

下面的旧东西

我一直在尝试Docker1.12使用DockerSwarm模式
创建节点

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)

创建zookeeper服务

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中新的mesh网络和负载平衡可能会干扰kafka连接。。。。
为了获得主机容器,我在本地运行了一个flask应用程序

from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/')
def hello_world():
    return request.remote_addr
b4lqfgs4

b4lqfgs43#

需要考虑两个问题:网络和存储。
因为kafka是有状态的服务,所以在云本地存储解决之前,最好使用全局部署模式。即每个满足约束的群节点都有一个kafka容器。
另一个建议是使用 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

我现在不能解释所有的选项,但它的配置工作。

nfs0ujit

nfs0ujit4#

前面的方法提出了一些问题:
如何指定zookeeper节点的id?
如何指定kafka节点和zookeeper节点的id? #kafka configs echo "broker.id=${ID} advertised.host.name=${NAME} zookeeper.connect=${ZOOKEEPERS}" >> /opt/kafka/config/server.properties 覆盖网络中的一切都应该是可解决的。
此外,在问题中不能创建一个kafka服务和发布端口,因为路由mesh网络有一个注解不使用 ingress 网络。
我认为最好的选择是使用docker compose和swarm来指定您的服务。我将用一个例子来编辑答案。

相关问题