NodePort服务无法访问排查指南
Kubernetes生产排障实战:NodePort服务无法访问
一、故障现象:门牌号正确却进不了店
想象你开了一家网红店(Service),挂出了门牌号(NodePort 31000),但顾客却无法进门。以下是生产环境排查的完整路线图:
graph TD
A[顾客敲门] --> B{门是否打开?}
B -->|是| C[店内服务正常?]
B -->|否| D[检查防火墙/安全组]
C -->|是| E[产品是否上架?]
C -->|否| F[检查Pod状态]
E -->|是| G[收银系统正常?]
E -->|否| H[检查Endpoints]
二、快速诊断三板斧(5分钟定位问题层)
1. 基础健康检查
# 检查Service心脏是否跳动
kubectl get svc my-service -o wide
# 正常输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service NodePort 10.96.1.101 <none> 80:31000/TCP 3d
# 查看Pod是否在岗
kubectl get pods -l app=my-service
2. 四维端口扫描
# 在集群外部扫描节点端口(需安装nmap)
nmap -p 31000 192.168.1.100
# 理想结果
PORT STATE SERVICE
31000/tcp open unknown
# 在节点内部检查监听
kubectl debug node/node-01 -it --image=nicolaka/netshoot -- ss -ltn | grep 31000
3. 服务通道测试
# 从集群内部穿越测试(跳过Service直接访问Pod)
kubectl run -it --rm test-probe --image=curlimages/curl -- curl http://10.96.1.101:80
三、九大常见死因与破解秘籍
故障层 | 典型症状 | 排查命令 | 解决方案 |
---|---|---|---|
物理层 | 节点SSH无法连接 | ping <node-ip> |
联系基础设施团队 |
网络层 | 安全组阻断 | telnet <node-ip> 31000 |
开放云厂商安全组规则 |
传输层 | 端口被占用 | netstat -tulnp | grep 31000 |
修改NodePort范围 |
服务层 | kube-proxy罢工 | systemctl status kube-proxy |
重启kube-proxy服务 |
路由层 | CNI插件异常 | kubectl get pods -n kube-system | grep cni |
重启CNI插件Pod |
终结点层 | Endpoints为空 | kubectl get endpoints my-service |
检查Pod标签匹配 |
应用层 | Pod监听地址错误 | kubectl exec my-pod -- netstat -ltn |
修改应用监听0.0.0.0 |
策略层 | 网络策略阻断 | kubectl get networkpolicy |
调整NetworkPolicy |
玄学层 | 节点污点导致未调度 | kubectl describe node | grep Taint |
添加容忍或节点选择器 |
四、生产环境深度排查
1. 云平台三大陷阱
- AWS:检查安全组入站规则是否开放NodePort范围
- GCP:确认防火墙规则允许
0.0.0.0/0
访问 - 阿里云:查看SLB实例是否配置监听端口
2. kube-proxy侦探记
# 检查iptables规则链(iptables模式)
sudo iptables-save | grep "KUBE-SVC-"
# 查看IPVS虚拟服务(ipvs模式)
sudo ipvsadm -Ln | grep :31000
# 查看代理组件日志
journalctl -u kube-proxy -n 100 --no-pager | grep ERROR
3. 跨节点流量追踪
# 在目标节点抓包分析
kubectl debug node/node-01 -it --image=nicolaka/netshoot -- tcpdump -i any port 31000
# 使用traceroute检查路径
kubectl run trace --image=nicolaka/netshoot --rm -it -- traceroute my-service
五、经典故障案例库
案例1:安全组幽灵规则
- 现象:本地telnet通,公网不通
- 根因:云安全组仅开放了办公室IP段
- 解决:添加
0.0.0.0/0
入站规则
案例2:IPVS模式下的端口劫持
- 现象:NodePort访问返回404
- 排查:
ipvsadm -Ln
发现未正确转发 - 修复:重启kube-proxy并校验内核模块
案例3:节点选择器陷阱
- 现象:部分节点访问不通
- 根因:Service配置了
nodeSelector: gpu=true
- 解决:删除选择器或给节点打标签
案例4:Socket监听错误
- 现象:Pod日志显示"Connection refused"
- 诊断:
kubectl exec pod -- ss -ltn
- 修复:应用改为监听
0.0.0.0
而非127.0.0.1
六、防御性编程:构建坚不可摧的NodePort服务
- 端口分配规范
# 预留特殊端口范围
apiVersion: v1
kind: Service
metadata:
annotations:
kube-router.io/service.nodeport.range: 31000-31999
- 健康检查双保险
livenessProbe:
httpGet:
path: /healthz
port: 31000
initialDelaySeconds: 5
periodSeconds: 5
- 网络策略白名单
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec:
ingress:
- ports:
- port: 31000
from:
- ipBlock:
cidr: 192.168.0.0/16
七、终极验证武器库
- 全链路测试脚本
#!/bin/bash
# 节点端口扫描
nmap -p 31000 $NODE_IP
# 容器内访问测试
kubectl run test-$RANDOM --image=curlimages/curl --rm -it -- \
curl -s -o /dev/null -w "%{http_code}" http://$CLUSTER_IP:80
# 跨节点访问验证
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}' \
| xargs -n 1 -I {} curl -s http://{}:31000/health
- 混沌工程验证
# 使用Chaos Mesh模拟网络中断
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
spec:
action: partition
mode: one
selector:
namespaces:
- default
direction: both
架构师箴言:NodePort看似简单,实则是网络栈的照妖镜。掌握从物理层到应用层的全栈排查能力,才是Kubernetes高手的必经之路。记住:每一个无法访问的端口背后,都隐藏着至少三个不同层的潜在问题。