我的 kafka docker 容器无法连接到我的 zookeeper docker 容器

Posted

技术标签:

【中文标题】我的 kafka docker 容器无法连接到我的 zookeeper docker 容器【英文标题】:My kafka docker container cannot connect to my zookeeper docker container 【发布时间】:2019-10-23 02:43:13 【问题描述】:

我想同时使用 confluent/kafkaconfluent/zookeeper 并在单个 Ubuntu 服务器上运行它们。

我正在使用以下配置:

docker run -e ZOOKEEPER_CLIENT_PORT=2181 --name zookeeper confluent/zookeeper

docker run --name kafka -e KAFKA_ADVERTISED_HOST_NAME=kafka -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 -e KAFKA_CREATE_TOPICS=testtopic:1:1 confluent/kafka

但是这会导致:无法连接到 zookeeper:2181

我想连接其他容器,如何通过 zookeeper:2181 访问 zookeeper 和通过 kafka:9092 访问 kafka?

【问题讨论】:

这两个容器都已弃用。使用 confluentinc/kafka 和 Zookeeper 。另外,请使用 Docker 撰写并阅读此博客rmoff.net/2018/08/02/kafka-listeners-explained 感谢@cricket_007 - 我使用的是 docker compose,但图像开始失败(直到上周才正常工作),所以我一直按照上面的方式运行图像以帮助调试失败容器。我会尝试上面的命令,confluentinc/kafkaconfluentinc/zookeeper 【参考方案1】:

有多种方法可以做到这一点。但在我们调查之前,您需要了解您的方法中有两个问题

当您使用 docker run 时,zookeper 主机无法访问,因为每个容器都在不同的网络隔离中运行 kafka 可能会启动并尝试连接到 zookeeperzookeeper 尚未准备好

解决网络问题

你可以做很多事情来解决问题

使用--net=host 在主机网络上同时运行

使用docker network create <name>,然后在启动两个容器时使用--net=<name>

或者您可以在 zookeeper 容器网络上运行您的 kafka 容器。

在启动 kafka 容器时使用 --net=container:zookeeper。这将确保zookeeper 主机是可访问的。除非您有充分的理由这样做,否则不建议这样做。因为一旦zookeeper 容器出现故障,您的kafka 容器的网络也会出现故障。但是为了便于理解,我把这个选项放在这里

解决启动竞赛问题

您可以在启动zookeeperkafka 之间保持一个间隔,以确保kafka 启动时zookeeper 启动并运行

另一种选择是在 docker run 中使用 --restart=on-failure 标志。这将确保容器在失败时重新启动,并尝试重新连接到zookeeper,希望zookeeper 的时间会到。

而不是使用docker run,我总是更喜欢docker-compose 来运行这样的链接容器。您可以通过创建一个简单的docker-compose.yml 文件然后使用docker-compsoe up 运行它来做到这一点

version: "3.4"
services:
  zookeeper:
    image: confluent/zookeeper
    environment:
      - ZOOKEEPER_CLIENT_PORT=2181
  kafka:
    image: confluent/kafka
    environment:
      - KAFKA_ADVERTISED_HOST_NAME=kafka
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_CREATE_TOPICS=testtopic:1:1
    depends_on:
      - zookeeper
    restart: on-failure

【讨论】:

docker run -e ZOOKEEPER_CLIENT_PORT=2181 --name zookeeper confluent/zookeeper 后跟 docker run --name kafka -e KAFKA_ADVERTISED_HOST_NAME=kafka -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 -e KAFKA_CREATE_TOPICS=testtopic:1:1 --net=container:zookeeper confluent/kafka 不起作用。并显示“无法连接到 zookeeper:2181” 延迟后你做了吗? 是的,我执行了第一个命令,它显示:“INFO binding to port 0.0.0.0/0.0.0.0:2181”,然后等了2分钟,检查它还在运行,然后执行第二个命令。 然后试试localhost:2181 谢谢你的作品!不过,我希望这可以与 zookeeper 一起使用。所以也许有另一个环境变量用于 zookeeper 的adverted_name。【参考方案2】:

虽然我在 Mac 上运行,但它运行良好。由于“主机”网络在 mac 中不起作用,我只需创建一个名为 kafka_net 的网络并将容器放在那里。

version: "3.4"
services:
  zookeeper:
    image: confluent/zookeeper
    environment:
      - ZOOKEEPER_CLIENT_PORT=2181
    networks:
      - kafka_net
  kafka:
    image: confluent/kafka
    environment:
      - KAFKA_ADVERTISED_HOST_NAME=kafka
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    depends_on:
      - zookeeper
    networks:
      - kafka_net
    restart: on-failure
networks:
  kafka_net:
    driver: "bridge"

确保一切正常:

然后登录zookeeper容器

zookeeper-shell localhost:2181 => You should see something like 'Welcome to ZooKeeper!' after all the big chunk of text

然后登录kafka容器

kafka-topics --zookeeper zookeeper:2181 --list # empty list
kafka-topics --zookeeper zookeeper:2181 --create --topic first_topic --replication-factor 1 --partitions 1
kafka-topics --zookeeper zookeeper:2181 --list # you will see the first_topic
kafka-console-producer --broker-list localhost:9092 --topic first_topic # type some text and ctrl + c
kafka-console-consumer --bootstrap-server localhost:9092 --zookeeper zookeeper:2181 --topic first_topic --from-beginning # you will see the stuff you typed first_topic

如果仍然有问题,请查看官方示例。 https://github.com/confluentinc/cp-docker-images/tree/5.2.2-post/examples 并且仍在发布问题,将提供帮助。

【讨论】:

【参考方案3】:

Docker 在隔离网络中启动容器,称为default bridge,除非您明确指定网络。

您可以通过不同的方式取得成功,这里有两种最简单的方法:

    将容器放入同一个用户定义的桥接网络

    # create net
    docker network create foo
    docker run --network=foo -e ZOOKEEPER_CLIENT_PORT=2181 --name zookeeper confluent/zookeeper
    docker run --network=foo --name kafka -e KAFKA_ADVERTISED_HOST_NAME=kafka -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 -e KAFKA_CREATE_TOPICS=testtopic:1:1 confluent/kafka
    

    暴露端口并通过 localhost 连接

    docker run -p 2181:2181 -e ZOOKEEPER_CLIENT_PORT=2181 --name zookeeper confluent/zookeeper
    docker run --name kafka -e KAFKA_ADVERTISED_HOST_NAME=kafka -e KAFKA_ZOOKEEPER_CONNECT=host.docker.internal:2181 -e KAFKA_CREATE_TOPICS=testtopic:1:1 confluent/kafka
    

注意:在第二种方法中,您应该使用 host.docker.internal 作为主机名并为第一个容器公开(发布)端口 2181 以使其在 localhost 上可用

【讨论】:

我尝试了第一个选项,运行第二行时抛出“org.I0Itec.zkclient.exception.ZkException: Unable to connect to zookeeper:2181” 我尝试了第二个选项,我也得到 Unable to connect to zookeeper:2181 KAFKA_CREATE_TOPICS 对这些容器无效,此外,您不需要此处的 docker 主机 DNS 名称

以上是关于我的 kafka docker 容器无法连接到我的 zookeeper docker 容器的主要内容,如果未能解决你的问题,请参考以下文章

无法从我的 Docker 容器内部连接到主机的 localhost

Docker:Springboot 容器无法连接到 PostgreSql 容器连接错误

无法连接到 spotify kafka 容器,基本连接问题

无法连接到 Docker 容器

从 Docker 容器将 PySpark 连接到 Kafka

已连接到组协调器但无法连接到 kafka 节点