Kafka客户端仅尝试连接Advertised Listeners单个节点的问题排查
核心问题
你的配置存在两个关键错误,导致客户端只会尝试localhost:9090,完全忽略proxy:19097:
1. 客户端连接的监听与目标广告监听不匹配
客户端使用kafka-mock:9090作为Bootstrap地址,这个端口对应Kafka配置里的INTERNAL监听。Kafka的规则是:客户端通过哪个监听的地址连接Bootstrap,Kafka就只会返回该监听对应的ADVERTISED_LISTENERS地址。
你的INTERNAL监听对应的广告地址是localhost:9090,所以客户端拿到的只有这个地址,根本不会收到INSIDE_PLAINTEXT对应的proxy:19097。
2. 广告监听的端口映射逻辑未对齐
你的INSIDE_PLAINTEXT监听在LISTENERS里绑定的是Pod内部的0.0.0.0:9094,但ADVERTISED_LISTENERS里写的是proxy:19097——即便proxy是K8s Service且已正确转发端口,客户端也没机会用到这个监听,因为你没让客户端连接该监听对应的Bootstrap地址。
修复方案
方案一:让客户端直接连接INSIDE_PLAINTEXT监听的Bootstrap地址
- 确保K8s Service(比如
proxy)的19097端口已正确转发到Kafka Pod的9094端口。 - 修改客户端的Bootstrap地址为
proxy:19097。 - 保持Kafka配置的对应关系:
KAFKA_ADVERTISED_LISTENERS: "INTERNAL://localhost:9090,INSIDE_PLAINTEXT://proxy:19097" KAFKA_LISTENERS: "INTERNAL://0.0.0.0:9090,INTERNAL_FAILOVER://0.0.0.0:9092,INSIDE_PLAINTEXT://0.0.0.0:9094" KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "INTERNAL:PLAINTEXT,INTERNAL_FAILOVER:PLAINTEXT,INSIDE_PLAINTEXT:PLAINTEXT" KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
方案二:调整INTERNAL监听的广告地址为集群可访问地址
如果希望客户端通过INTERNAL监听连接,把INTERNAL的广告地址改成K8s Service的地址,而非localhost:
KAFKA_ADVERTISED_LISTENERS: "INTERNAL://kafka-mock:9090,INTERNAL_FAILOVER://kafka-mock:9092,INSIDE_PLAINTEXT://proxy:19097"
这样客户端连接kafka-mock:9090后,Kafka返回的是集群内可访问的kafka-mock:9090,无需再尝试localhost。
关于新增监听后正常的原因
你新增的INTERNAL_PLAINTEXT监听,广告地址是kafka-mock:9095,且客户端应该是用了这个地址作为Bootstrap,所以Kafka返回的是集群内可访问的kafka-mock:9095,自然能连上。但proxy:19097对应的监听从未被客户端作为Bootstrap地址连接,所以永远不会被返回。
内容的提问来源于stack exchange,提问作者Johnyb

