k8s集群中nodePort端口不可连接问题排查 您所在的位置:网站首页 mysql容器启动没有端口号 k8s集群中nodePort端口不可连接问题排查

k8s集群中nodePort端口不可连接问题排查

2024-07-11 03:02| 来源: 网络整理| 查看: 265

文章目录 1.问题说明2.问题分析3.问题排查4.问题结论5.问题解决

1.问题说明

今天早上发现,k8s其中有一个服务映射的 nodePort ,在k8s集群外的同内网服务器中,两次连接该服务时,一次可连接,一次不能连接,即50%的几率可以正常连接,使用telnet测试如下:

// 可正常连接 # telnet 192.168.21.202 30001 Trying 192.168.21.202... Connected to 192.168.21.202. Escape character is '^]'. //不可连接 # telnet 192.168.21.202 30001 Trying 192.168.21.202... telnet: connect to address 192.168.21.202: Connection refused 2.问题分析

可通过以下方式,将问题分层,缩小排查范围:

k8s集群外部服务器不可连接,k8s集群内部服务器可连接:此问题不属于k8s集群问题,应该是服务器之间网络连接问题,需要检查防火墙及安全组问题

k8s集群内部服务器不可连接,服务的pod容器内可连接:此问题可能为k8s集群内问题,需要检查各组件状态是否健康,尤其是kube-proxy服务(此服务作用为将svc的请求转发到pod容器内),同时还有iptables防火墙问题,同时也存在着服务问题,有可能此服务有两个pod容器,其中一个服务存在问题

服务的pod容器内也不可连接:此问题应该是服务本身问题,可查看服务启动状态是否启动,查看服务日志是否异常

3.问题排查

通过以上问题分析环节,可得出: k8s集群内部服务器不可连接,服务的pod容器内可连接,于是进行了以下排查步骤:

查看存在问题的服务是否存在两个pod容器及存活状态 // 问题服务svc状态 # kubectl get svc -o wide -n fabric-auto |grep fabric-auto-api fabric-auto-api NodePort 10.1.102.29 8088:30001/TCP 3h10m app=fabric-auto,role=fabric-auto-api // 问题服务pod状态 # kubectl get pod -o wide -n fabric-auto |grep fabric-auto-api fabric-auto-api-5955b9f9cc-x5mgz 1/1 Running 0 3h10m 10.2.3.175 192.168.21.202

可通过以上命令查看到pod容器的状态,目前该服务仅一个pod容器,且正常启动

查看master节点各组件是否正常

以下结果表示无问题

# kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-1 Healthy {"health":"true"} etcd-2 Healthy {"health":"true"} etcd-0 Healthy {"health":"true"} 查看node节点kubelet组件是否正常

可看到kubelet组件的服务状态为running,服务无问题

//node节点中执行 # systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Wed 2021-04-14 11:08:32 CST; 3h 10min ago Docs: https://kubernetes.io/docs/ Main PID: 1208 (kubelet) ...... 查看node节点kube-proxy服务是否正常

因为此k8s集群环境使用kubeadm安装,所以kube-proxy使用容器启动,查看kube-proxy日志时,发现以下报警:

can’t set sysctl net/ipv4/vs/conn_reuse_mode, kernel version must be at least 4.1

//node节点中执行 # docker ps|grep kube-proxy # docker logs -f k8s_kube-proxy_kube-proxy-qn8gg_kube-system_c189d6f0-b9ab-485b-b31e-bf3fd8f9f32d_0 ...... E0203 12:34:19.189547 1 proxier.go:381] can't set sysctl net/ipv4/vs/conn_reuse_mode, kernel version must be at least 4.1 W0203 12:34:19.189665 1 proxier.go:434] IPVS scheduler not specified, use rr by default ......

去 Kubernetes Github 查看相关 issues,发现有人遇见了相同的问题,经过 issue 中 Kubernetes 维护人员讨论,分析出原因可能为新版 Kubernetes 使用的 IPVS 模块是比较新的,需要系统内核版本支持,本人使用的是 CentOS 系统,内核版本为 3.10,里面的 IPVS 模块比较老旧,缺少新版 Kubernetes IPVS 所需的依赖。

根据该 issue 讨论结果,解决该问题的办法是,更新内核为新的版本。

centos7 服务器升级内核版本方法使用此链接:https://blog.csdn.net/cljdsc/article/details/115698143

注意:因升级服务器内核版本需要重启服务器生效,此操作之前,应确定服务器可暂时停机,重启前需要检查服务器启动的服务项,重启后再进行检查服务是否都已经启动!!!

内核版本升级后,kube-proxy容器已经不再打印如上报警,但此时依然无法解决端口连接不通问题

再次对kube-proxy容器重启后,依然未能解决,看来最后的绝招,重启已经无法解决问题了。。。。。

观察k8s集群内端口转发情况 命令:ipvsadm -Ln 作用:查看当前ipvs模块中记录的连接(可用于观察转发情况) # ipvsadm -ln TCP 172.17.0.1:30001 rr -> 10.2.3.161:8088 Masq 1 0 0 -> 10.2.3.172:8088 Masq 1 0 0 TCP 192.168.21.202:30336 rr -> 10.2.3.161:3306 Masq 1 0 0 -> 10.2.3.172:3306 Masq 1 0 0 TCP 172.17.0.1:30303 rr -> 10.2.3.163:8081 Masq 1 0 0

可以看到nodePort 端口:30001、30336转发规则下有两个pod容器,难道这两个端口各自存在两个服务吗,可使用以下命令进行查看:

//30001端口:仅一个pod容器 # kubectl get svc -o wide --all-namespaces |grep 30001 fabric-auto fabric-auto-api NodePort 10.1.102.29 8088:30001/TCP 3h19m app=fabric-auto,role=fabric-auto-api # kubectl get pod -o wide --all-namespaces |grep fabric-auto-api fabric-auto fabric-auto-api-5955b9f9cc-x5mgz 1/1 Running 0 3h19m 10.2.3.175 192.168.21.202 //30336端口:仅一个pod容器 # kubectl get svc -o wide --all-namespaces |grep 30336 fabric-auto fabric-auto-mysql NodePort 10.1.76.55 3306:30336/TCP 3h23m app=fabric-auto,role=fabric-auto-mysql # kubectl get pod -o wide --all-namespaces |grep fabric-auto-mysql fabric-auto fabric-auto-mysql-7f7dc8b46b-jfsmt 1/1 Running 0 3h23m 10.2.3.174 192.168.21.202

这两个服务一定有问题!!!

查看已有的Pod容器为YAML格式 # kubectl get svc -n fabric-auto fabric-auto-mysql -o yaml # kubectl get deployment -n fabric-auto fabric-auto-mysql -o yaml

使用如上命令,查看两pod容器的deployment及svc的yaml文件有一段是相同的:

labels: app: fabric-auto role: fabric-auto-control

labels 参数用来定义此当前服务的标签,以便对pod容器进行管理

4.问题结论

由于两个服务中的svc及pod的yaml文件中标签定义一致,kube-proxy在进行流量分发时,发现有两组同样标签的pod,于是都进行了转发,因此出现:一次可连接,一次不可连接的情况。

5.问题解决

删除两个服务的pod容器及svc

修改两个服务的deployment及svc的yaml文件中的labels标签项,使其不一致即可

重新创建服务的svc及pod,问题解决



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有