Kubernetes生产实战(二):NodePort无法访问排查指南(网络策略&&生产环境优化)

发布于:2025-05-11 ⋅ 阅读:(18) ⋅ 点赞:(0)
一、问题场景还原

当将Kubernetes的Service类型从ClusterIP改为NodePort后,理论上应通过<节点IP>:<NodePort>访问服务。但在实际生产环境中,常会遇到访问失败的情况。以部署Prometheus监控栈为例,Grafana服务修改为NodePort后无法访问,以下是完整的排查与解决方案。

二、基础环境检查
1. 确认Service配置正确
kubectl get svc grafana -n monitoring

期望输出

NAME      TYPE       CLUSTER-IP     PORT(S)          AGE
grafana   NodePort   10.96.112.113  3000:31735/TCP   5h

验证点

  • TYPE必须为NodePort
  • PORT(S)列需显示<集群端口>:<NodePort>/<协议>
2. 检查NodePort端口范围

Kubernetes默认NodePort范围为 30000-32767。若需自定义范围,需修改kube-apiserver配置:

# 查看kube-apiserver配置
ps aux | grep kube-apiserver | grep service-node-port-range

查看和调整默认NodePort端口范围方式参考:Kubernetes生产实战:NodePort端口范围的隐藏规则与调优指南-CSDN博客 

生产建议:保持默认范围,避免与系统端口冲突。

三、关键故障排查步骤
1. 节点防火墙与安全组

核心问题:云厂商安全组或节点iptables未开放NodePort端口。

验证方法

# 在集群节点执行
nc -zv <节点IP> 31735
# 或从外部测试
telnet <节点IP> 31735

修复方案

  • 云服务器控制台:添加安全组规则,允许31735/TCP入站
  • 本地防火墙(若有):
    sudo iptables -A INPUT -p tcp --dport 31735 -j ACCEPT
    sudo systemctl restart iptables
    
2. 网络策略(NetworkPolicy)拦截

现象:当集群启用网络插件(如Calico、Cilium)时,NetworkPolicy可能限制入口流量。

诊断命令

kubectl get networkpolicy -n monitoring

临时解决方案

kubectl delete networkpolicy --all -n monitoring

生产环境建议不要直接删除所有策略! 应针对性调整策略:

# grafana-networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: grafana-external-access
  namespace: monitoring
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: grafana
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0  # 生产环境应限制为特定IP段
3. kube-proxy服务异常

排查方法

# 检查kube-proxy日志
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=100

# 确认iptables规则存在
sudo iptables-save | grep 31735

典型问题

  • kube-proxy未正常运行
  • iptables/nftables规则被误删

修复方案

# 重启kube-proxy
kubectl rollout restart ds -n kube-system kube-proxy
4. Pod就绪状态与Endpoint

关键检查点

# 确认Pod处于Running状态
kubectl get pods -n monitoring -l app.kubernetes.io/name=grafana

# 查看Endpoint是否分配
kubectl get endpoints grafana -n monitoring

异常处理

  • 若Endpoint为空,检查Service的selector是否匹配Pod标签
  • Pod未就绪时排查资源限制、探针配置
四、生产环境高级优化方案
1. 使用Ingress替代直接暴露NodePort

优势

  • 统一管理外部访问
  • 支持HTTPS、路由规则等

示例配置(Nginx Ingress)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: monitoring
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: grafana.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: grafana
            port:
              number: 3000
2. 服务质量保障
  • 就绪探针配置

    # grafana-deployment.yaml片段
    readinessProbe:
      httpGet:
        path: /api/health
        port: 3000
      initialDelaySeconds: 10
      periodSeconds: 5
    
  • 资源限制

    resources:
      limits:
        cpu: "1"
        memory: 1Gi
      requests:
        cpu: "0.5"
        memory: 512Mi
    
3. 安全加固
  • 限制NodePort访问源

    # 使用iptables限制IP
    sudo iptables -A INPUT -p tcp --dport 31735 -s 192.168.1.0/24 -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 31735 -j DROP
    
  • 定期轮换NodePort端口

    kubectl patch svc grafana -n monitoring -p '{"spec":{"ports":[{"port":3000,"nodePort":31000}]}}'
    
五、总结排查流程图

六、技术冷知识
  • NodePort实现原理:kube-proxy通过监听API Server,动态维护iptables/IPVS规则,将NodePort流量转发到后端Pod。
  • 为什么默认端口范围是30000-32767:避免与Linux系统端口(0-1023)和用户端口(1024-29999)冲突。
  • NetworkPolicy的隐藏影响:即使没有显式定义NetworkPolicy,某些CNI插件(如Calico)的默认拒绝策略也可能阻断流量。