在K8S中,K8S集群外部,突然之间无法访问到Pod,排查思路是什么?

在 Kubernetes 集群外部突然无法访问 Pod 时,需从“外部访问路径”入手,按“从外向内、逐层穿透”的思路排查,重点关注访问入口(如 Service、Ingress)、网络链路、Pod 状态及配置等环节。以下是具体排查步骤:

一、明确外部访问的路径(关键前提)

首先需确认外部访问 Pod 的具体方式,不同方式的排查重点不同,常见路径包括:

  • 通过 NodePort Service外部客户端 → 节点 IP:NodePort → Service → Pod
  • 通过 LoadBalancer Service外部客户端 → 负载均衡器 IP:端口 → 节点 → Service → Pod
  • 通过 Ingress外部客户端 → Ingress 入口 IP/域名 → Ingress 控制器 → Service → Pod
  • 直接访问 Pod IP(不推荐,因 Pod IP 不稳定):外部客户端 → Pod IP:端口

先明确当前使用的路径,再针对性排查。

二、排查访问入口的可用性(从最外层开始)

外部访问失败的第一站通常是“入口点”(如 NodePort 端口、负载均衡器、Ingress 地址),需确认入口是否可达。

1. 若通过 NodePort Service 访问

  • 检查 NodePort 端口是否在节点上开放
    • 执行 kubectl get svc <service-name> -o wide,确认 NodePort 字段(如 30080)和关联的节点 IP(可通过 kubectl get nodes -o wide 获取节点的外部 IP)。
    • 从外部客户端测试节点 IP:NodePort 的连通性:
      # 测试网络连通性(需替换为实际节点 IP 和 NodePort)
      ping <node-ip>  # 确认节点是否可达
      telnet <node-ip> <nodeport>  # 确认端口是否开放(连接成功则端口可达)
      curl http://<node-ip>:<nodeport>  # 测试应用是否响应
      
    • telnet 失败(端口不可达),可能原因:
      • 节点防火墙(如 iptables、firewalld)未开放 NodePort 端口(默认 30000-32767 范围)。
      • 云环境中,节点安全组未允许该端口的入站流量。

2. 若通过 LoadBalancer Service 访问

  • 检查负载均衡器是否正常工作
    • 执行 kubectl get svc <service-name>,确认 EXTERNAL-IP 字段是否为有效公网 IP(而非 <pending>)。若为 <pending>,说明云厂商未成功创建负载均衡器(需检查云平台权限或配置)。
    • 从外部客户端测试负载均衡器 IP:端口的连通性(同 NodePort 的 ping/telnet/curl 命令)。
    • 若负载均衡器不可达,可能原因:
      • 负载均衡器未完成初始化(云厂商创建需要时间)。
      • 负载均衡器健康检查失败(后端节点或 Pod 异常,导致负载均衡器标记节点为不健康)。
      • 云平台网络 ACL 阻止了流量。

3. 若通过 Ingress 访问

  • 检查 Ingress 入口和控制器状态
    • 执行 kubectl get ingress <ingress-name>,确认 ADDRESS 字段是否有值(Ingress 控制器的 IP 或域名)。
    • 检查 Ingress 控制器 Pod 是否正常运行(如 nginx-ingress-controller):
      kubectl get pods -n <ingress-namespace>  # 通常在 ingress-nginx 或 kube-system 命名空间
      
    • 从外部客户端测试 Ingress 地址的连通性:
      ping <ingress-ip>  # 若用域名,先执行 nslookup <domain> 确认解析是否正确
      curl http://<ingress-domain>/<path>  # 测试应用响应
      
    • 若 Ingress 不可达,可能原因:
      • Ingress 控制器崩溃或未正常运行。
      • Ingress 规则配置错误(如 hostpath 与 Service 关联错误),可通过 kubectl describe ingress <ingress-name> 查看事件。

三、排查 Service 与 Pod 的关联(中间层)

若入口可达但仍无法访问 Pod,需检查 Service 是否正确关联到 Pod,以及流量是否能从 Service 转发到 Pod。

1. 检查 Service 配置及 Endpoints

  • Service 依赖 selector 匹配 Pod 的 labels,若匹配失败,Endpoints 会为空,导致流量无后端可转发。
    • 执行 kubectl describe svc <service-name>,查看 Endpoints 字段是否有值(格式为 PodIP:targetPort)。
      • Endpoints 为空:
        • 检查 Service 的 selector 与 Pod 的 labels 是否一致:
          # 查看 Service 的 selector
          kubectl get svc <service-name> -o jsonpath='{.spec.selector}'
          # 查看 Pod 的 labels(需替换为实际 Pod 名称)
          kubectl get pod <pod-name> -o jsonpath='{.metadata.labels}'
          
        • 若不一致,修改 Service 或 Pod 的标签使其匹配。

2. 检查 Service 端口映射是否正确

  • Service 的 port(集群内访问端口)和 targetPort(Pod 实际监听端口)是否匹配,若 targetPort 错误,流量会转发到 Pod 的无效端口。
    • 执行 kubectl get svc <service-name> -o wide,确认 PORT(S) 列是否为 port:targetPort(如 80:8080,表示 Service 80 端口转发到 Pod 8080 端口)。
    • targetPort 错误,修改 Service 配置(kubectl edit svc <service-name>)。

