如何在群组配置中保持主机重启后的kafka主题

时间:2019-09-20 16:14:21

标签: docker apache-kafka docker-swarm

我正在使用wurstmeister/kafka-docker,并遵循kafka-docker Wiki中的swarm配置。按照一般的docker指令,我添加了一个卷。如果您未在start-kafka.shexport KAFKA_LOG_DIRS="/kafka/kafka-logs-$HOSTNAME"中进行显式设置,我发现kafka日志目录部分由$ HOSTNAME(我相信是该网络中的容器ID)定义。由于$ HOSTNAME在两次重新启动之间发生更改,因此不会找到以前的日志(可能应该使用HOSTNAME_COMMAND?),因此会发生更改。由于每个主机仅运行一个kafka,因此将其设置为静态值。所以我生成的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服务中对其进行引用。

我将堆栈部署到具有三个在docker-machine上运行的节点的集群:dar0,dar1,dar2。我还有一个用于测试的默认默认虚拟机。我用以下方法测试连接性:

docker run -i --network host confluentinc/cp-kafkacat kafkacat -b dar0:9094,dar1:9094,dar2:9094  -t test  -P

在一个外壳中,并且:

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。

但是,如果我关闭了vms,然后重新启动:

$ 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(这有点脆弱,但可以完成工作)。似乎可以正常工作,但不能解决客户端重新启动后看不到数据的问题。

1 个答案:

答案 0 :(得分:0)

经过一些实验,我发现与Zookeeper结合BROKER_ID_COMMAND添加卷似乎可以解决问题。

如果我删除了任何一个,则无法正常工作。我还向zookeeper中添加了kafka的depends_on,但我不确定这是必不可少的。

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]\+\)/\1/''`}}'
    ...
    depends_on:
      - zookeeper
volumes:
   ...
   zookeeperconf:
   zookeeperdata:

这是我在原始帖子中显示的配置的补充。