Kubernetes部署Kafka无法写入Topic问题求助
从你给出的配置和错误信息来看,核心问题集中在Kafka与ZooKeeper通信异常,以及Kafka的网络配置(尤其是advertised.listeners)不正确,导致生产者无法正确获取Broker的可访问地址。咱们一步步来排查解决:
1. 先排查ZooKeeper的连通性问题
你从Kafka容器连接ZK时出现超时,这是Broker无法正常工作的根源。先在Kafka容器内测试ZK的可达性:
# 进入Kafka容器的交互终端 kubectl exec -it kafka-broker0-69c97b67f-4pmw9 -c kafka -- /bin/bash # 测试ZK服务名的DNS解析(应该返回ZK的ClusterIP 10.101.3.128) nslookup zoo1 # 测试ZK 2181端口的连通性 telnet zoo1 2181
- 如果DNS解析失败:检查Kubernetes的CoreDNS Pod是否正常运行(
kubectl get pods -n kube-system),若CoreDNS异常,重启或重建它;同时确认zoo1服务的标签选择器是否匹配ZK Pod。 - 如果端口不通:查看ZK Pod的日志(
kubectl logs zookeeper-deployment-1-796f9d9bcc-cr756),确认ZK进程是否正常监听2181端口;同时检查zoo1服务的端口配置是否正确映射了2181。
2. 检查Kafka的关键网络配置
K8s中部署Kafka最容易踩的坑就是listeners和advertised.listeners配置错误,这直接导致生产者无法获取正确的Broker地址。
查看Kafka Broker的配置(通常在Deployment的环境变量或配置文件中),确保以下配置正确:
# 容器内部监听所有地址 listeners=PLAINTEXT://0.0.0.0:9092 # 告诉外部客户端(集群内/外)可访问的Broker地址 advertised.listeners=PLAINTEXT://kafka-service:9092,PLAINTEXT_HOST://<你的NodeIP>:30998
PLAINTEXT://kafka-service:9092:供K8s集群内的客户端使用(比如你在Pod内执行生产者命令)PLAINTEXT_HOST://<NodeIP>:30998:供集群外的客户端使用(对应NodePort服务的30998端口)
如果你的Deployment中没有设置这两个环境变量,需要更新Kafka的Deployment配置,添加类似:
env: - name: KAFKA_LISTENERS value: "PLAINTEXT://0.0.0.0:9092" - name: KAFKA_ADVERTISED_LISTENERS value: "PLAINTEXT://kafka-service:9092,PLAINTEXT_HOST://10.225.36.98:30998" - name: KAFKA_ZOOKEEPER_CONNECT value: "zoo1:2181"
更新后重启Kafka Pod:kubectl rollout restart deployment kafka-broker0
3. 验证Kafka Broker的状态
查看Kafka的日志,确认Broker是否成功连接ZK并注册:
kubectl logs kafka-broker0-69c97b67f-4pmw9 -c kafka
如果日志中出现Registered broker 0 at path /brokers/ids/0 with addresses: PLAINTEXT://kafka-service:9092,PLAINTEXT_HOST://10.225.36.98:30998,说明Broker已正常注册到ZK。
4. 重新测试生产者写入
集群内测试(在Kafka Pod中执行)
使用K8s服务名作为Broker地址:
kubectl exec kafka-broker0-69c97b67f-4pmw9 -c kafka -i -t -- /opt/kafka_2.12-2.1.0/bin/kafka-console-producer.sh --broker-list kafka-service:9092 --topic test >{"k":"v"}
集群外测试(主机上执行)
使用NodeIP+NodePort:
/opt/kafka_2.12-2.1.0/bin/kafka-console-producer.sh --broker-list 10.225.36.98:30998 --topic test >{"k":"v"}
5. 关于LoadBalancer类型服务的问题
如果你的K8s集群没有集成云厂商的LoadBalancer(比如是本地集群),创建LoadBalancer类型的服务不会自动分配IP,此时可以改用NodePort或者Ingress(如果需要外部访问)。
内容的提问来源于stack exchange,提问作者OO7