3. 在节点上测试 Service 到 Pod 的转发

  • 登录任意节点,直接访问 Service 的 ClusterIP:port 或 Pod IP:targetPort,确认流量能否到达 Pod:
    # 获取 Service 的 ClusterIP
    cluster_ip=$(kubectl get svc <service-name> -o jsonpath='{.spec.clusterIP}')
    # 访问 Service(测试 Service 转发是否正常)
    curl http://$cluster_ip:<service-port>
    # 直接访问 Pod IP(测试 Pod 本身是否响应,需替换为实际 Pod IP 和 targetPort)
    curl http://<pod-ip>:<targetPort>
    
    • 若访问 Pod IP 成功但访问 Service 失败:可能是 kube-proxy 异常(负责 Service 转发规则),需检查 kube-proxy 状态(见步骤四)。

四、排查 Pod 本身的可用性(内层)

若 Service 转发正常但仍无法访问,需确认 Pod 内的应用是否正常运行,能否处理请求。

1. 检查 Pod 状态及事件

  • 执行 kubectl get pods <pod-name>,确认 Pod 处于 Running 状态(无 CrashLoopBackOffError 等异常)。
  • 执行 kubectl describe pod <pod-name>,查看事件是否有错误(如启动失败、健康检查失败)。

2. 检查 Pod 内应用是否正常监听端口

  • 应用需在 targetPort 上正常监听,否则即使 Pod 运行,也无法响应请求。
    • 进入 Pod 内部,检查端口监听情况:
      kubectl exec -it <pod-name> -- sh
      # 检查 targetPort 是否被监听(如 8080)
      netstat -tuln | grep 8080  # 或 ss -tuln | grep 8080
      # 测试应用是否响应本地请求
      curl localhost:8080
      
    • 若应用未监听端口或本地访问失败:
      • 检查应用启动命令是否正确(如配置文件错误导致启动失败)。
      • 查看应用日志定位错误:kubectl logs <pod-name>(或 kubectl logs <pod-name> -p 查看上一次启动日志)。

3. 检查 Pod 健康检查配置

  • 若 Pod 配置了 livenessProbe(存活探针)或 readinessProbe(就绪探针),探针失败会导致 Pod 被标记为不健康,Service 会剔除该 Pod 或不将其加入 Endpoints。
    • 执行 kubectl describe pod <pod-name>,查看 LivenessReadiness 探针的状态,若失败,需调整探针配置(如延长超时时间、修正探针路径)。

五、排查网络链路与安全策略(底层)

若以上步骤均正常,需检查网络插件、kube-proxy 及安全策略是否阻止了流量。

1. 检查 kube-proxy 状态

  • kube-proxy 负责维护 Service 的转发规则(如 iptables 或 IPVS 规则),若异常会导致流量无法转发。
    • 检查 kube-proxy Pod 是否正常运行(通常在 kube-system 命名空间):
      kubectl get pods -n kube-system | grep kube-proxy
      
    • 查看 kube-proxy 日志,排查是否有规则配置失败、端口冲突等错误:
      kubectl logs <kube-proxy-pod-name> -n kube-system
      

2. 检查网络插件状态

  • 网络插件(如 Calico、Flannel)负责 Pod 网络连通性,若异常会导致跨节点 Pod 通信失败。
    • 检查网络插件 Pod 是否正常运行(如 Calico 在 kube-system,Cilium 在 cilium 命名空间):
      kubectl get pods -n <network-namespace>
      
    • 确认节点状态为 Ready(网络插件故障可能导致节点 NotReady):
      kubectl get nodes
      

3. 检查网络策略(NetworkPolicy)

  • 若集群中配置了 NetworkPolicy,可能存在规则阻止外部流量进入 Pod(如仅允许特定命名空间或 IP 访问)。
    • 查看当前命名空间的 NetworkPolicy:
      kubectl get networkpolicy -n <namespace>
      
    • 分析规则是否拦截了外部流量(可临时删除 NetworkPolicy 测试是否恢复访问)。

4. 检查节点与 Pod 的网络连通性

  • 从节点测试到 Pod IP 的连通性,确认节点到 Pod 的网络是否通畅:
    ping <pod-ip>  # 测试节点到 Pod 的网络连通性
    telnet <pod-ip> <targetPort>  # 测试节点到 Pod 端口的连通性
    
    • 若不通,可能是网络插件配置错误(如 CIDR 冲突)或节点防火墙拦截了 Pod 网段流量。

六、云环境特殊检查(若适用)

  • 安全组:云厂商节点安全组需允许外部访问的端口(如 NodePort、负载均衡器端口)。
  • 网络 ACL:子网的网络 ACL 规则是否阻止了入站/出站流量。
  • 负载均衡器健康检查:云厂商负载均衡器的健康检查配置是否正确(如检查路径、端口是否与 Pod 应用匹配)。

总结排查流程

  1. 确认外部访问路径(NodePort/LoadBalancer/Ingress),检查入口点是否可达;
  2. 验证 Service 与 Pod 的关联(Endpoints 非空、端口映射正确);
  3. 检查 Pod 状态及应用健康(运行正常、监听正确端口);
  4. 排查网络组件(kube-proxy、网络插件)及安全策略(NetworkPolicy、防火墙);
  5. 云环境额外检查安全组、负载均衡器配置。

通过逐层缩小范围,可快速定位外部访问失败的根源(如配置错误、组件故障、安全拦截等)。

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