繁体   English   中英

在docker swarm上构建一个多节点Kafka集群

[英]Build a multi node Kafka cluster on docker swarm

我为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集群。

我怎样才能做到这一点?

编辑28/11/2017:

Kafka将listener.security.protocol.map添加到他们的配置中 这允许您根据您是在群集内部还是在群集外部来设置不同的侦听器地址和协议,并阻止Kafka对docker中发生的任何负载平衡或ip转换感到困惑。 Wurstmeister 在这里 有一个工作的docker图像和示例撰写文件 我试了一会儿,将几个docker机器节点设置为一个群,它似乎工作。

虽然我只是将Kafka图像附加到覆盖网络并运行Kafka控制台命令,但我现在想要与它进行交互。

希望有所帮助


下面的旧东西

我一直在尝试使用docker swarm模式的docker 1.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)

创建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中新的网状网络和负载均衡可能会干扰Kafka连接的一些方式....

为了得到主机容器我有一个本地运行的烧瓶应用程序,我卷曲

from flask import Flask
from flask import request

app = Flask(__name__)

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

之前的方法提出了一些问题:

  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来指定你的服务。 我将用一个例子编辑答案。

在server.properties中设置broker.id = -1以允许kafka自动生成代理ID。 Swarm模式有帮助。

需要考虑两个问题:网络和存储。

由于Kafka是有状态服务,因此在计算出云原生存储之前,建议使用全局部署模式。 也就是说,每个满足约束的swarm节点都有一个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

我现在无法解释所有选项,但它的配置是有效的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM