0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在Kubernetes集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查

馬哥Linux運(yùn)維 ? 來源:博客園 ? 作者:Cylon ? 2022-09-02 09:45 ? 次閱讀

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

  • Pod 常見網(wǎng)絡(luò)異常分類
  • 網(wǎng)絡(luò)排查工具
  • Pod 網(wǎng)絡(luò)異常排查思路及流程模型
  • CNI 網(wǎng)絡(luò)異常排查步驟
  • 案例學(xué)習(xí)

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

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

  • 網(wǎng)絡(luò)不可達(dá),主要現(xiàn)象為 ping 不通,其可能原因?yàn)椋?/p>

    • 源端和目的端防火墻(iptables,selinux)限制
    • 網(wǎng)絡(luò)路由配置不正確
    • 源端和目的端的系統(tǒng)負(fù)載過高,網(wǎng)絡(luò)連接數(shù)滿,網(wǎng)卡隊(duì)列滿
    • 網(wǎng)絡(luò)鏈路故障
  • 端口不可達(dá):主要現(xiàn)象為可以 ping 通,但 telnet 端口不通,其可能原因?yàn)椋?/p>

    • 源端和目的端防火墻限制
    • 源端和目的端的系統(tǒng)負(fù)載過高,網(wǎng)絡(luò)連接數(shù)滿,網(wǎng)卡隊(duì)列滿,端口耗盡
    • 目的端應(yīng)用未正常監(jiān)聽導(dǎo)致(應(yīng)用未啟動,或監(jiān)聽為 127.0.0.1 等)
  • DNS 解析異常:主要現(xiàn)象為基礎(chǔ)網(wǎng)絡(luò)可以連通,訪問域名報(bào)錯(cuò)無法解析,訪問 IP 可以正常連通。其可能原因?yàn)?/p>

    • Pod 的 DNS 配置不正確
    • DNS 服務(wù)異常
    • pod 與 DNS 服務(wù)通訊異常
  • 大數(shù)據(jù)包丟包:主要現(xiàn)象為基礎(chǔ)網(wǎng)絡(luò)和端口均可以連通,小數(shù)據(jù)包收發(fā)無異常,大數(shù)據(jù)包丟包??赡茉?yàn)椋?/p>

    • 可使用ping -s指定數(shù)據(jù)包大小進(jìn)行測試
    • 數(shù)據(jù)包的大小超過了 docker、CNI 插件、或者宿主機(jī)網(wǎng)卡的MTU值。

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

    • kube-proxy 服務(wù)異常,沒有生成 iptables 策略或者 ipvs 規(guī)則導(dǎo)致無法訪問
    • CIDR 耗盡,無法為 Node 注入PodCIDR導(dǎo)致 CNI 插件異常
    • 其他 CNI 插件問題

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

1ec3d2c4-2a04-11ed-ba43-dac502259ad0.pngPod network trouble hirarchy

總結(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ò)故障原因,下面會介紹一些網(wǎng)絡(luò)排查工具。

tcpdump

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

?

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

  • Ubuntu/Debian:tcpdumpapt-get install -y tcpdump
  • Centos/Fedora:tcpdump;yum install -y tcpdump
  • Apline:tcpdump;apk add tcpdump --no-cache

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

語法

參數(shù) 說明
-i [interface]
-w [flle] 第一個(gè) n 表示將地址解析為數(shù)字格式而不是主機(jī)名,第二個(gè) N 表示將端口解析為數(shù)字格式而不是服務(wù)名
-n 不顯示 IP 地址
-X hex and ASCII
-A ASCII(實(shí)際上是以人類可讀懂的包進(jìn)行顯示)
-XX
-v 詳細(xì)信息
-r 讀取文件而不是實(shí)時(shí)抓包
關(guān)鍵字
type host(主機(jī)名,域名,IP 地址), net, port, portrange
direction src, dst, src or dst , src and ds
protocol ether, ip,arp, tcp, udp, wlan

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

tcpdump-D

按 IP 查找流量

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

tcpdumphost1.1.1.1

按源 / 目的 地址過濾

如果只想查看來自 / 向某方向流量,可以使用srcdst

tcpdumpsrc|dst1.1.1.1

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

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

tcpdumpnet1.2.3.0/24

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

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

tcpdump-c1-Xicmp

查看特定端口的流量

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

tcpdumpport3389
tcpdumpsrcport1025

查找端口范圍的流量

tcpdumpportrange21-23

過濾包的大小

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

tcpdumpless32
tcpdumpgreater64
tcpdump<=?128

捕獲流量輸出為文件

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

tcpdumpport80-wcapture_file

