在 K8s 跨集群網(wǎng)絡(luò)出現(xiàn)問題時,你會首先排查哪些常見的網(wǎng)絡(luò)層問題?如果這些都排除了,你會繼續(xù)如何深入排查?
引言
面對這樣的情況,你們公司的處理流程是怎么樣的呢,如果你還沒有遇到過,就先提前預(yù)防下。
最后有相關(guān)的群聊,有興趣可以加入。
開始
問題場景還原
背景:
開發(fā)團(tuán)隊報告測試集群A的Pod(10.0.1.5)無法訪問生產(chǎn)集群B的Service(prod-svc.prod-ns:8080),運維團(tuán)隊確認(rèn)NetworkPolicy允許跨集群流量,安全團(tuán)隊要求審計全鏈路日志。
核心矛盾:
技術(shù)層面:跨集群網(wǎng)絡(luò)策略、DNS解析、CNI插件兼容性問題協(xié)作層面:部門間信息孤島、排查流程不透明
一、場景深度拆解與拓?fù)浞治?/span>
1.1 典型多集群架構(gòu)拓?fù)鋱D
測試集群A(AWS EKS) 生產(chǎn)集群B(Azure AKS)
┌───────────────────────┐ ┌───────────────────────┐
│ Namespace: test │ │ Namespace: prod │
│ Pod CIDR: 10.0.1.0/24│ │ Pod CIDR: 10.1.1.0/24│
│ ┌───────────────┐ │ │ ┌───────────────┐ │
│ │ test-pod ├──┐ │ │ │ prod-svc │ │
│ │ 10.0.1.5 │ │ │ │ │ ClusterIP │ │
│ └───────┬───────┘ │ │ │ │ 10.96.1.123 │ │
│ │ │ │ │ └───────┬───────┘ │
│ │ │ │ │ │ │
│ ┌───────▼───────┐ │ │ │ ┌───────▼───────┐ │
│ │ Cilium CNI │ │ │跨云VPC對等連接 │ │ Calico CNI │ │
│ │ BGP Peer ?──┼─┼───────────────────────────? BGP Router │ │
│ └───────┬───────┘ │ │ │ └───────┬───────┘ │
│ │ │ │ │ │ │
└──────────┼───────────┘ └──────────┼───────────┘
│ │
▼ ▼
AWS VPC (vpc-123456) Azure VNet (vnet-7890)
1.2 關(guān)鍵路徑分析
請求路徑:
test-pod (10.0.1.5) → Cilium CNI → AWS Transit Gateway → Azure ExpressRoute → Calico CNI → prod-svc (10.96.1.123)
潛在故障點:
1. 跨云網(wǎng)絡(luò)路由配置(BGP傳播狀態(tài))
2. 集群間防火墻規(guī)則(安全組/NSG)
3. CNI插件MTU不匹配導(dǎo)致分片丟失
4. 服務(wù)網(wǎng)格mTLS強(qiáng)制策略
5. CoreDNS泛域名解析配置
二、kubectl debug全流程實操(含20+診斷命令)
2.1 創(chuàng)建臨時調(diào)試容器(生產(chǎn)級技巧)
# 在測試集群A創(chuàng)建共享網(wǎng)絡(luò)命名空間的調(diào)試容器
kubectl debug -it test-pod-5dfd5d9f7c-abcde \
--image=nicolaka/netshoot:latest \
--copy-to=network-debugger \
--namespace=test \
--target=test-pod-5dfd5d9f7c-abcde \
-- sh
# 驗證容器網(wǎng)絡(luò)棧綁定
ip addr show eth0 | grep 'inet '
# 預(yù)期輸出:10.0.1.5/24(與目標(biāo)Pod相同IP)
2.2 分層診斷手冊(逐層排除)
第1層:物理網(wǎng)絡(luò)連通性
# 測試基礎(chǔ)ICMP連通性(注意生產(chǎn)環(huán)境可能禁用ICMP)
ping -c 4 10.96.1.123
mtr -n -t -4 10.96.1.123 -P 8080 --tcp --interval 1
# 檢查路由表
ip route get 10.96.1.123
# 期望輸出:via 10.0.1.1 dev eth0 src 10.0.1.5
# 驗證AWS VPC對等連接狀態(tài)
aws ec2 describe-vpc-peering-connections \
--filters Name=status-code,Values=active \
--query "VpcPeeringConnections[?RequesterVpcInfo.VpcId=='vpc-123456']"
第2層:傳輸層驗證
# TCP端口連通性測試(替代telnet)
timeout 5 bash -c "</dev/tcp/10.96.1.123/8080" && echo "Success" || echo "Failure"
# 使用socat進(jìn)行雙向握手驗證
socat -d -d -v TCP4:10.96.1.123:8080 STDIO 2>&1 | grep 'starting connect'
# 檢查conntrack表(排查NAT問題)
conntrack -L -d 10.96.1.123 -p tcp --dport 8080
第3層:Kubernetes服務(wù)發(fā)現(xiàn)
# 解析生產(chǎn)集群Service DNS
dig +short prod-svc.prod-ns.svc.cluster.local @10.96.0.10
# 期望輸出:10.96.1.123
# 檢查CoreDNS配置映射
kubectl get configmap coredns -n kube-system -o yaml | grep 'forward .* /etc/resolv.conf'
# 跨集群DNS劫持測試
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- \
nslookup prod-svc.prod-ns.svc.cluster.az1.cloudapp.azure.com
第4層:網(wǎng)絡(luò)策略深度審計
# 導(dǎo)出兩集群所有NetworkPolicy
kubectl get networkpolicies -A -o yaml > clusterA-netpols.yaml
kubectl --context=clusterB get networkpolicies -A -o yaml > clusterB-netpols.yaml
# 使用Calico的calicoctl診斷工具
calicoctl get networkpolicy -o wide --all-namespaces
# 策略模擬測試(需Calico企業(yè)版)
calicoctl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: PolicySimulation
metadata:
name: cross-cluster-test
spec:
source:
namespace: test
serviceAccountName: default
destination:
namespace: prod
podSelector: app=prod-svc
protocol: TCP
port: 8080
EOF
第5層:服務(wù)網(wǎng)格攔截分析
# 檢查Istio Sidecar注入狀態(tài)
istioctl proxy-config listeners test-pod-5dfd5d9f7c-abcde.test
# 強(qiáng)制繞過Sidecar測試
curl -H "Host: prod-svc.prod-ns.svc.cluster.local" \
--connect-to "prod-svc.prod-ns.svc.cluster.local:8080:10.96.1.123:8080" \
http://prod-svc.prod-ns.svc.cluster.local:8080/api/test
# 解密mTLS握手過程
openssl s_client -connect 10.96.1.123:8080 -debug -state -tlsextdebug -cert client.crt -key client.key
2.3 高級診斷工具鏈
# 使用Cilium Hubble進(jìn)行實時流量追蹤
hubble observe --from-ip 10.0.1.5 --to-ip 10.96.1.123 --verdict DROPPED -o json
# 生成網(wǎng)絡(luò)策略沖突報告
kubectl get networkpolicy -o json | jq '[.items[] | {name: .metadata.name, rules: .spec}]' > netpol-audit.json
# 跨集群抓包分析(需特權(quán)模式)
kubectl debug --image=corfr/tcpdump -it capture-tool --namespace=prod -- \
tcpdump -i any -s 0 'host 10.0.1.5 and port 8080' -w /tmp/capture.pcap
三、跨部門協(xié)作標(biāo)準(zhǔn)化模板(含30+字段說明)
3.1 《多集群網(wǎng)絡(luò)故障協(xié)同排查報告》模板
# 故障追蹤ID:[INC-20240220-001]
## 1. 故障概況
| 字段 | 填寫說明 |
|---------------------|--------------------------------------------------------------------------|
| 受影響服務(wù) | prod-svc.prod-ns (v1.2.3) |
| 故障模式 | 持續(xù)性超時/間歇性中斷/認(rèn)證失敗 |
| SLA影響等級 | P1(核心業(yè)務(wù)不可用) |
| 跨部門參與團(tuán)隊 | 開發(fā)團(tuán)隊(@dev-lead)、運維團(tuán)隊(@ops-lead)、安全團(tuán)隊(@sec-lead) |
## 2. 環(huán)境拓?fù)湓斍?```yaml
network_topology:
clusterA:
cloud_provider: AWS
region: us-west-2
cni: Cilium 1.13.5
service_mesh: Istio 1.18.3
k8s_version: v1.27.4
network_policies:
- name: allow-cross-cluster
selector: app=test-pod
ports: 8080/TCP
clusterB:
cloud_provider: Azure
region: eastus
cni: Calico 3.25.0
service_mesh: Linkerd 2.12.4
k8s_version: v1.26.7
firewall_rules:
- name: allow-inbound-8080
source: 10.0.1.0/24
port: 8080
3. 多維度排查記錄
3.1 開發(fā)團(tuán)隊輸入
{
"復(fù)現(xiàn)步驟": "kubectl exec -it test-pod -- curl -m 10 http://prod-svc.prod-ns:8080/health",
"錯誤日志": "curl: (28) Connection timed out after 10001 ms",
"業(yè)務(wù)影響面": ["訂單支付流程", "數(shù)據(jù)分析看板"]
}
3.2 運維團(tuán)隊發(fā)現(xiàn)
# ClusterB入口流量監(jiān)控
$ kubectl logs -l app=prod-svc -n prod --since=5m | grep '10.0.1.5'
< 無結(jié)果輸出 >
# NetworkPolicy審計
$ calicoctl get networkpolicy -n prod -o yaml | grep '10.0.1.5'
- 10.0.1.0/24 # 確認(rèn)允許測試集群CIDR
3.3 安全團(tuán)隊證據(jù)
Falco告警日志:
16:02:33.511: "Unexpected cross-cluster connection"
src_ip=10.0.1.5 dst_ip=10.96.1.123 protocol=TCP
WireShark解密流量:
Frame 1234: 78 bytes on wire
Ethernet II: 00:0d:3a:cd:02:01 -> 00:0d:3a:cd:02:02
Internet Protocol: 10.0.1.5 -> 10.96.1.123
Transmission Control Protocol: [SYN] Seq=0 Win=64240 Len=0
4. 根本原因分析(RCA)
圖片
5. 修復(fù)與驗證方案
5.1 緊急修復(fù)
# 調(diào)整Cilium MTU配置
helm upgrade cilium cilium/cilium -n kube-system \
--set global.mtu=1450 \
--set global.tunnel=disabled
# 臨時放寬Azure NSG規(guī)則
az network nsg rule create -g prod-rg --nsg-name prod-nsg \
--name allow-fragments \
--protocol '*' \
--source-address-prefixes 10.0.1.0/24 \
--destination-address-prefixes 10.96.1.0/24 \
--access Allow \
--priority 1000
5.2 驗證步驟
# 分階段驗證腳本
#!/bin/bash
validate_mtu() {
kubectl exec -it $1 -- ping -M do -s 1472 -c 4 $2 | grep "0% packet loss"
}
validate_mtu "test-pod" "10.96.1.123"
validate_mtu "prod-svc-pod" "10.0.1.5"
6. 事后復(fù)盤與改進(jìn)
6.1 技術(shù)債務(wù)清理
? CNI插件統(tǒng)一化(Cilium → Calico)
? 實施跨集群MTU自動探測機(jī)制
6.2 流程改進(jìn)
新流程:
1. 建立跨集群通信預(yù)檢清單(含MTU/DNS/防火墻等20項)
2. 實施變更前的自動化冒煙測試
3. 每周跨部門網(wǎng)絡(luò)演練(Chaos Engineering)
6.3 監(jiān)控增強(qiáng)
# Prometheus監(jiān)控規(guī)則新增
-alert:CrossClusterMTUMismatch
expr:increase(cilium_drop_bytes_total{reasnotallow="Fragmentationneeded"}[5m])>0
for:5m
labels:
severity:critical
annotations:
summary: "跨集群MTU不匹配導(dǎo)致分片丟失"
四、跨部門協(xié)作SOP(含溝通機(jī)制設(shè)計)
4.1 協(xié)作流程圖
圖片
4.2 關(guān)鍵溝通話術(shù)模板
【緊急故障召集令】
標(biāo)題:[P1] 跨集群網(wǎng)絡(luò)中斷 - 需立即響應(yīng)
參與方:@dev-lead @ops-lead @sec-lead
會議時間:立即(15分鐘內(nèi))
準(zhǔn)備材料:
1. 測試集群kubeconfig(有效期2小時)
2. 生產(chǎn)集群只讀審計賬號
3. 最近1小時網(wǎng)絡(luò)監(jiān)控截圖
【跨部門爭議解決】
當(dāng)出現(xiàn)責(zé)任歸屬爭議時:
"根據(jù)SLA第3.2條,網(wǎng)絡(luò)策略的生效驗證屬于運維團(tuán)隊職責(zé)范圍,
建議立即執(zhí)行以下命令驗證策略實際生效情況:
kubectl --cnotallow=clusterB get networkpolicy -n prod -o yaml | grep '10.0.1.0/24'"
4.3 自動化協(xié)作工具鏈
# 使用Crossplane統(tǒng)一管理多集群配置
kubectl apply -f - <<EOF
apiVersion: networking.crossplane.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
name: cross-cluster-allow
spec:
forProvider:
sourceCluster: clusterA
destinationCluster: clusterB
port: 8080
protocol: TCP
providerConfigRef:
name: aws-azure-config
EOF
# 集成Jira自動化工作流
curl -X POST -H "Content-Type: application/json" \
-d '{"fields":{"project":{"key":"INFRA"},"summary":"網(wǎng)絡(luò)故障跟蹤","description":"詳見附件報告"}}' \
https://jira.example.com/rest/api/2/issue/
五、專家級調(diào)試技巧(生產(chǎn)環(huán)境驗證)
5.1 eBPF深度觀測
# 使用Cilium監(jiān)控TCP重傳
cilium monitor -t drop -t trace --related-to 10.0.1.5
# 捕獲TCP握手失敗事件
bpftool prog load kprobe:tcp_connect ./tcp_connect.bpf.o
bpftool prog tracelog
# 輸出示例:
[4026531993] test-pod-5dfd5d9f7c-abcde connect() to 10.96.1.123:8080 failed with ECONNREFUSED
5.2 內(nèi)核級問題定位
# 跟蹤iptables規(guī)則匹配
iptables -t nat -nvL CILIUM_OUTPUT --line-numbers
# 檢查conntrack表狀態(tài)
conntrack -L -d 10.96.1.123 -p tcp --dport 8080 -o extended
# 抓取SYN包但無ACK響應(yīng)
tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn' -vvv
5.3 混沌工程驗證
# 使用chaos-mesh模擬網(wǎng)絡(luò)中斷
kubectl apply -f - <<EOF
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: cross-cluster-loss
spec:
action: loss
mode: one
selector:
namespaces: ["prod"]
loss:
loss: "100%"
direction: from
target:
mode: all
selector:
namespaces: ["test"]
EOF