在K8S中,集群服务访问失败 如何解决?
Kubernetes服务访问故障救命指南:从红屏报警到故障消除的血泪经验
作为经历过数百次线上故障的SRE,我总结出这套"服务不通"排查九阳神功。跟着以下步骤操作,10分钟内定位问题概率高达90%!
一、快速自检清单(5分钟定位80%问题)
- 服务三件套检查
# 一键检查服务状态
kubectl get pod,svc,endpoints -l app=你的服务标签
✅ 理想状态:
- Pods: Running且READY 1/1
- Service: 有ClusterIP和正确Endpoints
- Endpoints: 包含Pod IP+端口
- 经典报错对照表
| 现象 | 可能原因 | 应急命令 |
|---|---|---|
| Connection refused | 端口映射错误 | kubectl describe svc <服务名> |
| No route to host | 网络插件故障 | kubectl get networkpolicy |
| 503 Service Unavailable | 无可用Endpoint | kubectl get endpoints |
| DNS解析失败 | CoreDNS异常 | kubectl logs -n kube-system -l k8s-app=kube-dns |
二、深度排查六脉神剑(生产环境必备)
1. 端口映射黑洞探测
# 在节点上检查iptables规则
iptables-save | grep KUBE-SVC
# 正确示例应看到NAT规则
-A KUBE-SVC-XXX -m comment --comment "my-service:80" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-XXX
2. 跨命名空间访问陷阱
# 错误示例:直接调用服务名
http://my-service
# 正确姿势:带命名空间
http://my-service.<namespace>.svc.cluster.local
3. 容器网络连通性测试
# 启动临时诊断Pod
kubectl run net-tool --image=nicolaka/netshoot -it --rm --restart=Never
# 在诊断Pod中执行
dig my-service.<namespace>.svc.cluster.local
telnet my-service 80
curl -v http://my-service:80
4. 网络策略审查
# 常见错误:未开放服务端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-service
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- ports:
- protocol: TCP
port: 80
5. 节点级故障排查
# 检查kube-proxy日志
kubectl logs -n kube-system -l k8s-app=kube-proxy | grep ERROR
# 查看conntrack表
conntrack -L -d <服务IP>
6. 分布式追踪大法
# 在Deployment中添加Sidecar
- name: istio-proxy
image: docker.io/istio/proxyv2:1.16
args:
- proxy
- sidecar
三、经典故障场景复盘
案例1:深夜的诡异503
现象:服务状态正常但持续返回503
根因:Endpoints未更新(残留旧Pod IP)
解决:
kubectl patch endpoints my-service -p '{"subsets":[]}' # 强制刷新
案例2:跨集群调用超时
现象:A集群服务无法访问B集群服务
根因:Calico网络策略冲突
解决:
calicoctl get globalnetworkpolicies -o yaml
案例3:生产环境DNS劫持
现象:部分节点解析服务名超时
根因:节点DNS配置被第三方安全软件篡改
解决:
systemctl restart systemd-resolved
四、运维工具箱(赶紧收藏)
| 工具 | 用途 | 安装命令 |
|---|---|---|
| netshoot | 网络诊断神器 | kubectl run netshoot --image=nicolaka/netshoot |
| ksniff | 抓包分析工具 | kubectl sniff <pod> -n <namespace> |
| kubectl-debug | 实时调试运行中Pod | kubectl debug <pod> -it --copy-to=debugger |
| cilium | 可视化网络拓扑 | cilium connectivity test |
五、防崩坏措施(预防大于治疗)
- 服务健康检查双保险
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
exec:
command:
- /bin/sh
- -c
- curl -s http://localhost:8080/ready
- 自动故障转移配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr-failover
spec:
host: my-service
trafficPolicy:
outlierDetection:
consecutiveErrors: 5
interval: 1m
baseEjectionTime: 3m
- 监控告警黄金指标
# Prometheus告警规则
- alert: ServiceDown
expr: up{job="my-service"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "服务 {{ $labels.instance }} 下线"
六、终极检查清单
最后送上血泪经验:永远不要相信"服务配置没问题"这种鬼话!实际生产环境中,连kube-proxy的iptables模式在不同内核版本都有差异。记住,直接登陆Pod测试是王道!
(配个梗图:左边程序员面对报错抓狂,右边运维淡定敲命令,字幕"你只管重启,剩下的交给奇迹")
浙公网安备 33010602011771号