組合條件

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

  • ANDandor&&
  • ORoror||
  • EXCEPTnotor!
tcpdump-ieth0-nnhost220.181.57.216and10.0.0.1#主機(jī)之間的通訊
tcpdump-ieth0-nnhost220.181.57.216or10.0.0.1
#獲取10.0.0.1與10.0.0.9或10.0.0.1與10.0.0.3之間的通訊
tcpdump-ieth0-nnhost10.0.0.1and(10.0.0.9or10.0.0.3)

原始輸出

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

tcpdump-ttnnvvS-ieth0
tcpdump-ttnnvvS-ieth0

IP 到端口

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

tcpdump-nnvvSsrc10.5.2.3anddstport3389

去除特定流量

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

tcpdumpdst192.168.0.2andsrcnetandnoticmp

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

tcpdump-vvsrcmarsandnotdstport22

選項(xiàng)分組

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

tcpdump'src10.0.2.4and(dstport3389or22)'

過濾 TCP 標(biāo)記位

TCP RST

The filters below find these various packets because tcp[13] looks at offset 13 in the TCP header, the number represents the location within the byte, and the !=0 means that the flag in question is set to 1, i.e. it’s on.

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-vvAs0port53

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

tcpdumpporthttporportftporportsmtporportimaporportpop3orporttelnet-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)的接口,有以下建議

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

通常情況下會在源端和目的端兩端同時(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í)抓包。

抓包設(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}的包,在vethcni0上可以指定 Pod IP 抓包,而在宿主機(jī)網(wǎng)卡上如果仍然指定 Pod IP 會發(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ò)接口

1f0bafd6-2a04-11ed-ba43-dac502259ad0.pngVxLAN in kubernetes

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)限

?

各系統(tǒng)下的安裝[2][1]

  • Ubuntu/Debian:util-linux;apt-get install -y util-linux
  • Centos/Fedora:util-linux;yum install -y util-linux
  • Apline:util-linux;apk add util-linux --no-cache

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

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

$ps-ef|greptail
root1763662887020:19pts/20000grep--color=autotail
root3085830838015:55?0001tail-f

$nsenter-t30858-nifconfig
eth0:flags=4163mtu1480
inet192.168.1.213netmask255.255.255.0broadcast192.168.1.255
ether5e98dc:6btxqueuelen0(Ethernet)
RXpackets92bytes9100(8.8KiB)
RXerrors0dropped0overruns0frame0
TXpackets92bytes8422(8.2KiB)
TXerrors0dropped0overruns0carrier0collisions0

lo:flags=73mtu65536
inet127.0.0.1netmask255.0.0.0
looptxqueuelen1000(LocalLoopback)
RXpackets5bytes448(448.0B)
RXerrors0dropped0overruns0frame0
TXpackets5bytes448(448.0B)
TXerrors0dropped0overruns0carrier0collisions0

net1:flags=4163mtu1500
inet10.1.0.201netmask255.255.255.0broadcast10.1.0.255
etherb2f92a:10txqueuelen0(Ethernet)
RXpackets228bytes21272(20.7KiB)
RXerrors0dropped0overruns0frame0
TXpackets216bytes20272(19.7KiB)
TXerrors0dropped0overruns0carrier0collisions0

如何定位 Pod 名稱空間

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

$kubectlgetpods-owide|awk'{print$1,$7}'
NAMENODE
netbox-85865d5556-hfg6vmaster-machine
netbox-85865d5556-vlgr4node01

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

$kubectlgetpods-owide|awk'{print$1,$6,$7}'
NAMEIPNODE
netbox-85865d5556-hfg6v192.168.1.213master-machine
netbox-85865d5556-vlgr4192.168.0.4node01

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

$dockerps|grepnetbox-85865d5556-hfg6v
6f8c58377aaef78dd05f11ff"tail-f"45hoursagoUp45hoursk8s_netbox_netbox-85865d5556-hfg6v_default_4a8e2da8-05d1-4c81-97a7-3d76343a323a_0
b9c732ee457eregistry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1"/pause"45hoursagoUp45hoursk8s_POD_netbox-85865d5556-hfg6v_default_4a8e2da8-05d1-4c81-97a7-3d76343a323a_0

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

$dockerinspect--format"{{.State.Pid}}"6f8c58377aae
30858

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

paping

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

paping download:paping[2]

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

  • RedHat/CentOS:yum install -y libstdc++.i686 glibc.i686
  • Ubuntu/Debian:最小化安裝無需依賴
$paping-h
papingv1.5.5-Copyright(c)2011MikeLovell

Syntax:paping[options]destination

