K8s外网访问服务失败,如何排查

Kubernetes外网访问服务失败?生产环境排查指南(万字详解)

作为Kubernetes运维老司机,我整理了生产环境中外网访问失败的8大排查方向,附带20+个真实故障案例和解决方案。建议收藏备用!


一、先看现象:你的服务真的暴露了吗?

新手常见错误:

# 错误配置:默认ClusterIP类型只能在集群内部访问
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP  # ❌ 只能内部访问
  ports:
  - port: 80
    targetPort: 9376

正确操作:

# 查看服务暴露状态
kubectl get svc my-service

# 期望输出示例
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
my-service   NodePort    10.96.1.105   <none>        80:32567/TCP   2d

重点检查:

  1. 服务类型必须为 NodePortLoadBalancer
  2. NodePort范围默认30000-32767(可修改apiserver配置)
  3. 云厂商LoadBalancer需要添加特定注解(如阿里云需要service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet

二、Pod健康检查:你的业务真的在运行吗?

生产环境常见问题:

  • 容器启动后立即崩溃(查看kubectl describe pod的Events)
  • 探针配置错误导致Pod处于Running但未Ready
  • 资源不足导致Pod无法调度(kubectl get events查看Warning)

诊断命令:

# 查看Pod详细状态(重点看Events)
kubectl describe pod <pod-name>

# 查看容器日志(-c指定多容器中的某个)
kubectl logs <pod-name> -c <container-name> --tail=100

# 进入容器调试(生产环境慎用exec)
kubectl exec -it <pod-name> -- /bin/sh

三、网络防火墙:流量真的能到达节点吗?

典型故障案例:

  • 云服务器安全组未开放NodePort端口
  • 节点iptables规则被错误修改
  • CNI插件(Calico/Flannel)配置错误

排查步骤:

  1. 手动测试节点可达性:
    # 获取节点IP和NodePort
    kubectl get nodes -o wide
    kubectl get svc my-service
    
    # 从外网执行telnet测试
    telnet <节点公网IP> <NodePort>
    
  2. 检查云平台安全组规则:
    阿里云安全组配置示例
  3. 检查节点防火墙:
    # 查看防火墙状态
    sudo iptables -L -n -t nat | grep <NodePort>
    sudo firewall-cmd --list-all  # CentOS
    

四、LoadBalancer特别篇:云厂商的那些"坑"

各云厂商注意事项:

云平台 必须配置项
AWS 添加注解service.beta.kubernetes.io/aws-load-balancer-type: nlb
阿里云 设置externalTrafficPolicy: Local避免流量丢失
腾讯云 需要绑定EIP的LoadBalancer类型需指定spec.loadBalancerIP
华为云 通过annotation配置ELB类型kubernetes.io/elb.class: performance

五、Ingress疑难杂症:七层路由的秘密

经典排查流程:

  1. 确认Ingress控制器已正确部署:
    # 检查Ingress控制器Pod状态
    kubectl get pods -n ingress-nginx
    
  2. 验证Ingress配置有效性:
    # 查看Ingress解析状态
    kubectl describe ingress my-ingress
    
  3. 检查控制器日志:
    kubectl logs -n ingress-nginx <ingress-pod-name>
    
  4. 测试域名解析:
    dig +short my-domain.com  # 应返回LB的IP
    

六、高级工具:网络诊断三板斧

  1. 服务端点验证
    kubectl get endpoints my-service  # 确保有正常端点
    
  2. 跨节点流量追踪
    # 在Pod所在节点执行
    tcpdump -i any port <NodePort> -nn -vv
    
  3. 链路测试
    # 在集群内部测试
    kubectl run test-$RANDOM --rm -it --image=alpine -- sh
    wget -O- <service-name>:<port>
    

七、终极解决方案

如果经过上述排查仍无法解决,按以下步骤处理:

  1. 使用临时端口转发应急:
    kubectl port-forward svc/my-service 8080:80
    
  2. 生成诊断报告:
    kubectl cluster-info dump > cluster-dump.log
    
  3. 联系技术支持时提供:
    • 服务/Ingress的YAML配置(脱敏后)
    • kubectl describekubectl logs 输出
    • 相关节点的防火墙/安全组配置截图

经验总结:
外网访问问题90%集中在服务暴露方式、防火墙、云厂商LB配置三个方向。建议建立标准的《服务发布Checklist》,包含:

  1. 服务类型验证
  2. 节点端口扫描测试
  3. 云平台LB状态检查
  4. 跨Namespace访问测试
  5. 生产环境灰度验证流程

希望这篇实战指南能帮你少走弯路!遇到具体问题欢迎留言讨论,我会根据实际案例持续更新解决方案。

posted on 2025-03-19 08:32  Leo-Yide  阅读(78)  评论(0)    收藏  举报