K3S集群中NATS连接失败问题排查求助
NATS在K3S集群中连接超时问题排查与修复
问题背景
在树莓派搭建的K3S集群中,通过Helm部署NATS用于多应用通信,参考官方及社区指南完成安装后,在my-nats-box容器内执行测试时持续出现连接超时,报错:
nats: error: dial tcp: lookup my-nats: i/o timeout
测试操作及输出如下:
kubectl exec -n default -it deployment/my-nats-box -- /bin/sh -l # 省略欢迎信息 my-nats-box-b864cbd4c-46q2z:~# nats sub test& my-nats-box-b864cbd4c-46q2z:~# nats pub test hi nats: error: dial tcp: lookup my-nats: i/o timeout # 省略重复报错及后续测试失败输出
集群资源状态显示NATS相关组件均正常运行:
kubectl get all # 省略无关资源 NAME READY STATUS RESTARTS AGE pod/my-nats-0 3/3 Running 0 2m47s pod/my-nats-box-b864cbd4c-46q2z 1/1 Running 0 2m47s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-nats ClusterIP None <none> 4222/TCP,6222/TCP,8222/TCP,7777/TCP,7422/TCP,7522/TCP 2m47s NAME READY AGE statefulset.apps/my-nats 1/1 2m47s
NATS服务日志无异常,确认服务已正常启动:
kubectl logs service/my-nats [7] 2022/09/26 14:47:58.528353 [INF] Starting nats-server [7] 2022/09/26 14:47:58.531880 [INF] Server is ready
问题分析
报错显示DNS解析my-nats超时,核心原因可能是以下几点:
- K3S集群的CoreDNS组件异常,导致服务域名无法解析
- NATS客户端默认使用的连接地址未正确指向集群内的NATS服务
- Headless Service(
my-nats)与StatefulSet的标签匹配存在问题
修复步骤
1. 验证DNS解析能力
进入my-nats-box容器,执行DNS查询命令验证my-nats是否能被解析:
kubectl exec -n default -it deployment/my-nats-box -- nslookup my-nats # 或使用dig kubectl exec -n default -it deployment/my-nats-box -- dig my-nats
- 如果解析失败:检查CoreDNS的Pod状态(
kubectl get pods -n kube-system),查看CoreDNS日志排查异常,必要时重启CoreDNS组件。 - 如果解析成功:说明问题出在客户端连接配置上。
2. 指定NATS服务地址进行测试
直接在命令中指定NATS服务的完整地址(Headless Service默认端口4222):
# 订阅消息 nats sub test --server=nats://my-nats:4222& # 发布消息 nats pub test hi --server=nats://my-nats:4222
或者设置环境变量统一指定连接地址:
export NATS_URL=nats://my-nats:4222 nats sub test& nats pub test hi
3. 验证Headless Service与StatefulSet的标签匹配
检查my-nats服务的标签选择器是否与my-nats StatefulSet的Pod标签一致:
# 查看服务的标签选择器 kubectl describe service my-nats | grep "Selector" # 查看StatefulSet的Pod标签 kubectl describe statefulset my-nats | grep "Labels"
如果标签不匹配,修改Helm配置中的服务选择器,重新部署NATS。
4. 直接使用Pod IP测试(排除DNS影响)
如果DNS问题暂时无法解决,可直接使用NATS Pod的IP进行测试:
# 获取NATS Pod的IP NATS_POD_IP=$(kubectl get pod my-nats-0 -o jsonpath='{.status.podIP}') # 进入容器测试 kubectl exec -n default -it deployment/my-nats-box -- /bin/sh -l nats sub test --server=nats://${NATS_POD_IP}:4222& nats pub test hi --server=nats://${NATS_POD_IP}:4222
内容的提问来源于stack exchange,提问作者Johnney
相关产品推荐
相关产品推荐

