K8S故障處理指南:網絡問題排查思路

1. 前言
對于私有化環境,客戶的網絡架構,使用的云平臺存在著各種差異,K8S網絡可能會出現各種問題,此文著重講解遇到此種問題的排查方法和思路,不會涉及相關網絡底層技術描述。
環境說明
由于我們的k8s網絡組件默認使用了flannel,這里描述的集群網絡,均為flannel。但如果你使用了其他CNI組件,依然可以參考此文章的排查思路。
2. 異常場景
如何判斷k8s集群網絡出現異常?
- 當集群出現pods大量異常,日志顯示dns解析失敗,或者節點間網絡連接失敗等,即可判斷是集群網絡異常。
我們可以通過如下幾種方式進行排查。當任何一種方式的結果非預期內,則確認k8s集群網絡出現異常。
排查步驟
- 測試節點互ping
可以按照如下步驟操作:
查詢node名稱,podcidr,address并打印。
[root@localhost ~]# kubectl get nodes -o jsonpath='{range .items[*]}[name:{.metadata.name} , podCIDR:{.spec.podCIDR} , ipaddr:{.status.addresses[0].address}]{"\n"} {end}'
[name:10.28.87.59 , podCIDR:172.27.1.0/24 , ipaddr:10.28.87.59]
[name:10.28.87.60 , podCIDR:172.27.0.0/24 , ipaddr:10.28.87.60]
[name:10.28.87.61 , podCIDR:172.27.2.0/24 , ipaddr:10.28.87.61]
[name:10.28.87.62 , podCIDR:172.27.4.0/24 , ipaddr:10.28.87.62]
[name:10.28.87.63 , podCIDR:172.27.3.0/24 , ipaddr:10.28.87.63]
[name:10.28.87.64 , podCIDR:172.27.5.0/24 , ipaddr:10.28.87.64]此命令需要在所有節點下執行,可在部署機器上使用ansible調用使用上述命令獲取到的CIDR地址,進行ping操作,seq根據節點數量進行設置。
從上面結果可以看到共6個K8S節點,子網分別是172.27.0-172.27.5子網段。
使用下邊shell腳本測試pod子網,通的話打印up。
[root@localhost ~]# for ip in $(seq 0 5);do ping -c2 -W1 -q 172.27.$ip.1 2>1 &>/dev/null && echo "172.27.$ip.1 up" || echo "172.27.$ip.1 down";done
172.27.0.1 up
172.27.1.1 up
172.27.2.1 up
172.27.3.1 up
172.27.4.1 up
172.27.5.1 up非預期結果: 出現某個節點固定的ping異常,即認為對應節點間vxlan通信異常,檢查對應節點的網絡即可。
- tcp,udp查詢
需要在所有節點上執行,可在一臺機器上使用ansible調用。
ping操作屬于三層操作,由于某些環境會禁ping,因此我們可以使用如下命令進行確認。
使用http請求訪問coredns metrics接口,狀態碼為200時正常,狀態碼000代表網絡異常不通。
[root@CentOS76 ~]# kubectl get pods -n kube-system -o wide | grep coredns | awk '{print $6}' | xargs -i curl --connect-timeout 2 -o /dev/null -s -w "%{http_code}\n" http://{}:9153/metrics
200
200
200
200
200
200使用dns查詢kubernetes.default地址。有返回則代表正常。
[root@localhost ~]# kubectl get pods -n kube-system -o wide | grep coredns | awk '{print $6}' | xargs -l nslookup -type=a kubernetes.default.svc.cluster.local
Server: 172.27.2.23
Address: 172.27.2.23#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------
Server: 172.27.1.131
Address: 172.27.1.131#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------
Server: 172.27.3.57
Address: 172.27.3.57#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------
Server: 172.27.0.29
Address: 172.27.0.29#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------
Server: 172.27.5.53
Address: 172.27.5.53#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------
Server: 172.27.4.65
Address: 172.27.4.65#53
Name: kubernetes.default.svc.cluster.local
Address: 172.26.0.1
---------非預期結果:dns查詢報connection timed out; no servers could be reached, curl報000,都代表網絡可能存在異常。
3. 異常場景
當我們通過上述方式,確認集群節點存在異常時,可以使用如下思路進行逐一排查。
- ip_forward內核被重置為0
- flannel通信異常
- 啟用了firewalld防火墻
- 啟用了安全軟件
- ip_forward
名詞解釋:ip_forward代表了路由轉發特性,為0時不開啟,設置為1時代表啟用。由于vxlan的跨三層特性, 集群節點需要轉發目標主機非自己的數據包。
影響范圍: 如果此值設為0,會導致跨節點通信異常。
出現原因:在部署時,會向/etc/sysctl.conf里邊添加net.ipv4.ip_forward=1,來保證永久生效。
問題定位:出現在集群重啟后,發現pods異常,網絡不通. 通過tcmdump抓包發現flannel流量正常。
處理方式
查詢本機內核參數, 在所有節點上執行,可在部署機上使用ansible調用,為讀操作,可放心執行。
[root@localhost ~]# sysctl -n net.ipv4.ip_forward
0打印sysctl加載鏈,會變更相關內核參數,生產環境禁用使用(如果出現ip_forward為0則可使用)。
[root@localhost ~]# sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
......
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
.....
* Applying /usr/lib/sysctl.d/50-default.conf ...
.......
* Applying /etc/sysctl.d/99-sysctl.conf ...
.......
* Applying /etc/sysctl.conf ...
.......找到具體是哪個文件修改了ip_forward為0,則修改此文件,并重載內核參數。無異常禁止使用。
[root@localhost ~]# sysctl -p- flannel通信異常
名詞說明: vxlan是vlan的拓展協議,為overlay網絡,可以穿透三層網絡對二層進行擴展,即大二層網絡。flannel我們默認使用了vxlan做為封裝協議,端口為8472。
影響范圍: 跨節點通信異常。
問題定位: 對udp 8472端口抓發,發現只有出站流量,未有入站流量,即可認定為flannel vxlan通信異常。
出現原因: 安全組封禁,vxlan端口沖突,網卡異常等。由于flannel異常的原因多種多樣,此次僅針對常見情況進行描述。建議具體問題具體分析。
問題處理: 使用nc等相關命令進行測試,如果抓包仍未發現入站流量,且其他udp端口正常,則可使用修改port的方式。
添加Port字段,將通信端口修改為8475。
[root@localhost ~]# kubectl edit cm -n kube-system kube-flannel-cfg
net-conf.json: |
{
"Network": "172.27.0.0/16",
"Backend": {
"Type": "vxlan",
"Port": 8475
}
}修改后需要重啟相關daemonset pods。
[root@localhost ~]# kubectl get pods -n kube-system | grep flannel | xargs kubectl delete pods -n kube-system修改port不生效,可使用host-gw 如果內網各節點二層互通,可使用host-gw模式,此模式兼容性好,網絡效率高。
[root@localhost ~]# kubectl edit cm -n kube-system kube-flannel-cfg
net-conf.json: |
{
"Network": "172.27.0.0/16",
"Backend": {
"Type": "host-gw",
}如果無法定位問題,可以通過抓包的方式來判斷。
例如:當時coredns網絡不通時,通過curl測試。
curl -I 10.187.1.24:9153/metrics然后再開一個窗口抓包。
tcpdump -nn -i flannel.1 host 10.187.1.24 and port 9153 -vv防火墻排查
名詞解釋: 此處的防火墻指Linux的軟件防火墻,在Cenots上叫firewalld, 在UOS下叫UFW. 默認的軟件防火墻會導致相關數據庫被攔截。
影響范圍: 特定服務訪問異常,集群節點互通異常。
問題定位: 對iptables表鏈進行分析,發現有非預期的規則出現,則代表存在其他防火墻規則。
出現原因: 客戶安裝安全軟件,或者是非預期的軟件行為導致。
問題排查:
一般看到ufw, public, zone這種,都可能是默認的系統防火墻。
[root@localhost ~]# iptables-save | egrep "^:" | egrep -v "KUBE|CNI|DOCKER"
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]發現后手動關閉,以centos7為例。
[root@localhost ~]# systemctl stop firewalldiptables FORWARD轉發鏈添加了REJECT規則,該規則在ACCEPT之上。

刪除規則后正常。
iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited常見安全軟件排查。
qaxsafed # 奇安信,
sangfor_watchdog # 深信服安全軟件
YDservice #qcloud安全軟件,影響pod和docker橋接網絡
Symantec #賽門鐵克的安全軟件
start360su_safed #360安全軟件
gov_defence_service
gov_defence_guard # ps aux | grep defence
wsssr_defence_daemon # 奇安信服務器安全加固軟件
wsssr_defence_service
wsssr_defence_agent #影響pod網絡
kesl #卡巴斯基安全軟件,影響容器通信名詞解釋: 和在windows環境下是一樣的,xc背景下,linux的各類安全軟件也非常多,如奇安信,深信服等。
影響范圍: 特定服務訪問異常。
問題定位: 以上所有排查方式都嘗試過,則可往此方面排查。
出現原因: 客戶安全軟件在內核網絡層hook了對應函數,相關規則過濾了特定的應用數據庫,導致異常。































