tl;dr - 从容器到主机的简单端口转发将 不起作用 不应修改 /etc/hosts
主机文件(例如
在代理上将 advertised.listeners
值设置为 advertised.host.name
(而不是 advertised.port
和 Connection to node -1 (localhost/127.0.0.1:9092)
,则表示您的应用容器尝试连接到自身。您的应用容器是否也在运行 Kafka 代理进程?可能不是。
2) 确保列出的服务器 bootstrap.servers
确实可解析。例如 ping
IP/主机名,用于 netcat
检查端口... 如果您的客户端位于容器中,则需要 从容器 如果容器没有立即崩溃, docker exec
请使用它
3) 如果从主机而不是另一个容器运行进程,则要验证端口是否在主机上正确映射,请确保显示 docker ps
kafka 容器是从 映射的 0.0.0.0:<host_port> -> <advertised_listener_port>/tcp
。如果尝试从 Docker 网络外部运行客户端,端口必须匹配。您不需要在两个容器之间进行端口转发;使用链接/docker 网络
以下答案使用 confluentinc
docker 镜像来解决所提出的问题, 而不是 wurstmeister/kafka
。如果您 KAFKA_ADVERTISED_HOST_NAME
设置了变量,请将其删除(这是一个弃用的属性)
以下部分尝试汇总使用其他镜像所需的所有详细信息。对于其他常用的 Kafka 镜像, it's all the same Apache Kafka 在容器中运行的 Apache Kafka。
你只需要看 它是如何配置的 ,以及 哪些变量 使它如此。
wurstmeister/kafka
自 2023 年 10 月起,DockerHub 中不再存在此功能。无论如何,2022 年之后不再维护。
请参阅有关 侦听器配置 ,另 请参阅其连接性 wiki .
bitnami/kafka
如果您想要一个小容器,请尝试这些。这些图像比 Confluent 图像小得多,并且比 wurstmeister
. 参考其 README 进行监听器配置维护得更好。
debezium/kafka
此处提到了 相关文档 .
注意 :已弃用广告主机和端口设置。广告 侦听器 涵盖两者。与 Confluent 容器类似,Debezium 可以使用 KAFKA_
前缀代理设置来更新其属性。
其他的
-
ubuntu/kafka
需要您通过 Docker 镜像参数添加 --override advertised.listeners=kafka:9092
...我发现它比环境变量的可移植性更差,所以不推荐
-
spotify/kafka
已被弃用并且过时了。
-
fast-data-dev
或者 lensesio/box
非常适合一体化解决方案,包括 Schema Registry、Kafka Connect 等,但如果你 只 想要 Kafka,它们就太臃肿了。此外,在一个容器中运行许多服务是 Docker 的反模式
-
你自己
Dockerfile
- 为什么?这些其他人的东西不完整吗?从拉取请求开始,而不是从头开始。
有关补充阅读材料、 功能齐全的 docker-compose
和网络图,请参阅 @rmoff 的博客
回答
Confluent 快速入门(Docker)文档 假定所有生产和消费请求都在 Docker 网络内。
您可以通过在其自己的容器内运行 Kafka 客户端代码来解决连接问题 kafka:9092
,因为它使用 Docker 网络桥,但除此之外,您需要添加更多环境变量以在外部公开容器,同时仍使其在 Docker 网络中工作。
首先添加一个协议映射 PLAINTEXT_HOST:PLAINTEXT
,将侦听器协议映射到 Kafka 协议
钥匙: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
价值: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
然后在不同的端口上设置两个通告的监听器。( kafka
这里指的是docker容器名称;它也可能被命名 broker
,因此请仔细检查您的服务+主机名)。
钥匙: KAFKA_ADVERTISED_LISTENERS
价值: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
请注意,此处的协议与上面协议映射设置左侧的值相匹配
在运行容器时,添加 -p 29092:29092
主机端口映射,以及通告 PLAINTEXT_HOST
监听器。
因此...( 使用上述设置 )
如果 仍然 不起作用, KAFKA_LISTENERS
可以设置为包括 <PROTOCOL>://0.0.0.0:<PORT>
两个选项与广告设置和 Docker 转发端口匹配的位置
客户端位于同一台机器上,不在容器中
正如您所期望的那样,宣传 localhost 和相关端口将允许您连接到容器外部。
换句话说,在 Docker 网络 之外 localhost:29092
用于引导服务器和 localhost:2181
Zookeeper(需要 Docker 端口转发)
另一台机器上的客户端
如果尝试从外部服务器连接,则需要公布 192.168.x.y
主机的外部主机名/ip(例如) 以及/代替本地主机 .
仅通过端口转发来宣传本地主机是行不通的,因为 Kafka 协议仍将继续宣传您已配置的侦听器。
此设置需要 Docker 端口转发 和 路由器端口转发(以及防火墙/安全组更改),例如,您的容器在云中运行并且您想从本地机器与其交互。
同一主机上容器中的客户端(或另一个代理)
这是最不容易出错的配置;您可以直接使用 DNS 服务名称。
在 Docker 网络中 运行应用程序时 ,使用 kafka:9092
(参见 PLAINTEXT
上面公布的侦听器配置)作为引导服务器和 zookeeper:2181
Zookeeper,就像任何其他 Docker 服务通信一样(不需要任何端口转发)
如果你使用单独的 docker run
命令或 Compose 文件,则需要 network
使用 Compose networks
部分手动定义共享或 docker network --create
请参阅完整 Confluent 堆栈的示例 Compose 文件 or 单个代理的 更简约文件
如果使用多个代理,则它们需要使用唯一的主机名 + 公布的侦听器。 参见示例
相关问题
从 Docker(ksqlDB)连接到主机上的 Kafka
附录
对于任何对 Kubernetes 部署感兴趣的人: