在K8S中,有个服务使用service的nodeport进行暴露,访问不到如何排查?

在Kubernetes中,通过NodePort暴露的服务无法访问时,可按照以下步骤逐步排查,从服务配置到网络链路逐层定位问题:

1. 检查Service本身配置与状态

首先确认Service是否正确创建且NodePort已正常分配。

  • 查看Service基本信息
    执行命令:

    kubectl get svc <service-name> -o wide
    

    重点关注:

    • TYPE 是否为 NodePort(确保不是ClusterIP或LoadBalancer)。
    • PORT(S) 列是否显示 [目标端口]:[NodePort]/TCP(例如 80:30080/TCP,30080即为NodePort)。
    • 若未显示NodePort,可能是端口超出默认范围(通常30000-32767)或集群配置限制,需检查Service的nodePort字段是否合法。
  • 查看Service详细描述
    执行命令:

    kubectl describe svc <service-name>
    

    重点关注:

    • Endpoints 字段是否有值(格式为 PodIP:targetPort)。若为空,说明Service的selector与Pod的labels不匹配,导致没有后端Pod。

2. 检查后端Pod状态与可用性

Service的Endpoints依赖于匹配的Pod,需确认Pod正常运行且应用可访问。

  • 检查Pod状态
    执行命令:

    kubectl get pods -l <selector-key>=<selector-value>  # 用Service的selector过滤
    

    确保Pod处于 Running 状态,无 CrashLoopBackOffError 等异常(若有异常,执行 kubectl logs <pod-name> 查看日志)。

  • 检查Pod与Service的label匹配
    执行命令:

    kubectl get pods <pod-name> -o jsonpath='{.metadata.labels}'  # 查看Pod的labels
    kubectl get svc <service-name> -o jsonpath='{.spec.selector}'  # 查看Service的selector
    

    确保两者的键值对完全一致(例如均为 app: my-app)。

  • 验证Pod内应用是否正常监听端口
    进入Pod内部,检查应用是否在Service配置的targetPort上监听:

    kubectl exec -it <pod-name> -- sh  # 进入Pod
    # 内部执行:检查端口监听(如targetPort=8080)
    netstat -tuln | grep 8080  # 或 ss -tuln | grep 8080
    # 测试应用是否响应(如HTTP服务)
    curl localhost:8080
    

    若应用未监听目标端口或无响应,需排查应用本身(如启动失败、配置错误)。

3. 检查节点层面网络与端口

NodePort会在集群所有节点开放端口,需确认节点端口可访问。

  • 确认节点IP正确性
    获取节点IP(外部可访问的IP,非集群内部IP):

    kubectl get nodes -o wide  # 查看节点的EXTERNAL-IP或INTERNAL-IP(根据网络环境选择)
    

    访问时需使用节点的实际IP(例如 http://<node-ip>:<nodeport>),而非集群VIP或控制平面IP。

  • 检查节点防火墙规则
    登录节点(或通过云平台控制台),确认防火墙允许NodePort端口的入站流量:

    • 对于iptables
      iptables -L INPUT -n | grep <nodeport>  # 检查是否有允许规则
      
    • 对于firewalld
      firewall-cmd --list-ports | grep <nodeport>/tcp
      

    若未允许,需添加规则开放该端口(例如 firewall-cmd --add-port=<nodeport>/tcp --permanent)。

  • 检查节点是否可达
    从客户端测试节点网络连通性:

    ping <node-ip>  # 确认节点可ping通
    telnet <node-ip> <nodeport>  # 确认端口是否开放(连接成功则端口可达)
    

4. 检查kube-proxy与网络插件

kube-proxy负责维护NodePort的转发规则,网络插件负责Pod与节点的网络连通。

  • 检查kube-proxy状态
    kube-proxy通常以DaemonSet运行在每个节点,执行:

    kubectl get pods -n kube-system | grep kube-proxy  # 确认所有节点的kube-proxy Pod正常运行
    kubectl logs <kube-proxy-pod> -n kube-system  # 查看日志是否有错误(如端口冲突、规则配置失败)
    
  • 检查网络插件状态
    确认Calico、Flannel、Cilium等网络插件正常运行:

    kubectl get pods -n <网络插件命名空间>  # 例如Calico在kube-system,Cilium在cilium
    kubectl get nodes  # 确认所有节点状态为Ready(NotReady可能是网络插件故障)
    

5. 检查Service的externalTrafficPolicy配置

若Service配置了 externalTrafficPolicy: Local,则只有运行对应Pod的节点会响应NodePort请求(未运行Pod的节点会拒绝访问)。

  • 查看配置:
    kubectl get svc <service-name> -o jsonpath='{.spec.externalTrafficPolicy}'
    
  • 若为Local,可临时改为Cluster(所有节点均会转发请求)排查:
    kubectl patch svc <service-name> -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
    

6. 云环境特殊检查(若适用)

若在云厂商(如AWS、GCP、阿里云)的K8s集群中,还需检查:

  • 节点公网IP:确保访问的节点有公网IP(或通过负载均衡转发)。
  • 安全组规则:云平台的节点安全组需允许NodePort端口的入站流量。
  • 网络ACL:子网的网络ACL规则是否阻止了流量。

总结排查流程

  1. 确认Service配置正确、NodePort已分配、Endpoints非空;
  2. 确认后端Pod正常运行、应用监听正确端口;
  3. 确认节点IP正确、防火墙开放NodePort、端口可达;
  4. 检查kube-proxy和网络插件状态;
  5. 排查externalTrafficPolicy和云环境特殊限制。

通过以上步骤,可逐步定位从Service到应用的全链路问题,找到访问失败的根源。

posted @ 2025-08-08 09:40  天道酬勤zjh  阅读(84)  评论(0)    收藏  举报