Options:
-?,--helpdisplayusage
-p,--portNsetTCPportN(required)
--nocolorDisablecoloroutput
-t,--timeouttimeoutinmilliseconds(default1000)
-c,--countNsetnumberofcheckstoN

mtr

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

?

各系統(tǒng)下的安裝[2][3]

  • Ubuntu/Debian:mtrapt-get install -y mtr
  • Centos/Fedora:mtr;yum install -y mtr
  • Apline:mtr;apk add mtr --no-cache

簡單的使用示例

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

$mtrgoogle.com

Start:ThuJun2812132018
HOST:TecMintLoss%SntLastAvgBestWrstStDev
1.|--192.168.0.10.0%50.30.30.30.40.0
2.|--5.5.5.2110.0%50.70.90.71.30.0
3.|--209.snat-111-91-120.hns.n80.0%57.17.17.17.10.0
4.|--72.14.194.2260.0%51.92.91.94.41.1
5.|--108.170.248.1610.0%52.93.52.04.30.7
6.|--216.239.62.2370.0%53.06.22.918.36.7
7.|--bom05s12-in-f14.1e100.net0.0%52.12.42.03.80.5

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

$mtr-ngoogle.com

Start:ThuJun2812582018
HOST:TecMintLoss%SntLastAvgBestWrstStDev
1.|--192.168.0.10.0%50.30.30.30.40.0
2.|--5.5.5.2110.0%50.90.90.81.10.0
3.|--???100.050.00.00.00.00.0
4.|--72.14.194.2260.0%52.02.01.92.00.0
5.|--108.170.248.1610.0%52.32.32.22.40.0
6.|--216.239.62.2370.0%53.03.23.03.30.0
7.|--172.217.160.1740.0%53.73.62.05.31.4

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

$mtr-bgoogle.com

Start:ThuJun2812362018
HOST:TecMintLoss%SntLastAvgBestWrstStDev
1.|--192.168.0.10.0%50.30.30.30.40.0
2.|--5.5.5.2110.0%50.70.80.61.00.0
3.|--209.snat-111-91-120.hns.n0.0%51.41.61.32.10.0
4.|--72.14.194.2260.0%51.82.11.82.60.0
5.|--108.170.248.2090.0%52.01.91.82.00.0
6.|--216.239.56.1150.0%52.42.72.42.90.0
7.|--bom07s15-in-f14.1e100.net0.0%53.72.21.73.70.9

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

$mtr-c5google.com

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

$mtr-r-c5google.com>1
$cat1
Start:SunAug2122492022
HOST:xxxxx.xxxxx.xxxx.xxxxLoss%SntLastAvgBestWrstStDev
1.|--gateway0.0%50.6146.80.6420.2191.4
2.|--212.xx.21.2410.0%50.41.00.42.30.5
3.|--188.xxx.106.1240.0%50.71.10.72.10.5
4.|--???100.050.00.00.00.00.0
5.|--72.14.209.890.0%543.243.343.143.30.0
6.|--108.xxx.250.330.0%543.243.143.143.20.0
7.|--108.xxx.250.340.0%543.743.643.543.70.0
8.|--142.xxx.238.820.0%560.660.960.661.20.0
9.|--142.xxx.238.640.0%559.767.559.389.813.2
10.|--142.xxx.37.810.0%562.762.962.663.50.0
11.|--142.xxx.229.850.0%561.060.960.761.30.0
12.|--xx-in-f14.1e100.net0.0%559.058.958.959.00.0

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

mtr--tcpgoogle.com

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

mtr-m35216.58.223.78

-s指定包的大小

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

colum describe
last 最近一次的探測延遲值
avg 探測延遲的平均值
best 探測延遲的最小值
wrst 探測延遲的最大值
stdev 標(biāo)準(zhǔn)偏差。越大說明相應(yīng)節(jié)點(diǎn)越不穩(wěn)定

丟包判斷

任一節(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 跳作為參考。

延遲判斷

由于鏈路抖動或其它因素的影響,節(jié)點(diǎn)的BestWorst值可能相差很大。而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ù)包延遲很?。ɡ纾?5ms),而另一些延遲卻很大(例如:350ms),但最終得到的平均延遲反而可能是正常的。所以此時(shí)Avg并不能很好的反應(yīng)出實(shí)際的網(wǎng)絡(luò)質(zhì)量情況。

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

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

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

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

1f38aa04-2a04-11ed-ba43-dac502259ad0.pngPod network troubleshooting idea

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

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

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

環(huán)境信息:

