<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Kubernetes 網(wǎng)絡(luò)排錯(cuò)終極指南

          共 24163字,需瀏覽 49分鐘

           ·

          2023-09-20 14:17

          本文將引入一個(gè)思路:“在 Kubernetes 集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查”。文章將引入 Kubernetes 集群中網(wǎng)絡(luò)排查的思路,包含網(wǎng)絡(luò)異常模型、常用工具,并且提出一些案例以供學(xué)習(xí)。


          一、Pod 網(wǎng)絡(luò)異常


          網(wǎng)絡(luò)異常大概分為如下幾類:



          1.網(wǎng)絡(luò)不可達(dá)


          主要現(xiàn)象為 ping 不通,其可能原因?yàn)椋?/span>


          • 源端和目的端防火墻(iptables、selinux)限制

          • 網(wǎng)絡(luò)路由配置不正確

          • 源端和目的端的系統(tǒng)負(fù)載過高,網(wǎng)絡(luò)連接數(shù)滿,網(wǎng)卡隊(duì)列滿

          • 網(wǎng)絡(luò)鏈路故障



          2.端口不可達(dá)


          主要現(xiàn)象為可以 ping 通,但 telnet 端口不通,其可能原因?yàn)椋?/span>


          • 源端和目的端防火墻限制

          • 源端和目的端的系統(tǒng)負(fù)載過高,網(wǎng)絡(luò)連接數(shù)滿,網(wǎng)卡隊(duì)列滿,端口耗盡

          • 目的端應(yīng)用未正常監(jiān)聽導(dǎo)致(應(yīng)用未啟動(dòng),或監(jiān)聽為 127.0.0.1 等)



          3.DNS 解析異常


          主要現(xiàn)象為基礎(chǔ)網(wǎng)絡(luò)可以連通,訪問域名報(bào)錯(cuò)無法解析,訪問 IP 可以正常連通。其可能原因?yàn)椋?/span>


          • Pod 的 DNS 配置不正確

          • DNS 服務(wù)異常

          • Pod 與 DNS 服務(wù)通訊異常



          4.大數(shù)據(jù)包丟包


          主要現(xiàn)象為基礎(chǔ)網(wǎng)絡(luò)和端口均可以連通,小數(shù)據(jù)包收發(fā)無異常,大數(shù)據(jù)包丟包??赡茉?yàn)椋?/span>


          • 可使用 ping -s 指定數(shù)據(jù)包大小進(jìn)行測試

          • 數(shù)據(jù)包的大小超過了 Docker、CNI 插件、或者宿主機(jī)網(wǎng)卡的 MTU 值。



          5.CNI 異常


          主要現(xiàn)象為 Node 可以通,但 Pod 無法訪問集群地址,可能原因有:


          • kube-proxy 服務(wù)異常,沒有生成 iptables 策略或者 ipvs 規(guī)則導(dǎo)致無法訪問

          • CIDR 耗盡,無法為 Node 注入 PodCIDR 導(dǎo)致 CNI 插件異常



          6.其他 CNI 插件問題


          那么整個(gè) Pod 網(wǎng)絡(luò)異常分類可以如下圖所示:



          總結(jié)一下,Pod 最常見的網(wǎng)絡(luò)故障有,網(wǎng)絡(luò)不可達(dá)(ping 不通);端口不可達(dá)(telnet 不通);DNS 解析異常(域名不通)與大數(shù)據(jù)包丟失(大包不通)。


          二、常用網(wǎng)絡(luò)排查工具


          在了解到常見的網(wǎng)絡(luò)異常后,在排查時(shí)就需要使用到一些網(wǎng)絡(luò)工具才可以很有效的定位到網(wǎng)絡(luò)故障原因,下面會(huì)介紹一些網(wǎng)絡(luò)排查工具。



          1.tcpdump


          tcpdump 網(wǎng)絡(luò)嗅探器,將強(qiáng)大和簡單結(jié)合到一個(gè)單一的命令行界面中,能夠?qū)⒕W(wǎng)絡(luò)中的報(bào)文抓取,輸出到屏幕或者記錄到文件中。


          各系統(tǒng)下的安裝:


          • Ubuntu/Debian: tcpdump;apt-get install -y tcpdump

          • Centos/Fedora: tcpdump;yum install -y tcpdump

          • Apline:tcpdump ;apk add tcpdump --no-cache


          查看指定接口上的所有通訊。


          語法:


          捕獲所有網(wǎng)絡(luò)接口:


          tcpdump -D


          按 IP 查找流量:最常見的查詢之一 host,可以看到來往于 1.1.1.1 的流量。


          tcpdump host 1.1.1.1


          按源 / 目的 地址過濾:如果只想查看來自 / 向某方向流量,可以使用 src 和 dst。


          tcpdump src|dst 1.1.1.1


          通過網(wǎng)絡(luò)查找數(shù)據(jù)包:


          使用 net 選項(xiàng),來要查找出 / 入某個(gè)網(wǎng)絡(luò)或子網(wǎng)的數(shù)據(jù)包。


          tcpdump net 1.2.3.0/24


          使用十六進(jìn)制輸出數(shù)據(jù)包內(nèi)容:


          hex 可以以 16 進(jìn)制輸出包的內(nèi)容


          tcpdump -c 1 -X icmp


          查看特定端口的流量:


          使用 port 選項(xiàng)來查找特定的端口流量。


          tcpdump port 3389tcpdump src port 1025


          查找端口范圍的流量:


          tcpdump portrange 21-23


          過濾包的大?。?/span>


          如果需要查找特定大小的數(shù)據(jù)包,可以使用以下選項(xiàng)。你可以使用 less,greater。


          tcpdump less 32tcpdump greater 64tcpdump <= 128


          捕獲流量輸出為文件:


          -w 可以將數(shù)據(jù)包捕獲保存到一個(gè)文件中以便將來進(jìn)行分析。這些文件稱為 PCAP(PEE-cap)文件,它們可以由不同的工具處理,包括 Wireshark 。


          tcpdump port 80 -w capture_file


          組合條件:


          tcpdump 也可以結(jié)合邏輯運(yùn)算符進(jìn)行組合條件查詢:


          • ANDand or &&

          • ORor or ||

          • EXCEPTnot or !


          tcpdump -i eth0 -nn host 220.181.57.216 and 10.0.0.1  # 主機(jī)之間的通訊tcpdump -i eth0 -nn host 220.181.57.216 or 10.0.0.1# 獲取10.0.0.1與 10.0.0.9或 10.0.0.1 與10.0.0.3之間的通訊tcpdump -i eth0 -nn host 10.0.0.1 and \(10.0.0.9 or 10.0.0.3\)


          原始輸出:


          并顯示人類可讀的內(nèi)容進(jìn)行輸出包(不包含內(nèi)容)。


          tcpdump -ttnnvvS -i eth0tcpdump -ttnnvvS -i eth0


          IP 到端口:


          讓我們查找從某個(gè) IP 到端口任何主機(jī)的某個(gè)端口所有流量。


          tcpdump -nnvvS src 10.5.2.3 and dst port 3389


          去除特定流量:


          可以將指定的流量排除,如這顯示所有到 192.168.0.2 的 非 ICMP 的流量。


          tcpdump dst 192.168.0.2 and src net and not icmp


          來自非指定端口的流量,如,顯示來自不是 SSH 流量的主機(jī)的所有流量。


          tcpdump -vv src mars and not dst port 22


          選項(xiàng)分組:


          在構(gòu)建復(fù)雜查詢時(shí),必須使用單引號(hào) '。單引號(hào)用于忽略特殊符號(hào) () ,以便于使用其他表達(dá)式(如 host, port, net 等)進(jìn)行分組。


          tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'


          過濾 TCP 標(biāo)記位。


          TCP RST:


          下面的過濾器可以找到這些不同的數(shù)據(jù)包,因?yàn)閠cp[13]看的是TCP頭中的偏移量13,數(shù)字代表字節(jié)內(nèi)的位置,而!=0意味著相關(guān)的標(biāo)志被設(shè)置為1,即它是打開的。


          tcpdump 'tcp[13] & 4!=0'tcpdump 'tcp[tcpflags] == tcp-rst'


          TCP SYN:


          tcpdump 'tcp[13] & 2!=0'tcpdump 'tcp[tcpflags] == tcp-syn'


          同時(shí)忽略 SYN 和 ACK 標(biāo)志的數(shù)據(jù)包。


          tcpdump 'tcp[13]=18'


          TCP URG:


          tcpdump 'tcp[13] & 32!=0'tcpdump 'tcp[tcpflags] == tcp-urg'


          TCP ACK:


          tcpdump 'tcp[13] & 16!=0'tcpdump 'tcp[tcpflags] == tcp-ack'


          TCP PSH:


          tcpdump 'tcp[13] & 8!=0'tcpdump 'tcp[tcpflags] == tcp-push'


          TCP FIN:


          tcpdump 'tcp[13] & 1!=0'tcpdump 'tcp[tcpflags] == tcp-fin'


          查找 http 包。


          查找 user-agent 信息:


          tcpdump -vvAls0 | grep 'User-Agent:'


          查找只是 GET 請求的流量:


          tcpdump -vvAls0 | grep 'GET'


          查找 http 客戶端 IP:


          tcpdump -vvAls0 | grep 'Host:'


          查詢客戶端 cookie:


          tcpdump -vvAls0 | grep 'Set-Cookie|Host:|Cookie:'


          查找 DNS 流量:


          tcpdump -vvAs0 port 53


          查找對應(yīng)流量的明文密碼:


          tcpdump port http or port ftp or port smtp or port imap or port pop3 or port telnet -lA | egrep -i -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd= |password=|pass:|user:|username:|password:|login:|pass |user '


          wireshark 追蹤流:wireshare 追蹤流可以很好的了解出在一次交互過程中都發(fā)生了那些問題。


          wireshare 選中包,右鍵選擇 “追蹤流“ 如果該包是允許的協(xié)議是可以打開該選項(xiàng)的。


          關(guān)于抓包節(jié)點(diǎn)和抓包設(shè)備:


          如何抓取有用的包,以及如何找到對應(yīng)的接口,有以下建議:


          1)抓包節(jié)點(diǎn)


          通常情況下會(huì)在源端和目的端兩端同時(shí)抓包,觀察數(shù)據(jù)包是否從源端正常發(fā)出,目的端是否接收到數(shù)據(jù)包并給源端回包,以及源端是否正常接收到回包。如果有丟包現(xiàn)象,則沿網(wǎng)絡(luò)鏈路上各節(jié)點(diǎn)抓包排查。


          例如,A 節(jié)點(diǎn)經(jīng)過 c 節(jié)點(diǎn)到 B 節(jié)點(diǎn),先在 AB 兩端同時(shí)抓包,如果 B 節(jié)點(diǎn)未收到 A 節(jié)點(diǎn)的包,則在 c 節(jié)點(diǎn)同時(shí)抓包。


          2)抓包設(shè)備


          對于 Kubernetes 集群中的 Pod,由于容器內(nèi)不便于抓包,通常視情況在 Pod 數(shù)據(jù)包經(jīng)過的 veth 設(shè)備,docker0 網(wǎng)橋,CNI 插件設(shè)備(如 cni0,flannel.1 etc..)及 Pod 所在節(jié)點(diǎn)的網(wǎng)卡設(shè)備上指定 Pod IP 進(jìn)行抓包。


          選取的設(shè)備根據(jù)懷疑導(dǎo)致網(wǎng)絡(luò)問題的原因而定,比如范圍由大縮小,從源端逐漸靠近目的端,比如懷疑是 CNI 插件導(dǎo)致,則在 CNI 插件設(shè)備上抓包。從 pod 發(fā)出的包逐一經(jīng)過 veth 設(shè)備,cni0 設(shè)備,flannel0,宿主機(jī)網(wǎng)卡,到達(dá)對端,抓包時(shí)可按順序逐一抓包,定位問題節(jié)點(diǎn)。


          需要注意在不同設(shè)備上抓包時(shí)指定的源目 IP 地址需要轉(zhuǎn)換,如抓取某 Pod 時(shí),ping {host} 的包,在 veth 和 cni0 上可以指定 Pod IP 抓包,而在宿主機(jī)網(wǎng)卡上如果仍然指定 Pod IP 會(huì)發(fā)現(xiàn)抓不到包,因?yàn)榇藭r(shí) Pod IP 已被轉(zhuǎn)換為宿主機(jī)網(wǎng)卡 IP。


          下圖是一個(gè)使用 VxLAN 模式的 flannel 的跨界點(diǎn)通訊的網(wǎng)絡(luò)模型,在抓包時(shí)需要注意對應(yīng)的網(wǎng)絡(luò)接口。




          2.nsenter


          nsenter 是一款可以進(jìn)入進(jìn)程的名稱空間中。例如,如果一個(gè)容器以非 root 用戶身份運(yùn)行,而使用 docker exec 進(jìn)入其中后,但該容器沒有安裝 sudo 或未 netstat ,并且您想查看其當(dāng)前的網(wǎng)絡(luò)屬性,如開放端口,這種場景下將如何做到這一點(diǎn)?nsenter 就是用來解決這個(gè)問題的。


          nsenter(namespace enter)可以在容器的宿主機(jī)上使用 nsenter 命令進(jìn)入容器的命名空間,以容器視角使用宿主機(jī)上的相應(yīng)網(wǎng)絡(luò)命令進(jìn)行操作。當(dāng)然需要擁有 root 權(quán)限。


          nsenter 的 c 使用語法為,nsenter -t pid -n <commond>,-t 接 進(jìn)程 ID 號(hào),-n 表示進(jìn)入名稱空間內(nèi),為執(zhí)行的命令。


          實(shí)例:如我們有一個(gè) Pod 進(jìn)程 ID 為 30858,進(jìn)入該 Pod 名稱空間內(nèi)執(zhí)行 ifconfig ,如下列所示:


          $ ps -ef|grep tailroot      17636  62887  0 20:19 pts/2    00:00:00 grep --color=auto tailroot      30858  30838  0 15:55 ?        00:00:01 tail -f
          $ nsenter -t 30858 -n ifconfigeth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1480inet 192.168.1.213 netmask 255.255.255.0 broadcast 192.168.1.255ether 5e:d5:98:af:dc:6b txqueuelen 0 (Ethernet)RX packets 92 bytes 9100 (8.8 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 92 bytes 8422 (8.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
          lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0loop txqueuelen 1000 (Local Loopback)RX packets 5 bytes 448 (448.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 5 bytes 448 (448.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
          net1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 10.1.0.201 netmask 255.255.255.0 broadcast 10.1.0.255ether b2:79:f9:dd:2a:10 txqueuelen 0 (Ethernet)RX packets 228 bytes 21272 (20.7 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 216 bytes 20272 (19.7 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


          如何定位 Pod 名稱空間:


          首先需要確定 Pod 所在的節(jié)點(diǎn)名稱。


          $ kubectl get pods -owide |awk '{print $1,$7}'NAME NODEnetbox-85865d5556-hfg6v master-machinenetbox-85865d5556-vlgr4 node01


          如果 Pod 不在當(dāng)前節(jié)點(diǎn)還需要用 IP 登錄則還需要查看 IP(可選)。


          $ kubectl get pods -owide |awk '{print $1,$6,$7}'NAME IP NODEnetbox-85865d5556-hfg6v 192.168.1.213 master-machinenetbox-85865d5556-vlgr4 192.168.0.4 node01


          接下來,登錄節(jié)點(diǎn),獲取容器 lD,如下列所示,每個(gè) pod 默認(rèn)有一個(gè) pause 容器,其他為用戶 yaml 文件中定義的容器,理論上所有容器共享相同的網(wǎng)絡(luò)命名空間,排查時(shí)可任選一個(gè)容器。


          $ docker ps |grep netbox-85865d5556-hfg6v6f8c58377aae   f78dd05f11ff                                                    "tail -f"                45 hours ago   Up 45 hours             k8s_netbox_netbox-85865d5556-hfg6v_default_4a8e2da8-05d1-4c81-97a7-3d76343a323a_0b9c732ee457e   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1   "/pause"                 45 hours ago   Up 45 hours             k8s_POD_netbox-85865d5556-hfg6v_default_4a8e2da8-05d1-4c81-97a7-3d76343a323a_0


          接下來獲得獲取容器在節(jié)點(diǎn)系統(tǒng)中對應(yīng)的進(jìn)程號(hào),如下所示:


          $ docker inspect --format "{{ .State.Pid }}" 6f8c58377aae30858


          最后就可以通過 nsenter 進(jìn)入容器網(wǎng)絡(luò)空間執(zhí)行命令了。



          3.paping


          paping 命令可對目標(biāo)地址指定端口以 TCP 協(xié)議進(jìn)行連續(xù) ping,通過這種特性可以彌補(bǔ) ping ICMP 協(xié)議,以及 nmap、telnet 只能進(jìn)行一次操作的的不足;通常情況下會(huì)用于測試端口連通性和丟包率。


          paping download[2]:


          paping 還需要安裝以下依賴,這取決于你安裝的 paping 版本。


          • RedHat/CentOS:yum install -y libstdc++.i686 glibc.i686

          • Ubuntu/Debian:最小化安裝無需依賴


          $ paping -hpaping v1.5.5 - Copyright (c) 2011 Mike Lovell
          Syntax: paping [options] destination
          Options: -?, --help display usage -p, --port N set TCP port N (required) --nocolor Disable color output -t, --timeout timeout in milliseconds (default 1000) -c, --count N set number of checks to N




          4.mtr


          mtr 是一個(gè)跨平臺(tái)的網(wǎng)絡(luò)診斷工具,將 traceroute 和 ping 的功能結(jié)合到一個(gè)工具。與 traceroute 不同的是 mtr 顯示的信息比起 traceroute 更加豐富:通過 mtr 可以確定網(wǎng)絡(luò)的條數(shù),并且可以同時(shí)打印響應(yīng)百分比以及網(wǎng)絡(luò)中各跳躍點(diǎn)的響應(yīng)時(shí)間。


          簡單的使用示例:


          最簡單的示例,就是后接域名或 IP,這將跟蹤整個(gè)路由。


          $ mtr google.com
          Start: Thu Jun 28 12:10:13 2018HOST: TecMint Loss% Snt Last Avg Best Wrst StDev1.|-- 192.168.0.1 0.0% 5 0.3 0.3 0.3 0.4 0.02.|-- 5.5.5.211 0.0% 5 0.7 0.9 0.7 1.3 0.03.|-- 209.snat-111-91-120.hns.n 80.0% 5 7.1 7.1 7.1 7.1 0.04.|-- 72.14.194.226 0.0% 5 1.9 2.9 1.9 4.4 1.15.|-- 108.170.248.161 0.0% 5 2.9 3.5 2.0 4.3 0.76.|-- 216.239.62.237 0.0% 5 3.0 6.2 2.9 18.3 6.77.|-- bom05s12-in-f14.1e100.net 0.0% 5 2.1 2.4 2.0 3.8 0.5


          -n 強(qiáng)制 mtr 打印 IP 地址而不是主機(jī)名。


          $ mtr -n google.com
          Start: Thu Jun 28 12:12:58 2018HOST: TecMint Loss% Snt Last Avg Best Wrst StDev1.|-- 192.168.0.1 0.0% 5 0.3 0.3 0.3 0.4 0.02.|-- 5.5.5.211 0.0% 5 0.9 0.9 0.8 1.1 0.03.|-- ??? 100.0 5 0.0 0.0 0.0 0.0 0.04.|-- 72.14.194.226 0.0% 5 2.0 2.0 1.9 2.0 0.05.|-- 108.170.248.161 0.0% 5 2.3 2.3 2.2 2.4 0.06.|-- 216.239.62.237 0.0% 5 3.0 3.2 3.0 3.3 0.07.|-- 172.217.160.174 0.0% 5 3.7 3.6 2.0 5.3 1.4


          -b 同時(shí)顯示 IP 地址與主機(jī)名。


          $ mtr -b google.com
          Start: Thu Jun 28 12:14:36 2018HOST: TecMint Loss% Snt Last Avg Best Wrst StDev1.|-- 192.168.0.1 0.0% 5 0.3 0.3 0.3 0.4 0.02.|-- 5.5.5.211 0.0% 5 0.7 0.8 0.6 1.0 0.03.|-- 209.snat-111-91-120.hns.n 0.0% 5 1.4 1.6 1.3 2.1 0.04.|-- 72.14.194.226 0.0% 5 1.8 2.1 1.8 2.6 0.05.|-- 108.170.248.209 0.0% 5 2.0 1.9 1.8 2.0 0.06.|-- 216.239.56.115 0.0% 5 2.4 2.7 2.4 2.9 0.07.|-- bom07s15-in-f14.1e100.net 0.0% 5 3.7 2.2 1.7 3.7 0.9


          -c 跟一個(gè)具體的值,這將限制 mtr ping 的次數(shù),到達(dá)次數(shù)后會(huì)退出。


          $ mtr -c5 google.com


          如果需要指定次數(shù),并且在退出后保存這些數(shù)據(jù),使用 -r flag。


          $ mtr -r -c 5 google.com >  1$ cat 1Start: Sun Aug 21 22:06:49 2022HOST: xxxxx.xxxxx.xxxx.xxxx Loss%   Snt   Last   Avg  Best  Wrst StDev1.|-- gateway                    0.0%     5    0.6 146.8   0.6 420.2 191.4  2.|-- 212.xx.21.241              0.0%     5    0.4   1.0   0.4   2.3   0.53.|-- 188.xxx.106.124            0.0%     5    0.7   1.1   0.7   2.1   0.5  4.|-- ???                       100.0     5    0.0   0.0   0.0   0.0   0.05.|-- 72.14.209.89               0.0%     5   43.2  43.3  43.1  43.3   0.0  6.|-- 108.xxx.250.33             0.0%     5   43.2  43.1  43.1  43.2   0.07.|-- 108.xxx.250.34             0.0%     5   43.7  43.6  43.5  43.7   0.0  8.|-- 142.xxx.238.82             0.0%     5   60.6  60.9  60.6  61.2   0.09.|-- 142.xxx.238.64             0.0%     5   59.7  67.5  59.3  89.8  13.2 10.|-- 142.xxx.37.81              0.0%     5   62.7  62.9  62.6  63.5   0.011.|-- 142.xxx.229.85             0.0%     5   61.0  60.9  60.7  61.3   0.0 12.|-- xx-in-f14.1e100.net  0.0%     5   59.0  58.9  58.9  59.0   0.0


          默認(rèn)使用的是 ICMP 協(xié)議 -i,可以指定 -u、-t 使用其他協(xié)議。


          mtr --tcp google.com


          -m 指定最大的跳數(shù)。


          mtr -m 35 216.58.223.78


          -s 指定包的大小。


          mtr 輸出的數(shù)據(jù):



          丟包判斷:


          任一節(jié)點(diǎn)的 Loss%(丟包率)如果不為零,則說明這一跳網(wǎng)絡(luò)可能存在問題。導(dǎo)致相應(yīng)節(jié)點(diǎn)丟包的原因通常有兩種。


          • 運(yùn)營商基于安全或性能需求,人為限制了節(jié)點(diǎn)的 ICMP 發(fā)送速率,導(dǎo)致丟包。

          • 節(jié)點(diǎn)確實(shí)存在異常,導(dǎo)致丟包??梢越Y(jié)合異常節(jié)點(diǎn)及其后續(xù)節(jié)點(diǎn)的丟包情況,來判定丟包原因。


          Notes:


          • 如果隨后節(jié)點(diǎn)均沒有丟包,則通常說明異常節(jié)點(diǎn)丟包是由于運(yùn)營商策略限制所致??梢院雎韵嚓P(guān)丟包。

          • 如果隨后節(jié)點(diǎn)也出現(xiàn)丟包,則通常說明節(jié)點(diǎn)確實(shí)存在網(wǎng)絡(luò)異常,導(dǎo)致丟包。對于這種情況,如果異常節(jié)點(diǎn)及其后續(xù)節(jié)點(diǎn)連續(xù)出現(xiàn)丟包,而且各節(jié)點(diǎn)的丟包率不同,則通常以最后幾跳的丟包率為準(zhǔn)。如鏈路測試在第 5、6、7 跳均出現(xiàn)了丟包。最終丟包情況以第 7 跳作為參考。


          延遲判斷:


          由于鏈路抖動(dòng)或其它因素的影響,節(jié)點(diǎn)的 Best 和 Worst 值可能相差很大。而 Avg(平均值)統(tǒng)計(jì)了自鏈路測試以來所有探測的平均值,所以能更好的反應(yīng)出相應(yīng)節(jié)點(diǎn)的網(wǎng)絡(luò)質(zhì)量。


          而 StDev(標(biāo)準(zhǔn)偏差值)越高,則說明數(shù)據(jù)包在相應(yīng)節(jié)點(diǎn)的延時(shí)值越不相同(越離散)。所以標(biāo)準(zhǔn)偏差值可用于協(xié)助判斷 Avg 是否真實(shí)反應(yīng)了相應(yīng)節(jié)點(diǎn)的網(wǎng)絡(luò)質(zhì)量。


          例如,如果標(biāo)準(zhǔn)偏差很大,說明數(shù)據(jù)包的延遲是不確定的??赡苣承?shù)據(jù)包延遲很小(例如:25ms),而另一些延遲卻很大(例如:350ms),但最終得到的平均延遲反而可能是正常的。所以此時(shí) Avg 并不能很好的反應(yīng)出實(shí)際的網(wǎng)絡(luò)質(zhì)量情況。


          這就需要結(jié)合如下情況進(jìn)行判斷:


          • 如果 StDev 很高,則同步觀察相應(yīng)節(jié)點(diǎn)的 Best 和 wrst,來判斷相應(yīng)節(jié)點(diǎn)是否存在異常。

          • 如果 StDev 不高,則通過 Avg 來判斷相應(yīng)節(jié)點(diǎn)是否存在異常。


          三、Pod 網(wǎng)絡(luò)排查流程


          Pod網(wǎng)絡(luò)異常時(shí)排查思路,可以按照下圖所示:


          Pod network troubleshooting idea


          四、案例學(xué)習(xí)



          1.擴(kuò)容節(jié)點(diǎn)訪問 service 地址不通


          測試環(huán)境 Kubernetes 節(jié)點(diǎn)擴(kuò)容后無法訪問集群 clusterlP 類型的 registry 服務(wù)。


          環(huán)境信息:



          • CNI 插件:flannel vxlan

          • kube-proxy 工作模式為 iptables

          • Registry 服務(wù)

          • 單實(shí)例部署在 10.61.187.48:5000

          • Pod IP:10.233.65.46,

          • Cluster IP:10.233.0.100


          現(xiàn)象:


          • 所有節(jié)點(diǎn)之間的 pod 通信正常

          • 任意節(jié)點(diǎn)和 Pod curl registry 的 Pod 的 IP:5000 均可以連通

          • 新擴(kuò)容節(jié)點(diǎn) 10.153.204.15 curl registry 服務(wù)的 Cluster lP 10.233.0.100:5000 不通,其他節(jié)點(diǎn) curl 均可以連通


          分析思路:


          • 根據(jù)現(xiàn)象 1 可以初步判斷 CNI 插件無異常

          • 根據(jù)現(xiàn)象 2 可以判斷 registry 的 Pod 無異常

          • 根據(jù)現(xiàn)象 3 可以判斷 registry 的 service 異常的可能性不大,可能是新擴(kuò)容節(jié)點(diǎn)訪問 registry 的 service 存在異常


          懷疑方向:


          • 問題節(jié)點(diǎn)的 kube-proxy 存在異常

          • 問題節(jié)點(diǎn)的 iptables 規(guī)則存在異常

          • 問題節(jié)點(diǎn)到 service 的網(wǎng)絡(luò)層面存在異常


          排查過程:


          排查問題節(jié)點(diǎn)的 kube-proxy


          執(zhí)行 kubectl get pod -owide -nkube-system l grep kube-proxy 查看 kube-proxy Pod 的狀態(tài),問題節(jié)點(diǎn)上的 kube-proxy Pod 為 running 狀態(tài)


          執(zhí)行 kubecti logs <nodename> <kube-proxy pod name> -nkube-system 查看問題節(jié)點(diǎn) kube-proxy 的 Pod 日志,沒有異常報(bào)錯(cuò)


          在問題節(jié)點(diǎn)操作系統(tǒng)上執(zhí)行 iptables -S -t nat 查看 iptables 規(guī)則


          排查過程:


          確認(rèn)存在到 Registry 服務(wù)的 Cluster lP 10.233.0.100 的 KUBE-SERVICES 鏈,跳轉(zhuǎn)至 KUBE-SVC-* 鏈做負(fù)載均衡,再跳轉(zhuǎn)至 KUBE-SEP-* 鏈通過 DNAT 替換為服務(wù)后端 Pod 的 IP 10.233.65.46。因此判斷 iptables 規(guī)則無異常執(zhí)行 route-n 查看問題節(jié)點(diǎn)存在訪問 10.233.65.46 所在網(wǎng)段的路由,如圖所示:


          10.233.65.46 路由


          查看對端的回程路由:


          回程路由


          以上排查證明問題原因不是 CNI 插件或者 kube-proxy 異常導(dǎo)致,因此需要在訪問鏈路上抓包,判斷問題原因、問題節(jié)點(diǎn)執(zhí)行 curl 10.233.0.100:5000,在問題節(jié)點(diǎn)和后端 pod 所在節(jié)點(diǎn)的 flannel.1 上同時(shí)抓包發(fā)包節(jié)點(diǎn)一直在重傳,Cluster lP 已 DNAT 轉(zhuǎn)換為后端 Pod IP,如圖所示:


          抓包過程,發(fā)送端


          后端 Pod( Registry 服務(wù))所在節(jié)點(diǎn)的 flannel.1 上未抓到任何數(shù)據(jù)包,如圖所示:


          抓包過程,服務(wù)端


          請求 service 的 ClusterlP 時(shí),在兩端物理機(jī)網(wǎng)卡抓包,發(fā)包端如圖所示,封裝的源端節(jié)點(diǎn) IP 是 10.153.204.15,但一直在重傳:


          圖片包傳送過程,發(fā)送端


          收包端收到了包,但未回包,如圖所示:


          圖片包傳送過程,服務(wù)端


          由此可以知道,NAT 的動(dòng)作已經(jīng)完成,而只是后端 Pod(Registry 服務(wù))沒有回包,接下來在問題節(jié)點(diǎn)執(zhí)行 curl10.233.65.46:5000,在問題節(jié)點(diǎn)和后端( registry 服務(wù))Pod 所在節(jié)點(diǎn)的 flannel.1 上同時(shí)抓包,兩節(jié)點(diǎn)收發(fā)正常,發(fā)包如圖所示:


          正常包發(fā)送端


          正常包接收端


          接下來在兩端物理機(jī)網(wǎng)卡接口抓包,因?yàn)閿?shù)據(jù)包通過物理機(jī)網(wǎng)卡會(huì)進(jìn)行 vxlan 封裝,需要抓 vxlan 設(shè)備的 8472 端口,發(fā)包端如圖所示:


          問題節(jié)點(diǎn)物理機(jī)網(wǎng)卡接口抓包


          發(fā)現(xiàn)網(wǎng)絡(luò)鏈路連通,但封裝的 IP 不對,封裝的源端節(jié)點(diǎn) IP 是 10.153.204.228,但是存在問題節(jié)點(diǎn)的 IP 是 10.153.204.15。


          后端 Pod 所在節(jié)點(diǎn)的物理網(wǎng)卡上抓包,注意需要過濾其他正常節(jié)點(diǎn)的請求包,如圖所示;發(fā)現(xiàn)收到的數(shù)據(jù)包,源地址是 10.153.204.228,但是問題節(jié)點(diǎn)的 IP 是 10.153.204.15。


          對端節(jié)點(diǎn)物理機(jī)網(wǎng)卡接口抓包


          此時(shí)問題以及清楚了,是一個(gè) Pod 存在兩個(gè) IP,導(dǎo)致發(fā)包和回包時(shí)無法通過隧道設(shè)備找到對端的接口,所以發(fā)可以收到,但不能回。


          問題節(jié)點(diǎn)執(zhí)行 ip addr,發(fā)現(xiàn)網(wǎng)卡 enp26s0f0 上配置了兩個(gè) IP,如圖所示:


          問題節(jié)點(diǎn) IP


          進(jìn)一步查看網(wǎng)卡配置文件,發(fā)現(xiàn)網(wǎng)卡既配置了靜態(tài) IP,又配置了 dhcp 動(dòng)態(tài)獲取 IP。如圖所示:


          問題節(jié)點(diǎn)網(wǎng)卡配置


          最終定位原因?yàn)閱栴}節(jié)點(diǎn)既配置了 dhcp 獲取 IP,又配置了靜態(tài) IP,導(dǎo)致 IP 沖突,引發(fā)網(wǎng)絡(luò)異常。


          解決方法:修改網(wǎng)卡配置文件 /etc/sysconfig/network-scripts/ifcfg-enp26s0f0 里 BOOTPROTO="dhcp"為 BOOTPROTO="none";重啟 docker 和 kubelet 問題解決。



          2.集群外云主機(jī)調(diào)用集群內(nèi)應(yīng)用超時(shí)


          • 問題現(xiàn)象:Kubernetes 集群外云主機(jī)以 http post 方式訪問 Kubernetes 集群應(yīng)用接口超時(shí)。

          • 環(huán)境信息:Kubernetes 集群:calicoIP-IP 模式,應(yīng)用接口以 nodeport 方式對外提供服務(wù)。

          • 客戶端:Kubernetes 集群之外的云主機(jī)。


          排查過程:


          • 在云主機(jī) telnet 應(yīng)用接口地址和端口,可以連通,證明網(wǎng)絡(luò)連通正常,如圖所示

          • 云主機(jī)上調(diào)用接口不通,在云主機(jī)和 Pod 所在 Kubernetes 節(jié)點(diǎn)同時(shí)抓包,使用 wireshark 分析數(shù)據(jù)包



          通過抓包結(jié)果分析結(jié)果為 TCP 鏈接建立沒有問題,但是在傳輸大數(shù)據(jù)的時(shí)候會(huì)一直重傳 1514 大小的第一個(gè)數(shù)據(jù)包直至超時(shí)。懷疑是鏈路兩端 MTU 大小不一致導(dǎo)致(現(xiàn)象:某一個(gè)固定大小的包一直超時(shí)的情況)。如圖所示,1514 大小的包一直在重傳。


          報(bào)文 1-3 TCP 三次握手正常。


          報(bào)文 1 info 中 MSS 字段可以看到 MSS 協(xié)商為 1460,MTU=1460+20bytes(IP 包頭)+20bytes(TCP 包頭)=1500。


          報(bào)文 7 Kubernetes 主機(jī)確認(rèn)了包 4 的數(shù)據(jù)包,但是后續(xù)再?zèng)]有對數(shù)據(jù)的 ACK。


          報(bào)文 21-29 可以看到云主機(jī)一直在發(fā)送后面的數(shù)據(jù),但是沒有收到 Kubernetes 節(jié)點(diǎn)的 ACK,結(jié)合 Pod 未收到任何報(bào)文,表明是 Kubernetes 節(jié)點(diǎn)和 Pod 通信出現(xiàn)了問題。


          wireshark 分析


          在云主機(jī)上使用 ping -s 指定數(shù)據(jù)包大小,發(fā)現(xiàn)超過 1400 大小的數(shù)據(jù)包無法正常發(fā)送。結(jié)合以上情況,定位是云主機(jī)網(wǎng)卡配置的 MTU 是 1500,tunl0 配置的 MTU 是 1440,導(dǎo)致大數(shù)據(jù)包無法發(fā)送至 tunl0 ,因此 Pod 沒有收到報(bào)文,接口調(diào)用失敗。


          解決方法:修改云主機(jī)網(wǎng)卡 MTU 值為 1440,或者修改 Calico 的 MTU 值為 1500,保持鏈路兩端 MTU 值一致。



          3.集群 Pod 訪問對象存儲(chǔ)超時(shí)


          環(huán)境信息:


          公有云環(huán)境,Kubernetes 集群節(jié)點(diǎn)和對象存儲(chǔ)在同一私有網(wǎng)絡(luò)下,網(wǎng)絡(luò)鏈路無防火墻限制 Kubernetes 集群開啟了節(jié)點(diǎn)自動(dòng)彈縮(CA)和 Pod 自動(dòng)彈縮(HPA),通過域名訪問對象存儲(chǔ),Pod 使用集群 DNS 服務(wù),集群 DNS 服務(wù)配置了用戶自建上游 DNS 服務(wù)器。


          排查過程:


          • 使用 nsenter 工具進(jìn)入 pod 容器網(wǎng)絡(luò)命名空間測試,ping 對象存儲(chǔ)域名不通,報(bào)錯(cuò) unknown server name,ping 對象存儲(chǔ) lP 可以連通。

          • telnet 對象存儲(chǔ) 80/443 端口可以連通。

          • paping 對象存儲(chǔ) 80/443 端口無丟包。


          為了驗(yàn)證 Pod 創(chuàng)建好以后的初始階段網(wǎng)絡(luò)連通性,將以上測試動(dòng)作寫入 dockerfile,重新生成容器鏡像并創(chuàng) pod,測試結(jié)果一致。


          通過上述步驟,判斷 Pod 網(wǎng)絡(luò)連通性無異常,超時(shí)原因?yàn)橛蛎馕鍪。瑧岩蓡栴}如下:


          • 集群 DNS 服務(wù)存在異常

          • 上游 DNS 服務(wù)存在異常

          • 集群 DNS 服務(wù)與上游 DNS 通訊異常

          • Pod 訪問集群 DNS 服務(wù)異常


          根據(jù)上述方向排查,集群 DNS 服務(wù)狀態(tài)正常,無報(bào)錯(cuò)。測試 Pod 分別使用集群 DNS 服務(wù)和上游 DNS 服務(wù)解析域名,前者解析失敗,后者解析成功。至此,證明上游 DNS 服務(wù)正常,并且集群 DNS 服務(wù)日志中沒有與上游 DNS 通訊超時(shí)的報(bào)錯(cuò)。定位到的問題:Pod 訪問集群 DNS 服務(wù)超時(shí)。


          此時(shí)發(fā)現(xiàn),出現(xiàn)問題的 Pod 集中在新彈出的 Kubernetes 節(jié)點(diǎn)上。這些節(jié)點(diǎn)的 kube-proxy Pod 狀態(tài)全部為 pending,沒有正常調(diào)度到節(jié)點(diǎn)上。因此導(dǎo)致該節(jié)點(diǎn)上其他 Pod 無法訪問包括 DNS 在內(nèi)的所有 Kubernetes service。


          再進(jìn)一步排查發(fā)現(xiàn) kube-proxy Pod 沒有配置 priorityclass 為最高優(yōu)先級,導(dǎo)致節(jié)點(diǎn)資源緊張時(shí)為了將高優(yōu)先級的應(yīng)用 Pod 調(diào)度到該節(jié)點(diǎn),將原本已運(yùn)行在該節(jié)點(diǎn)的 kube-proxy 驅(qū)逐。


          解決方法:將 kube-proxy 設(shè)置 priorityclass 值為 system-node-critical 最高優(yōu)先級,同時(shí)建議應(yīng)用 Pod 配置就緒探針,測試可以正常連通對象存儲(chǔ)域名后再分配任務(wù)。


          鏈接:https://blog.csdn.net/wjianwei666/article/details/132900975

          (版權(quán)歸原作者所有,侵刪)


          瀏覽 1710
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  香蕉伊人av | 黄色成人网站在线观看免费 | 考逼免费视频 | 一级黄色毛片免费 | 奇米一区二区三区 |