【问题标题】:How to persist kafka topics beyond host restart in swarm configuration如何在集群配置中将 kafka 主题持久化到主机重启之外
【发布时间】:2019-09-20 16:14:21
【问题描述】:

我正在使用 wurstmeister/kafka-docker,并遵循 kafka-docker wiki 中的 swarm 配置。按照一般 docker 说明,我添加了一个卷。我发现如果您没有在start-kafka.sh:export 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。

但是,如果我关闭虚拟机然后重新启动:

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

【问题讨论】:

    标签: docker apache-kafka docker-swarm


    【解决方案1】:

    经过一些试验,我发现为 zookeeper 添加卷以及 BROKER_ID_COMMAND 似乎可以解决问题。

    如果我删除了任何一个,它都不起作用。我还为动物园管理员添加了一个 kafka 的依赖项,但我不确定这是否必不可少。

    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:
    

    这是我在原帖中展示的配置的补充。

    【讨论】:

    • 使用 BROKER_ID_COMMAND,给出错误 - org.apache.kafka.common.config.ConfigException:配置 broker.id 的值无效:不是 INT 类型的数字
    猜你喜欢
    • 2019-05-20
    • 2015-02-21
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2021-12-04
    • 2020-04-12
    • 1970-01-01
    • 2021-02-03
    相关资源
    最近更新 更多