IP Hostname role
10.153.204.15 yq01-aip-aikefu12 worknode 節(jié)點(diǎn)(本次擴(kuò)容的問題節(jié)點(diǎn))
10.153.203.14 yq01-aip-aikefu31 master 節(jié)點(diǎn)
10.61.187.42 yq01-aip-aikefu2746f8e9 master 節(jié)點(diǎn)
10.61.187.48 yq01-aip-aikefu30b61e25 master 節(jié)點(diǎn)(本次 registry 服務(wù) pod 所在 節(jié)點(diǎ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 可以判斷registryPod無異常
  • 根據(jù)現(xiàn)象 3 可以判斷registryservice異常的可能性不大,可能是新擴(kuò)容節(jié)點(diǎn)訪問registryservice存在異常

懷疑方向:

  • 問題節(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-proxyPod 的狀態(tài),問題節(jié)點(diǎn)上的kube-proxyPod 為running狀態(tài)
  • 執(zhí)行kubecti logs -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 lP10.233.0.100KUBE-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)段的路由,如圖所示

1f634e12-2a04-11ed-ba43-dac502259ad0.png10.233.65.46 路由

查看對端的回程路由

1fa6a572-2a04-11ed-ba43-dac502259ad0.png回程路由

以上排查證明問題原因不是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,如圖所示

20c21ee6-2a04-11ed-ba43-dac502259ad0.png抓包過程,發(fā)送端

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

20dc53ce-2a04-11ed-ba43-dac502259ad0.png抓包過程,服務(wù)端

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

210c52ae-2a04-11ed-ba43-dac502259ad0.png包傳送過程,發(fā)送端

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

21497490-2a04-11ed-ba43-dac502259ad0.png包傳送過程,服務(wù)端

由此可以知道,NAT 的動作已經(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ā)包如圖所示

22397454-2a04-11ed-ba43-dac502259ad0.png正常包發(fā)送端226fd382-2a04-11ed-ba43-dac502259ad0.png正常包接收端

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

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

23fe6420-2a04-11ed-ba43-dac502259ad0.png問題節(jié)點(diǎn)物理機(jī)網(wǎng)卡接口抓包

后端 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。

243c4e98-2a04-11ed-ba43-dac502259ad0.png對端節(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,如圖所示

247753a8-2a04-11ed-ba43-dac502259ad0.png問題節(jié)點(diǎn) IP

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

2491119e-2a04-11ed-ba43-dac502259ad0.png問題節(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-enp26s0f0BOOTPROTO="dhcp"BOOTPROTO="none";重啟dockerkubelet問題解決。

集群外云主機(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ù)包
24ded046-2a04-11ed-ba43-dac502259ad0.png

通過抓包結(jié)果分析結(jié)果為 TCP 鏈接建立沒有問題,但是在傳輸大數(shù)據(jù)的時(shí)候會一直重傳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 k8s 主機(jī)確認(rèn)了包 4 的數(shù)據(jù)包,但是后續(xù)再沒有對數(shù)據(jù)的 ACK

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

250562ba-2a04-11ed-ba43-dac502259ad0.pngwireshark 分析

在云主機(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 值一致。

集群 pod 訪問對象存儲超時(shí)

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

排查過程:

  • 使用 nsenter 工具進(jìn)入 pod 容器網(wǎng)絡(luò)命名空間測試,ping 對象存儲域名不通,報(bào)錯(cuò) unknown server name,ping 對象存儲 lP 可以連通。
  • telnet對象存儲 80/443 端口可以連通。
  • paping對象存儲 80/443 端口無丟包。
  • 為了驗(yàn)證 Pod 創(chuàng)建好以后的初始階段網(wǎng)絡(luò)連通性,將以上測試動作寫入 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-proxyPod 狀態(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-proxyPod 沒有配置 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 配置就緒探針,測試可以正常連通對象存儲域名后再分配任務(wù)。

審核編輯:湯梓紅


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 網(wǎng)絡(luò)
    +關(guān)注

    關(guān)注

    14

    文章

    7565

    瀏覽量

    88775
  • kubernetes
    +關(guān)注

    關(guān)注

    0

    文章

    224

    瀏覽量

    8715

原文標(biāo)題:Kubernetes 網(wǎng)絡(luò)排錯(cuò)骨灰級中文指南

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Kubernetes 網(wǎng)絡(luò)模型如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernete
    的頭像 發(fā)表于 10-08 11:32 ?1067次閱讀

    阿里云上Kubernetes集群聯(lián)邦

    規(guī)模的上限等等。Federation集群聯(lián)邦可以一定程度上解決這些問題。Federation是可以將分布多個(gè)Region或者多個(gè)云廠商的Kubernetes集群整合成一個(gè)大的
    發(fā)表于 03-12 17:10

    kubernetes集群配置

    基于v1104版本手動搭建高可用kubernetes 集群
    發(fā)表于 08-19 08:07

    Kubernetes 從懵圈到熟練:集群服務(wù)的三個(gè)要點(diǎn)和一種實(shí)現(xiàn)

    以我的經(jīng)驗(yàn)來講,理解 Kubernetes 集群服務(wù)的概念,是比較不容易的一件事情。尤其是當(dāng)我們基于似是而非的理解,去排查服務(wù)相關(guān)問題的時(shí)候,會非常不順利。這體現(xiàn)在,對于新手來說,ping 不通服務(wù)
    發(fā)表于 09-24 15:35

    請問鴻蒙系統(tǒng)上可以部署kubernetes集群嗎?

    鴻蒙系統(tǒng)上可以部署kubernetes集群
    發(fā)表于 06-08 11:16

    如何部署基于Mesos的Kubernetes集群

    的內(nèi)核。把Kubernetes運(yùn)行在Mesos集群之上,可以和其他的框架共享集群資源,提高集群資源的利用率。 本文是Kubernetes和M
    發(fā)表于 10-09 18:04 ?0次下載
    如何部署基于Mesos的<b class='flag-5'>Kubernetes</b><b class='flag-5'>集群</b>

    淺談Kubernetes集群的高可用方案

    Kubernetes作為容器應(yīng)用的管理中心,通過對Pod的數(shù)量進(jìn)行監(jiān)控,并且根據(jù)主機(jī)或容器失效的狀態(tài)將新的Pod調(diào)度到其他Node上,實(shí)現(xiàn)了應(yīng)用層的高可用性。針對Kubernetes集群,高可用性
    發(fā)表于 10-11 10:04 ?1次下載
    淺談<b class='flag-5'>Kubernetes</b><b class='flag-5'>集群</b>的高可用方案

    Kubernetes網(wǎng)絡(luò)模型介紹以及如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernete
    的頭像 發(fā)表于 05-05 20:22 ?1774次閱讀

    Kubernetes網(wǎng)絡(luò)模型的基礎(chǔ)知識

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernete
    的頭像 發(fā)表于 07-20 09:46 ?1211次閱讀

    Kubernetes 集群的功能

    Telepresence 是一個(gè)開源工具,可讓您在本地運(yùn)行單個(gè)服務(wù),同時(shí)將該服務(wù)連接到遠(yuǎn)程 Kubernetes 集群。
    的頭像 發(fā)表于 09-05 10:58 ?1095次閱讀

    Kubernetes集群的關(guān)閉與重啟

    日常對 Kubernetes 集群運(yùn)行維護(hù)的過程中,您可能需要臨時(shí)的關(guān)閉或者是重啟 Kubernetes 集群
    的頭像 發(fā)表于 11-07 09:50 ?9931次閱讀

    樹莓派上搭建Kubernetes智能邊緣集群

    電子發(fā)燒友網(wǎng)站提供《樹莓派上搭建Kubernetes智能邊緣集群.zip》資料免費(fèi)下載
    發(fā)表于 12-09 09:20 ?2次下載
    <b class='flag-5'>在</b>樹莓派上搭建<b class='flag-5'>Kubernetes</b>智能邊緣<b class='flag-5'>集群</b>

    Kubernetes集群部署

    Kubeadm是一種Kubernetes集群部署工具,通過kubeadm init命令創(chuàng)建master節(jié)點(diǎn),通過 kubeadm join命令把node節(jié)點(diǎn)加入到集群
    的頭像 發(fā)表于 02-15 10:35 ?1726次閱讀

    各種網(wǎng)絡(luò)組件 Kubernetes 集群中是如何交互的

    Kubernetes 中有多種網(wǎng)絡(luò)設(shè)置方法,以及 container runtime 的各種選項(xiàng)。這篇文章將使用 Flannel 作為 network provider,并使用 Containered 作為 containe
    的頭像 發(fā)表于 05-23 09:49 ?801次閱讀
    各種<b class='flag-5'>網(wǎng)絡(luò)</b>組件<b class='flag-5'>在</b> <b class='flag-5'>Kubernetes</b> <b class='flag-5'>集群</b>中是如何交互的

    使用Velero備份Kubernetes集群

    Velero 是 heptio 團(tuán)隊(duì)(被 VMWare 收購)開源的 Kubernetes 集群備份、遷移工具。
    的頭像 發(fā)表于 08-05 15:43 ?359次閱讀
    使用Velero備份<b class='flag-5'>Kubernetes</b><b class='flag-5'>集群</b>