如何在 swarm 配置中保留主机重启后的 kafka 主题
How to persist kafka topics beyond host restart in swarm configuration
我正在使用 wurstmeister/kafka-docker, and following the swarm configuration in the kafka-docker wiki. Following the general docker instructions, I've added a volume. I discovered that the kafka log dirs is defined in part by the $HOSTNAME (which is the container id, in this network, I believe) if you don't explicitly set it in start-kafka.sh:export KAFKA_LOG_DIRS="/kafka/kafka-logs-$HOSTNAME"
。由于 $HOSTNAME 在重新启动之间发生变化,它不会找到以前的日志(这可能应该使用 HOSTNAME_COMMAND?)这会改变 因为每个主机只有一个 kafka 运行ning,我将它设置为静态值.所以我的结果 docker-compose-swarm.yml 看起来像:
version: '3.2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
kafka:
image: wurstmeister/kafka:latest
ports:
- target: 9094
published: 9094
protocol: tcp
mode: host
environment:
HOSTNAME_COMMAND: "docker info | grep ^Name: | cut -d' ' -f 2"
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://_{HOSTNAME_COMMAND}:9094
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9094
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
# $HOSTNAME (container ID?) is used by default, that changes, so this, for now:
KAFKA_LOG_DIRS: "/kafka/kafka-logs/aaa"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- kafkamount:/kafka
volumes:
kafkamount:
基本上,我添加了 KAFKA_LOG_DIRS,添加了 kafkamount: 命名卷并在 kafka 服务中引用它。
我将堆栈部署到具有三个节点 运行ning 的集群 docker-machine:dar0、dar1、dar2。我还有第四个默认的虚拟机,用于测试。我测试连接:
docker run -i --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -t test -P
在一个 shell 中,并且:
docker run --tty --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -C -t test
一切正常,我可以看到数据正在进入 /var/lib/docker/volumes/darstack_kafkamount/_data/kafka-logs/aaa。
但是,如果我关闭虚拟机然后重新启动:
$ docker-machine stop dar0 dar1 dar2
...
$ docker-machine start dar0 dar1 dar2
我通常会遇到这个错误:
$ docker run --tty --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -C -t test
% ERROR: Topic test error: Broker: Leader not available
主题中没有数据。如果我再次 运行 它,它有时会起作用,并且我得到了主题中的数据。但有时什么也没有。
这可能是因为代理 ID 的分配不同,具体取决于哪个实例先启动?或者我是否还需要为 zookeeper 添加卷? (我还没有看到有人提到这一点。)还有别的吗?
编辑:
为了消除与经纪人 ID 有关的可能性,我添加了一个 BROKER_ID_COMMAND:
BROKER_ID_COMMAND: "docker info -f '{{`{{.Swarm.NodeAddr}}`}}' | sed 's/.*\.\([0-9]\+\)/\1/'"
这使用 IP 的最后一部分作为代理 ID(这有点脆弱,但可以完成工作)。似乎有效,但没有解决客户端在重启后看不到数据的问题。
经过一些试验后,我发现为 zookeeper 添加卷并结合 BROKER_ID_COMMAND 似乎可以解决问题。
如果我删除其中任何一个,它都不起作用。我还为 kafka 添加了一个 depends_on 到 zookeeper,但我不确定这是必要的。
services:
zookeeper:
...
volumes:
- zookeeperconf:/opt/zookeeper-3.4.13/conf
- zookeeperdata:/opt/zookeeper-3.4.13/data
...
kafka:
...
environment:
...
BROKER_ID_COMMAND: '{{`docker info -f ''{{.Swarm.NodeAddr}}'' | sed ''s/.*\.\([0-9]\+\)//''`}}'
...
depends_on:
- zookeeper
volumes:
...
zookeeperconf:
zookeeperdata:
这是我在原始 post 中显示的配置的补充。
我正在使用 wurstmeister/kafka-docker, and following the swarm configuration in the kafka-docker wiki. Following the general docker instructions, I've added a volume. I discovered that the kafka log dirs is defined in part by the $HOSTNAME (which is the container id, in this network, I believe) if you don't explicitly set it in start-kafka.sh:export KAFKA_LOG_DIRS="/kafka/kafka-logs-$HOSTNAME"
。由于 $HOSTNAME 在重新启动之间发生变化,它不会找到以前的日志(这可能应该使用 HOSTNAME_COMMAND?)这会改变 因为每个主机只有一个 kafka 运行ning,我将它设置为静态值.所以我的结果 docker-compose-swarm.yml 看起来像:
version: '3.2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
kafka:
image: wurstmeister/kafka:latest
ports:
- target: 9094
published: 9094
protocol: tcp
mode: host
environment:
HOSTNAME_COMMAND: "docker info | grep ^Name: | cut -d' ' -f 2"
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://_{HOSTNAME_COMMAND}:9094
KAFKA_LISTENERS: INSIDE://:9092,OUTSIDE://:9094
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
# $HOSTNAME (container ID?) is used by default, that changes, so this, for now:
KAFKA_LOG_DIRS: "/kafka/kafka-logs/aaa"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- kafkamount:/kafka
volumes:
kafkamount:
基本上,我添加了 KAFKA_LOG_DIRS,添加了 kafkamount: 命名卷并在 kafka 服务中引用它。
我将堆栈部署到具有三个节点 运行ning 的集群 docker-machine:dar0、dar1、dar2。我还有第四个默认的虚拟机,用于测试。我测试连接:
docker run -i --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -t test -P
在一个 shell 中,并且:
docker run --tty --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -C -t test
一切正常,我可以看到数据正在进入 /var/lib/docker/volumes/darstack_kafkamount/_data/kafka-logs/aaa。
但是,如果我关闭虚拟机然后重新启动:
$ docker-machine stop dar0 dar1 dar2
...
$ docker-machine start dar0 dar1 dar2
我通常会遇到这个错误:
$ docker run --tty --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094 -C -t test
% ERROR: Topic test error: Broker: Leader not available
主题中没有数据。如果我再次 运行 它,它有时会起作用,并且我得到了主题中的数据。但有时什么也没有。
这可能是因为代理 ID 的分配不同,具体取决于哪个实例先启动?或者我是否还需要为 zookeeper 添加卷? (我还没有看到有人提到这一点。)还有别的吗?
编辑: 为了消除与经纪人 ID 有关的可能性,我添加了一个 BROKER_ID_COMMAND:
BROKER_ID_COMMAND: "docker info -f '{{`{{.Swarm.NodeAddr}}`}}' | sed 's/.*\.\([0-9]\+\)/\1/'"
这使用 IP 的最后一部分作为代理 ID(这有点脆弱,但可以完成工作)。似乎有效,但没有解决客户端在重启后看不到数据的问题。
经过一些试验后,我发现为 zookeeper 添加卷并结合 BROKER_ID_COMMAND 似乎可以解决问题。
如果我删除其中任何一个,它都不起作用。我还为 kafka 添加了一个 depends_on 到 zookeeper,但我不确定这是必要的。
services:
zookeeper:
...
volumes:
- zookeeperconf:/opt/zookeeper-3.4.13/conf
- zookeeperdata:/opt/zookeeper-3.4.13/data
...
kafka:
...
environment:
...
BROKER_ID_COMMAND: '{{`docker info -f ''{{.Swarm.NodeAddr}}'' | sed ''s/.*\.\([0-9]\+\)//''`}}'
...
depends_on:
- zookeeper
volumes:
...
zookeeperconf:
zookeeperdata:
这是我在原始 post 中显示的配置的补充。