尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

K8s 1.22.17中NodePort端口不通?可能是kube-proxy模式惹的祸(附详细排查步骤)

K8s 1.22.17中NodePort端口不通?可能是kube-proxy模式惹的祸(附详细排查步骤) Kubernetes NodePort服务访问故障深度排查指南从kube-proxy模式到网络策略全解析当你兴冲冲地在Kubernetes集群中部署了一个NodePort服务准备通过节点IP访问时却发现某些节点上的端口死活不通——这种场景对于运维过生产级K8s集群的工程师来说绝不陌生。最近我就被这个问题结结实实坑了一把在1.22.17版本的集群中NodePort服务在worker节点上畅通无阻偏偏在master节点上毫无反应。经过长达6小时的排查最终发现问题的根源竟藏在kube-proxy的工作模式切换中。1. NodePort服务工作原理与典型故障现象NodePort作为Kubernetes服务暴露的三种基本类型之一其工作原理是在每个集群节点的指定端口上开放服务入口。假设我们有一个NodePort为32080的服务那么理论上你应该能够通过任何节点IP:32080访问该服务。但现实往往比理想骨感得多以下是几种典型的故障表现选择性失联部分节点特别是master节点无法访问而其他节点正常时通时不通连接时好时坏毫无规律可言完全沉默所有节点上的端口都没有任何响应在我最近遇到的案例中集群表现出第一种症状——两个worker节点上的NodePort工作正常但master节点上的相同端口却像被黑洞吞噬了一般。使用telnet测试时的表现尤为诡异# 在worker节点上测试成功 $ telnet worker-node-ip 32080 Trying worker-node-ip... Connected to worker-node-ip. Escape character is ^]. # 在master节点上测试失败 $ telnet master-node-ip 32080 Trying master-node-ip... telnet: Unable to connect to remote host: Connection refused2. 系统性排查路线图从基础到深层当面对NodePort不通的问题时按照系统性的排查路线可以避免在黑暗中盲目摸索。以下是我总结的七层排查法2.1 基础检查服务定义与节点状态首先确认服务本身的定义没有问题apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: type: NodePort ports: - port: 80 targetPort: 8080 nodePort: 32080 selector: app: my-app关键检查点nodePort范围是否在30000-32767之间默认范围selector是否匹配了实际存在的Pod对应的Pod是否处于Running状态且通过了readiness探针2.2 网络平面检查防火墙与内核参数即使K8s配置正确底层系统的网络设置也可能阻断流量。需要检查防火墙状态# 查看firewalld状态 systemctl status firewalld # 如果使用iptables iptables -L -n | grep 32080内核参数# 检查IP转发是否开启 cat /proc/sys/net/ipv4/ip_forward # 应该为1 # 检查bridge-nf-call相关参数 sysctl -a | grep bridge-nf-call2.3 kube-proxy工作模式诊断这是最容易被忽视却至关重要的一环。kube-proxy支持三种模式模式原理性能特点适用场景userspace用户空间代理高延迟低吞吐历史遗留基本不用iptables内核iptables规则中等性能中小规模集群ipvs内核IPVS负载均衡高性能大规模生产集群检查当前模式# 通过metrics接口查询 curl -s 127.0.0.1:10249/proxyMode # 或者检查kube-proxy日志 kubectl logs -n kube-system kube-proxy-pod在我的案例中明明配置了ipvs模式但实际运行的却是iptables模式$ curl -s 127.0.0.1:10249/proxyMode iptables3. kube-proxy模式切换实战从iptables到ipvs当发现kube-proxy运行在非预期模式时需要进行模式切换。以下是详细操作步骤3.1 修改kube-proxy配置kubectl edit cm kube-proxy -n kube-system找到mode字段确保其值为ipvsdata: config.conf: |- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs ipvs: scheduler: rr # 轮询调度算法3.2 重启kube-proxy Pod由于kube-proxy以DaemonSet方式运行直接删除Pod让其重建即可kubectl delete pod -n kube-system -l k8s-appkube-proxy3.3 验证模式切换等待新Pod启动后再次验证模式# 检查运行模式 kubectl logs -n kube-system 新的kube-proxy-pod | grep Using ipvs Proxier # 或者直接查询metrics接口 curl -s 127.0.0.1:10249/proxyMode3.4 检查ipvs规则成功切换后应该能看到ipvs创建的规则# 安装ipvsadm工具 yum install -y ipvsadm # CentOS/RHEL apt-get install -y ipvsadm # Ubuntu/Debian # 查看规则 ipvsadm -Ln预期输出应包含类似内容TCP 192.168.1.100:32080 rr - 10.244.1.5:8080 Masq 1 0 0 - 10.244.2.3:8080 Masq 1 0 04. 高级排查当切换模式仍不能解决问题时有时候即使切换到正确的kube-proxy模式问题仍然存在。这时候需要深入网络堆栈4.1 检查CNI插件状态# 查看CNI插件Pod状态 kubectl get pods -n kube-system | grep -E flannel|calico|cilium # 检查网络接口 ip addr show4.2 节点网络策略检查某些CNI插件如Calico可能会默认阻止master节点的某些流量# 检查NetworkPolicy kubectl get networkpolicies --all-namespaces # 临时放行所有流量测试 kubectl apply -f - EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-test namespace: default spec: podSelector: {} ingress: - {} egress: - {} policyTypes: - Ingress - Egress EOF4.3 内核模块检查ipvs模式依赖特定的内核模块# 检查所需模块 lsmod | grep -e ip_vs -e nf_conntrack # 如果缺少模块手动加载 modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack5. 预防措施与最佳实践为了避免将来再次陷入NodePort的泥潭我总结了以下预防措施集群初始化时明确指定kube-proxy模式推荐ipvs确保所有节点加载所需内核模块统一配置主机防火墙规则日常运维中定期检查kube-proxy日志是否有异常监控Service网络延迟和丢包率使用NetworkPolicy精细控制流量诊断工具箱# 端口连通性测试 nc -zv node-ip node-port telnet node-ip node-port # 服务端点检查 kubectl get endpoints service-name # 详细服务诊断 kubectl describe svc service-name那次故障后我在所有K8s集群的部署清单中都加入了ipvs模块的预加载检查再也没被NodePort问题困扰过。记住在云原生世界里看似玄学的问题背后往往藏着某个配置参数的微小偏差。
返回列表