有多种方法可以解决这个问题。但在我们深入了解之前,您需要了解您的方法存在两个问题:
- 当您使用
docker run
时,zookeeper
主机无法访问,因为每个容器都在不同的网络隔离中运行
kafka
可能会启动并尝试连接到 zookeeper
,但此时 zookeeper
还没有准备好
解决网络问题
有很多方法可以解决这些问题
使用 --net=host
来在主机网络上同时运行两个容器
使用 docker network create <name>
命令创建一个新的网络,并在启动两个容器时使用 --net=<name>
或者您可以将 kafka 容器运行在 zookeeper 容器的网络中。
在启动 kafka
容器时使用 --net=container:zookeeper
,这将确保 zookeeper
主机可访问。这不是推荐的方法,除非你有一些强烈的理由要这么做。因为一旦 zookeeper
容器关闭,kafka
容器的网络也会关闭。但为了便于理解,我在这里列出了这个选项
解决启动竞争问题
您可以在启动 zookeeper
和 kafka
之间留出一定的时间间隔,以确保在 kafka
启动时 zookeeper
已经运行
另一个选择是在 docker run 命令中使用 --restart=on-failure
标志。这将确保容器在失败时重新启动,并尝试重新连接到 zookeeper
,希望此时 zookeeper
已经启动。
相比于使用 docker run
,我更喜欢使用 docker-compose
来运行这样的关联容器。您可以通过创建一个简单的 docker-compose.yml
文件,然后使用 docker-compose 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
confluentinc/kafka
和 Zookeeper。另外,请使用 Docker compose,并阅读此博客 https://rmoff.net/2018/08/02/kafka-listeners-explained/。 - OneCricketeerconfluentinc/kafka
和confluentinc/zookeeper
。 - fuzzi