You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s环境Kafka重部署报NOT_LEADER_OR_FOLLOWER错误排查咨询

根因定位

你遇到的永久NOT_LEADER_OR_FOLLOWER报错,本质是Kafka生产者持续向错误的节点发送生产请求,目标节点既不是对应分区的Leader也不是Follower,且客户端始终没有获取到最新的集群元数据,才会出现剩余重试次数高达2147483138(接近Integer.MAX_VALUE,即无限重试配置)、永远无法自恢复的现象。结合你描述的「本地连接集群正常、仅K8s内重部署后触发、销毁命名空间重建才恢复」的特征,核心原因集中在4类:

  • Broker监听器配置错误:AWS环境部署Kafka时如果混用内外网访问地址,尤其是把K8s内部访问的advertised.listeners配置为可变的Pod IP,重调度Broker后Pod IP变更,客户端缓存的旧地址被其他新启动的Pod占用,该节点不持有对应分区副本,就会持续抛错。
  • DNS缓存配置不合理:JVM默认在开启SecurityManager时会永久缓存DNS解析结果,加上CoreDNS如果配置了过长的缓存TTL,重部署后Broker Pod IP变化,客户端始终解析到失效的旧IP,且因为访问的节点返回的错误不会触发全量元数据刷新,就会陷入死循环重试。销毁命名空间相当于重建所有客户端Pod清空了本地缓存,所以能临时恢复。
  • K8s网络层规则残留:如果通过普通ClusterIP Service访问Kafka,重调度Broker时Service Endpoint更新延迟、iptables/IPVS规则残留,会持续把请求转发到已经下线的旧Broker节点;如果集群部署了Service Mesh,sidecar的长连接路由规则不随Pod重调度更新,也会出现同类问题。
  • 客户端参数配置缺陷:仅调整client.dns.lookup但没有同步缩短元数据自动刷新间隔,默认5分钟的元数据刷新周期加上错误触发刷新的逻辑失效,会导致客户端长期持有旧的集群拓扑信息。

本地连接集群正常是因为本地访问走的是AWS NLB固定地址,不存在IP可变、缓存残留的问题,所以不会触发该故障。

可落地解决方案

按以下优先级调整配置,可彻底解决该问题:

1. 修正Kafka Broker多监听器配置

AWS环境部署Kafka必须严格区分内外网监听器,禁止混用地址:

  • 内部监听器绑定0.0.0.0:9092,advertised.listeners统一配置为StatefulSet对应的无头Service(Headless Service)固定域名,格式参考INTERNAL://kafka-0.kafka-headless.<kafka所在命名空间>.svc.cluster.local:9092,不要用可变的Pod IP作为对外广播的地址。
  • 外部监听器绑定0.0.0.0:9094,advertised.listeners配置为AWS NLB的固定域名,供集群外的本地环境、跨VPC服务访问。
  • 配置listener.security.protocol.map匹配两个监听器的安全协议,设置inter.broker.listener.name=INTERNAL,保证Broker之间同步走内部域名,不绕外部负载均衡。

2. 调整客户端配置

  • 给客户端应用的JVM加启动参数,修改DNS缓存TTL,禁止永久缓存解析结果:
-Dsun.net.inetaddr.ttl=30 -Dsun.net.inetaddr.negative.ttl=10

配置后JVM最多缓存30秒正向DNS结果、10秒负向解析结果,Broker IP变更后最多30秒就能拿到新的解析地址。

  • 修正Kafka生产者参数,不要仅调整client.dns.lookup:
    • 设置client.dns.lookup=use_all_dns_ips
    • 把metadata.max.age.ms从默认的300000(5分钟)调整为60000(1分钟),强制客户端每分钟主动全量刷新一次集群元数据,避免长期持有旧拓扑
    • 设置reconnect.backoff.ms=1000、reconnect.backoff.max.ms=10000,避免重连间隔过长导致恢复缓慢

3. 排查K8s网络层配置

  • 调整CoreDNS配置,把集群内域名的缓存TTL设置为30秒以内;给客户端Pod加dnsConfig配置,把ndots从默认的5改成2,减少无效的域名搜索解析。
  • 访问Kafka统一用无头Service地址,不要用开启了ClientIP会话保持的普通ClusterIP Service,避免iptables/IPVS规则残留导致流量转发错误。
  • 如果集群部署了Istio、Linkerd等Service Mesh组件,先给Kafka Broker和客户端配置sidecar注入排除规则,验证是否为sidecar路由规则不更新导致的流量转发异常。
故障快速定位方法

下次故障复现时无需删除命名空间,按以下步骤可快速定位根因:

  • 进入故障客户端Pod,用自带的kafka-console-producer.sh脚本直接连接Broker无头Service地址发测试消息,如果发送正常,说明是业务应用本身的DNS缓存、客户端元数据缓存问题。
  • 在客户端Pod内用nslookup解析每个Broker的域名,对比返回的IP和Broker当前实际运行的Pod IP,如果不一致就是DNS缓存问题。
  • 用telnet连接解析到的Broker IP对应端口,核对返回的Broker ID和集群元数据内的Broker ID是否匹配,如果不匹配就是网络层规则残留导致的转发错误。

内容的提问来源于stack exchange,提问作者JimmyyW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:39:20