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
重点检查:
- 服务类型必须为
NodePort
或LoadBalancer
- NodePort范围默认30000-32767(可修改apiserver配置)
- 云厂商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)配置错误
排查步骤:
- 手动测试节点可达性:
# 获取节点IP和NodePort kubectl get nodes -o wide kubectl get svc my-service # 从外网执行telnet测试 telnet <节点公网IP> <NodePort>
- 检查云平台安全组规则:
- 检查节点防火墙:
# 查看防火墙状态 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疑难杂症:七层路由的秘密
经典排查流程:
- 确认Ingress控制器已正确部署:
# 检查Ingress控制器Pod状态 kubectl get pods -n ingress-nginx
- 验证Ingress配置有效性:
# 查看Ingress解析状态 kubectl describe ingress my-ingress
- 检查控制器日志:
kubectl logs -n ingress-nginx <ingress-pod-name>
- 测试域名解析:
dig +short my-domain.com # 应返回LB的IP
六、高级工具:网络诊断三板斧
- 服务端点验证:
kubectl get endpoints my-service # 确保有正常端点
- 跨节点流量追踪:
# 在Pod所在节点执行 tcpdump -i any port <NodePort> -nn -vv
- 链路测试:
# 在集群内部测试 kubectl run test-$RANDOM --rm -it --image=alpine -- sh wget -O- <service-name>:<port>
七、终极解决方案
如果经过上述排查仍无法解决,按以下步骤处理:
- 使用临时端口转发应急:
kubectl port-forward svc/my-service 8080:80
- 生成诊断报告:
kubectl cluster-info dump > cluster-dump.log
- 联系技术支持时提供:
- 服务/Ingress的YAML配置(脱敏后)
kubectl describe
和kubectl logs
输出- 相关节点的防火墙/安全组配置截图
经验总结:
外网访问问题90%集中在服务暴露方式、防火墙、云厂商LB配置三个方向。建议建立标准的《服务发布Checklist》,包含:
- 服务类型验证
- 节点端口扫描测试
- 云平台LB状态检查
- 跨Namespace访问测试
- 生产环境灰度验证流程
希望这篇实战指南能帮你少走弯路!遇到具体问题欢迎留言讨论,我会根据实际案例持续更新解决方案。