Kubernetes 网络链路与企业排障 Hands-on
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| API | Application Programming Interface | 应用程序编程接口 |
| AZ | Availability Zone | 可用区 |
| CIDR | Classless Inter-Domain Routing | 无类别域间路由,用于表示网段 |
| CNI | Container Network Interface | 容器网络接口 |
| CPU | Central Processing Unit | 中央处理器 |
| DNS | Domain Name System | 域名系统 |
| eBPF | extended Berkeley Packet Filter | 扩展 BPF,用于内核可编程观测等场景 |
| EKS | Elastic Kubernetes Service | AWS 托管 Kubernetes 服务 |
| ENI | Elastic Network Interface | AWS 弹性网络接口 |
| GKE | Google Kubernetes Engine | Google 托管 Kubernetes 服务 |
| IP | Internet Protocol | 网际协议;IP 地址是网络寻址标识 |
| LB | Load Balancer | 负载均衡器 |
| MTU | Maximum Transmission Unit | 最大传输单元 |
| SNAT | Source Network Address Translation | 源网络地址转换 |
| TCP | Transmission Control Protocol | 传输控制协议 |
| TLS | Transport Layer Security | 传输层安全协议 |
| UDP | User Datagram Protocol | 用户数据报协议 |
前置:实践约定、真实 orders-api、已批准且包含 curl/dig/tcpdump 的诊断镜像;普通诊断不授予特权,抓包另走受控临时权限。CNI 安装与策略见 Cilium / Calico。
1. 画清实际路径并采证#
入口→LB→Gateway/Ingress→Service 对应的后端(实现可能直接到 Pod);集群内客户端→DNS→ClusterIP 的转发实现→Pod→依赖。Service 是抽象,ClusterIP 不对应一台固定服务器。
kubectl -n orders get service orders-api -o yaml
kubectl -n orders get endpointslices -l kubernetes.io/service-name=orders-api -o yaml
kubectl -n orders get pod -l app.kubernetes.io/name=orders-api -o wide
kubectl -n kube-system get ds,deploy
kubectl get networkpolicy -A记录 selector、port/targetPort、ready 后端、节点/AZ,以及实际使用 kube-proxy 还是 CNI eBPF 转发。不要同时对两套 dataplane 下结论。
2. 在出问题的网络身份下逐跳测试#
以下 ephemeral container 共享原 Pod 网络与身份;NetworkPolicy 也相同。容器进入后直到 Pod 重建才从对象中消失:
export POD='REPLACE_AFFECTED_CLIENT_POD'
kubectl debug -n orders -it "pod/$POD" --image="$DEBUG_IMAGE" --profile=restricted -- sh在诊断 shell 内执行,IP 从第一步获取,不填写虚构生产地址:
cat /etc/resolv.conf
dig orders-api.orders.svc.cluster.local
dig +tcp orders-api.orders.svc.cluster.local
curl -sv --connect-timeout 3 --max-time 10 http://orders-api.orders.svc.cluster.local/readyz
curl -sv --connect-timeout 3 --max-time 10 http://REPLACE_CLUSTER_IP/readyz
curl -sv --connect-timeout 3 --max-time 10 http://REPLACE_READY_POD_IP:8080/readyz| 对比结果 | 优先查 |
|---|---|
| IP 通、域名不通 | DNS 服务/转发、UDP/TCP 53、search/ndots;见 CoreDNS |
| Pod IP 通、ClusterIP 不通 | Service 端口、EndpointSlice、kube-proxy/eBPF service map |
| 同节点通、跨节点不通 | CNI 路由/隧道、节点防火墙、MTU、网络策略 |
| 集群内通、入口失败 | LB health check、Gateway route/TLS、安全组和数据面策略 |
| 偶发超时 | conntrack、SNAT 端口、丢包、CPU throttling、DNS 上游 |
3. 注入一个可撤销的 Service 错配#
不修改正式 Service;复制它并故意选择不存在的后端:
kubectl -n orders get svc orders-api -o json | jq '
del(.status,.metadata.uid,.metadata.resourceVersion,.metadata.creationTimestamp,.metadata.managedFields,.metadata.annotations) |
.metadata.name="orders-net-check" |
del(.spec.clusterIP,.spec.clusterIPs,.spec.ipFamilies,.spec.ipFamilyPolicy) |
.spec.type="ClusterIP" |
.spec.selector={"app.kubernetes.io/name":"missing-backend"}
' > net-check.json
kubectl apply -f net-check.json
kubectl -n orders get endpointslices -l kubernetes.io/service-name=orders-net-check
kubectl -n orders patch svc orders-net-check --type=merge -p '{"spec":{"selector":{"app.kubernetes.io/name":"orders-api"}}}'
kubectl -n orders get endpointslices -l kubernetes.io/service-name=orders-net-check在第二步 shell 中对 orders-net-check.orders.svc.cluster.local 重试,观察无 ready 后端→恢复。记录 DNS 可解析并不意味着应用可达。
4. 节点、出口和 IP 容量#
自建节点只读采集:
ip route
ip -s link
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
sudo conntrack -S抓包前限定目标/端口、时长和访问权限,避免采集业务正文。MTU 测试要考虑底层+隧道封装,不直接全局改 MTU。EKS 核对子网剩余 IP、ENI/前缀分配及 Pod 密度;GKE 核对 secondary ranges、节点 Pod CIDR 分配和 maxPods。扩节点不一定解决 IP 耗尽。
验收:入口、跨节点服务、DNS TCP/UDP、私有数据库和云 API 出口均有正向证据,隔离策略有反向拒绝证据。清理 kubectl -n orders delete svc orders-net-check;诊断容器随受控滚动重建清除,不为此强制重启生产业务。