本文將引入一個思路:“在 Kubernetes 集群發(fā)生網絡異常時如何排查”。文章將引入 Kubernetes 集群中網絡排查的思路,包含網絡異常模型,常用工具,并且提出一些案例以供學習。
- Pod 常見網絡異常分類
- 網絡排查工具
- Pod 網絡異常排查思路及流程模型
- CNI 網絡異常排查步驟
- 案例學習
Pod 網絡異常
網絡異常大概分為如下幾類:
-
網絡不可達,主要現(xiàn)象為 ping 不通,其可能原因為:
-
源端和目的端防火墻(
iptables
,selinux
)限制 - 網絡路由配置不正確
- 源端和目的端的系統(tǒng)負載過高,網絡連接數(shù)滿,網卡隊列滿
- 網絡鏈路故障
-
源端和目的端防火墻(
-
端口不可達:主要現(xiàn)象為可以 ping 通,但 telnet 端口不通,其可能原因為:
- 源端和目的端防火墻限制
- 源端和目的端的系統(tǒng)負載過高,網絡連接數(shù)滿,網卡隊列滿,端口耗盡
- 目的端應用未正常監(jiān)聽導致(應用未啟動,或監(jiān)聽為 127.0.0.1 等)
-
DNS 解析異常:主要現(xiàn)象為基礎網絡可以連通,訪問域名報錯無法解析,訪問 IP 可以正常連通。其可能原因為
- Pod 的 DNS 配置不正確
- DNS 服務異常
- pod 與 DNS 服務通訊異常
-
大數(shù)據包丟包:主要現(xiàn)象為基礎網絡和端口均可以連通,小數(shù)據包收發(fā)無異常,大數(shù)據包丟包??赡茉驗椋?/p>
-
可使用
ping -s
指定數(shù)據包大小進行測試 -
數(shù)據包的大小超過了 docker、CNI 插件、或者宿主機網卡的MTU值。
-
可使用
-
CNI 異常:主要現(xiàn)象為 Node 可以通,但 Pod 無法訪問集群地址,可能原因有:
- kube-proxy 服務異常,沒有生成 iptables 策略或者 ipvs 規(guī)則導致無法訪問
-
CIDR 耗盡,無法為 Node 注入
PodCIDR
導致 CNI 插件異常 - 其他 CNI 插件問題
那么整個 Pod 網絡異常分類可以如下圖所示:
![1ec3d2c4-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWAPUDLAAB6gl5pbHg530.png)
總結一下,Pod 最常見的網絡故障有,網絡不可達(ping 不通);端口不可達(telnet 不通);DNS 解析異常(域名不通)與大數(shù)據包丟失(大包不通)。
常用網絡排查工具
在了解到常見的網絡異常后,在排查時就需要使用到一些網絡工具才可以很有效的定位到網絡故障原因,下面會介紹一些網絡排查工具。
tcpdump
tcpdump 網絡嗅探器,將強大和簡單結合到一個單一的命令行界面中,能夠將網絡中的報文抓取,輸出到屏幕或者記錄到文件中。
?各系統(tǒng)下的安裝
查看指定接口上的所有通訊
語法
參數(shù) | 說明 |
---|---|
-i [interface] | |
-w [flle] | 第一個 n 表示將地址解析為數(shù)字格式而不是主機名,第二個 N 表示將端口解析為數(shù)字格式而不是服務名 |
-n | 不顯示 IP 地址 |
-X | hex and ASCII |
-A | ASCII(實際上是以人類可讀懂的包進行顯示) |
-XX | |
-v | 詳細信息 |
-r | 讀取文件而不是實時抓包 |
關鍵字 | |
type | host(主機名,域名,IP 地址), net, port, portrange |
direction | src, dst, src or dst , src and ds |
protocol | ether, ip,arp, tcp, udp, wlan |
捕獲所有網絡接口
tcpdump-D
按 IP 查找流量
最常見的查詢之一host
,可以看到來往于1.1.1.1
的流量。
tcpdumphost1.1.1.1
按源 / 目的 地址過濾
如果只想查看來自 / 向某方向流量,可以使用src
和dst
。
tcpdumpsrc|dst1.1.1.1
通過網絡查找數(shù)據包
使用net
選項,來要查找出 / 入某個網絡或子網的數(shù)據包。
tcpdumpnet1.2.3.0/24
使用十六進制輸出數(shù)據包內容
hex
可以以 16 進制輸出包的內容
tcpdump-c1-Xicmp
查看特定端口的流量
使用port
選項來查找特定的端口流量。
tcpdumpport3389
tcpdumpsrcport1025
查找端口范圍的流量
tcpdumpportrange21-23
過濾包的大小
如果需要查找特定大小的數(shù)據包,可以使用以下選項。你可以使用less
,greater
。
tcpdumpless32
tcpdumpgreater64
tcpdump<=?128
捕獲流量輸出為文件
-w
可以將數(shù)據包捕獲保存到一個文件中以便將來進行分析。這些文件稱為PCAP
(PEE-cap)文件,它們可以由不同的工具處理,包括Wireshark
。
tcpdumpport80-wcapture_file
組合條件
tcpdump 也可以結合邏輯運算符進行組合條件查詢
-
AND
and
or&&
-
OR
or
or||
-
EXCEPT
not
or!
tcpdump-ieth0-nnhost220.181.57.216and10.0.0.1#主機之間的通訊
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)
原始輸出
并顯示人類可讀的內容進行輸出包(不包含內容)。
tcpdump-ttnnvvS-ieth0
tcpdump-ttnnvvS-ieth0
IP 到端口
讓我們查找從某個 IP 到端口任何主機的某個端口所有流量。
tcpdump-nnvvSsrc10.5.2.3anddstport3389
去除特定流量
可以將指定的流量排除,如這顯示所有到 192.168.0.2 的 非 ICMP 的流量。
tcpdumpdst192.168.0.2andsrcnetandnoticmp
來自非指定端口的流量,如,顯示來自不是 SSH 流量的主機的所有流量。
tcpdump-vvsrcmarsandnotdstport22
選項分組
在構建復雜查詢時,必須使用單引號'
。單引號用于忽略特殊符號()
,以便于使用其他表達式(如 host, port, net 等)進行分組。
tcpdump'src10.0.2.4and(dstport3389or22)'
過濾 TCP 標記位
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'
同時忽略 SYN 和 ACK 標志的數(shù)據包
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
查找對應流量的明文密碼
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é)議是可以打開該選項的
關于抓包節(jié)點和抓包設備
如何抓取有用的包,以及如何找到對應的接口,有以下建議
抓包節(jié)點:
通常情況下會在源端和目的端兩端同時抓包,觀察數(shù)據包是否從源端正常發(fā)出,目的端是否接收到數(shù)據包并給源端回包,以及源端是否正常接收到回包。如果有丟包現(xiàn)象,則沿網絡鏈路上各節(jié)點抓包排查。例如,A 節(jié)點經過 c 節(jié)點到 B 節(jié)點,先在 AB 兩端同時抓包,如果 B 節(jié)點未收到 A 節(jié)點的包,則在 c 節(jié)點同時抓包。
抓包設備:
對于 Kubernetes 集群中的 Pod,由于容器內不便于抓包,通常視情況在 Pod 數(shù)據包經過的 veth 設備,docker0網橋,CNI插件設備(如 cni0,flannel.1 etc..)及 Pod 所在節(jié)點的網卡設備上指定 Pod IP 進行抓包。選取的設備根據懷疑導致網絡問題的原因而定,比如范圍由大縮小,從源端逐漸靠近目的端,比如懷疑是CNI插件導致,則在CNI插件設備上抓包。從 pod 發(fā)出的包逐一經過 veth 設備,cni0設備,flannel0,宿主機網卡,到達對端,抓包時可按順序逐一抓包,定位問題節(jié)點。
?需要注意在不同設備上抓包時指定的源目 IP 地址需要轉換,如抓取某 Pod 時,ping{host}的包,在veth和cni0上可以指定 Pod IP 抓包,而在宿主機網卡上如果仍然指定 Pod IP 會發(fā)現(xiàn)抓不到包,因為此時 Pod IP 已被轉換為宿主機網卡 IP。
下圖是一個使用VxLAN模式的flannel的跨界點通訊的網絡模型,在抓包時需要注意對應的網絡接口
![1f0bafd6-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWABmPyAACAXUH5fpo062.png)
nsenter
nsenter 是一款可以進入進程的名稱空間中。例如,如果一個容器以非 root 用戶身份運行,而使用docker exec
進入其中后,但該容器沒有安裝sudo
或未netstat
,并且您想查看其當前的網絡屬性,如開放端口,這種場景下將如何做到這一點?nsenter就是用來解決這個問題的。
nsenter(namespace enter) 可以在容器的宿主機上使用nsenter命令進入容器的命名空間,以容器視角使用宿主機上的相應網絡命令進行操作。當然需要擁有root權限
?各系統(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
接 進程 ID 號,-n
表示進入名稱空間內,
為執(zhí)行的命令。
實例:如我們有一個 Pod 進程 ID 為 30858,進入該 Pod 名稱空間內執(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é)點名稱
$kubectlgetpods-owide|awk'{print$1,$7}'
NAMENODE
netbox-85865d5556-hfg6vmaster-machine
netbox-85865d5556-vlgr4node01
如果 Pod 不在當前節(jié)點還需要用 IP 登錄則還需要查看 IP(可選)
$kubectlgetpods-owide|awk'{print$1,$6,$7}'
NAMEIPNODE
netbox-85865d5556-hfg6v192.168.1.213master-machine
netbox-85865d5556-vlgr4192.168.0.4node01
接下來,登錄節(jié)點,獲取容器 lD,如下列所示,每個 pod 默認有一個pause容器,其他為用戶 yaml 文件中定義的容器,理論上所有容器共享相同的網絡命名空間,排查時可任選一個容器。
$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é)點系統(tǒng)中對應的進程號,如下所示
$dockerinspect--format"{{.State.Pid}}"6f8c58377aae
30858
最后就可以通過nsenter進入容器網絡空間執(zhí)行命令了
paping
paping命令可對目標地址指定端口以 TCP 協(xié)議進行連續(xù) ping,通過這種特性可以彌補pingICMP 協(xié)議,以及nmap,telnet只能進行一次操作的的不足;通常情況下會用于測試端口連通性和丟包率
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是一個跨平臺的網絡診斷工具,將traceroute和ping的功能結合到一個工具。與traceroute不同的是mtr顯示的信息比起traceroute更加豐富:通過mtr可以確定網絡的條數(shù),并且可以同時打印響應百分比以及網絡中各跳躍點的響應時間。
?各系統(tǒng)下的安裝[2][3]
- Ubuntu/Debian:
mtr
;apt-get install -y mtr
- Centos/Fedora:
mtr
;yum install -y mtr
- Apline:
mtr
;apk add mtr --no-cache
簡單的使用示例
最簡單的示例,就是后接域名或 IP,這將跟蹤整個路由
$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
強制mtr打印 IP 地址而不是主機名
$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
同時顯示 IP 地址與主機名
$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
跟一個具體的值,這將限制mtrping 的次數(shù),到達次數(shù)后會退出
$mtr-c5google.com
如果需要指定次數(shù),并且在退出后保存這些數(shù)據,使用-r
flag
$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
默認使用的是 ICMP 協(xié)議-i
,可以指定-u
, -t
使用其他協(xié)議
mtr--tcpgoogle.com
-m
指定最大的跳數(shù)
mtr-m35216.58.223.78
-s
指定包的大小
mtr 輸出的數(shù)據
colum | describe |
---|---|
last | 最近一次的探測延遲值 |
avg | 探測延遲的平均值 |
best | 探測延遲的最小值 |
wrst | 探測延遲的最大值 |
stdev | 標準偏差。越大說明相應節(jié)點越不穩(wěn)定 |
丟包判斷
任一節(jié)點的Loss%
(丟包率)如果不為零,則說明這一跳網絡可能存在問題。導致相應節(jié)點丟包的原因通常有兩種。
- 運營商基于安全或性能需求,人為限制了節(jié)點的 ICMP 發(fā)送速率,導致丟包。
- 節(jié)點確實存在異常,導致丟包。可以結合異常節(jié)點及其后續(xù)節(jié)點的丟包情況,來判定丟包原因。
?Notes:
- 如果隨后節(jié)點均沒有丟包,則通常說明異常節(jié)點丟包是由于運營商策略限制所致??梢院雎韵嚓P丟包。
- 如果隨后節(jié)點也出現(xiàn)丟包,則通常說明節(jié)點確實存在網絡異常,導致丟包。對于這種情況,如果異常節(jié)點及其后續(xù)節(jié)點連續(xù)出現(xiàn)丟包,而且各節(jié)點的丟包率不同,則通常以最后幾跳的丟包率為準。如鏈路測試在第 5、6、7 跳均出現(xiàn)了丟包。最終丟包情況以第 7 跳作為參考。
延遲判斷
由于鏈路抖動或其它因素的影響,節(jié)點的Best和Worst值可能相差很大。而Avg(平均值)統(tǒng)計了自鏈路測試以來所有探測的平均值,所以能更好的反應出相應節(jié)點的網絡質量。而StDev(標準偏差值)越高,則說明數(shù)據包在相應節(jié)點的延時值越不相同(越離散)。所以標準偏差值可用于協(xié)助判斷Avg是否真實反應了相應節(jié)點的網絡質量。例如,如果標準偏差很大,說明數(shù)據包的延遲是不確定的??赡苣承?shù)據包延遲很小(例如:25ms),而另一些延遲卻很大(例如:350ms),但最終得到的平均延遲反而可能是正常的。所以此時Avg并不能很好的反應出實際的網絡質量情況。
這就需要結合如下情況進行判斷:
- 如果StDev很高,則同步觀察相應節(jié)點的Best和wrst,來判斷相應節(jié)點是否存在異常。
- 如果StDev不高,則通過 Avg 來判斷相應節(jié)點是否存在異常。
Pod 網絡排查流程
Pod 網絡異常時排查思路,可以按照下圖所示
![1f38aa04-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWAMznvAACayWBhB1c045.png)
案例學習
擴容節(jié)點訪問 service 地址不通
測試環(huán)境 k8s 節(jié)點擴容后無法訪問集群 clusterlP 類型的 registry 服務
環(huán)境信息:
IP | Hostname | role |
---|---|---|
10.153.204.15 | yq01-aip-aikefu12 | worknode 節(jié)點(本次擴容的問題節(jié)點) |
10.153.203.14 | yq01-aip-aikefu31 | master 節(jié)點 |
10.61.187.42 | yq01-aip-aikefu2746f8e9 | master 節(jié)點 |
10.61.187.48 | yq01-aip-aikefu30b61e25 | master 節(jié)點(本次 registry 服務 pod 所在 節(jié)點) |
- cni 插件:flannel vxlan
- kube-proxy 工作模式為 iptables
-
registry 服務
- 單實例部署在 10.61.187.48:5000
- Pod IP:10.233.65.46,
- Cluster IP:10.233.0.100
現(xiàn)象:
- 所有節(jié)點之間的 pod 通信正常
- 任意節(jié)點和 Pod curl registry 的 Pod 的IP:5000均可以連通
- 新擴容節(jié)點 10.153.204.15 curl registry 服務的 Cluster lP 10.233.0.100:5000 不通,其他節(jié)點 curl 均可以連通
分析思路:
- 根據現(xiàn)象 1 可以初步判斷CNI插件無異常
- 根據現(xiàn)象 2 可以判斷registry的Pod無異常
- 根據現(xiàn)象 3 可以判斷registry的service異常的可能性不大,可能是新擴容節(jié)點訪問registry的service存在異常
懷疑方向:
- 問題節(jié)點的 kube-proxy 存在異常
- 問題節(jié)點的 iptables 規(guī)則存在異常
- 問題節(jié)點到 service 的網絡層面存在異常
排查過程:
-
排查問題節(jié)點的
kube-proxy
-
執(zhí)行
kubectl get pod -owide -nkube-system l grep kube-proxy
查看kube-proxyPod 的狀態(tài),問題節(jié)點上的kube-proxyPod 為running狀態(tài) -
執(zhí)行
kubecti logs
查看問題節(jié)點kube-proxy的 Pod 日志,沒有異常報錯-nkube-system -
在問題節(jié)點操作系統(tǒng)上執(zhí)行
iptables -S -t nat
查看iptables
規(guī)則
排查過程:
確認存在到registry服務的 Cluster lP10.233.0.100的KUBE-SERVICES鏈,跳轉至KUBE-SVC-* 鏈做負載均衡,再跳轉至KUBE-SEP-* 鏈通過DNAT替換為服務后端 Pod 的 IP 10.233.65.46。因此判斷 iptables 規(guī)則無異常執(zhí)行 route-n 查看問題節(jié)點存在訪問 10.233.65.46 所在網段的路由,如圖所示
![1f634e12-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWAVXpTAALVWB_npWQ599.png)
查看對端的回程路由
![1fa6a572-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWAA0kKAANqtWmusrM645.png)
以上排查證明問題原因不是cni插件或者kube-proxy異常導致,因此需要在訪問鏈路上抓包,判斷問題原因、問題節(jié)點執(zhí)行curl 10.233.0.100:5000
,在問題節(jié)點和后端 pod 所在節(jié)點的 flannel.1 上同時抓包發(fā)包節(jié)點一直在重傳,Cluster lP 已DNAT轉換為后端 Pod IP,如圖所示
![20c21ee6-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYWAbJzxAAHPMU_CpiM303.png)
后端 Pod(registry服務)所在節(jié)點的flannel.1上未抓到任何數(shù)據包,如圖所示
![20dc53ce-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaAVKjkAAEWOlt9kWs454.png)
請求service的ClusterlP時,在兩端物理機網卡抓包,發(fā)包端如圖所示,封裝的源端節(jié)點 IP 是 10.153.204.15,但一直在重傳
![210c52ae-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaAHbzZAAJ_oZzbG-o411.png)
收包端收到了包,但未回包,如圖所示
![21497490-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaAJd-OAAJceKlRrL8417.png)
由此可以知道,NAT 的動作已經完成,而只是后端 Pod(registry服務)沒有回包,接下來在問題節(jié)點執(zhí)行curl10.233.65.46:5000
,在問題節(jié)點和后端(registry服務)Pod 所在節(jié)點的flannel.1上同時抓包,兩節(jié)點收發(fā)正常,發(fā)包如圖所示
![22397454-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaAEaI3AAMWbukgRSE599.png)
![226fd382-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaAHlJVAAMPfIPuxBU185.png)
接下來在兩端物理機網卡接口抓包,因為數(shù)據包通過物理機網卡會進行vxlan封裝,需要抓vxlan設備的 8472 端口,發(fā)包端如圖所示
發(fā)現(xiàn)網絡鏈路連通,但封裝的 IP 不對,封裝的源端節(jié)點 IP 是 10.153.204.228,但是存在問題節(jié)點的 IP 是 10.153.204.15
![23fe6420-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYaALNZQAARnwm185aU275.png)
后端 Pod 所在節(jié)點的物理網卡上抓包,注意需要過濾其他正常節(jié)點的請求包,如圖所示;發(fā)現(xiàn)收到的數(shù)據包,源地址是 10.153.204.228,但是問題節(jié)點的 IP 是 10.153.204.15。
![243c4e98-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYeAJIU8AAT1us8YteI408.png)
此時問題以及清楚了,是一個 Pod 存在兩個 IP,導致發(fā)包和回包時無法通過隧道設備找到對端的接口,所以發(fā)可以收到,但不能回。
問題節(jié)點執(zhí)行ip addr
,發(fā)現(xiàn)網卡enp26s0f0上配置了兩個 IP,如圖所示
![247753a8-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYeAebVGAAFvs56UrHM456.png)
進一步查看網卡配置文件,發(fā)現(xiàn)網卡既配置了靜態(tài) IP,又配置了 dhcp 動態(tài)獲取 IP。如圖所示
![2491119e-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYeAOxVzAAHtGo6U0I0649.png)
最終定位原因為問題節(jié)點既配置了 dhcp 獲取 IP,又配置了靜態(tài) IP,導致 IP 沖突,引發(fā)網絡異常
解決方法:修改網卡配置文件/etc/sysconfig/network-scripts/ifcfg-enp26s0f0
里BOOTPROTO="dhcp"
為BOOTPROTO="none"
;重啟docker和kubelet問題解決。
集群外云主機調用集群內應用超時
問題現(xiàn)象:Kubernetes 集群外云主機以 http post 方式訪問 Kubernetes 集群應用接口超時
環(huán)境信息:Kubernetes 集群:calicoIP-IP 模式,應用接口以 nodeport 方式對外提供服務
客戶端:Kubernetes 集群之外的云主機
排查過程:
- 在云主機 telnet 應用接口地址和端口,可以連通,證明網絡連通正常,如圖所示
- 云主機上調用接口不通,在云主機和 Pod 所在 Kubernetes 節(jié)點同時抓包,使用 wireshark 分析數(shù)據包
![24ded046-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYeAcsD0AAJmGmNA71g062.png)
通過抓包結果分析結果為 TCP 鏈接建立沒有問題,但是在傳輸大數(shù)據的時候會一直重傳1514大小的第一個數(shù)據包直至超時。懷疑是鏈路兩端 MTU 大小不一致導致(現(xiàn)象:某一個固定大小的包一直超時的情況)。如圖所示,1514 大小的包一直在重傳。
報文 1-3 TCP 三次握手正常
報文 1 info 中 MSS 字段可以看到 MSS 協(xié)商為 1460,MTU=1460+20bytes(IP 包頭)+20bytes(TCP 包頭)=1500
報文 7 k8s 主機確認了包 4 的數(shù)據包,但是后續(xù)再沒有對數(shù)據的 ACK
報文 21-29 可以看到云主機一直在發(fā)送后面的數(shù)據,但是沒有收到 k8s 節(jié)點的 ACK,結合 pod 未收到任何報文,表明是 k8s 節(jié)點和 POD 通信出現(xiàn)了問題。
![250562ba-2a04-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/59/wKgZomTnHYeAJYgaAAbv9vESs14632.png)
在云主機上使用ping -s
指定數(shù)據包大小,發(fā)現(xiàn)超過 1400 大小的數(shù)據包無法正常發(fā)送。結合以上情況,定位是云主機網卡配置的 MTU 是 1500,tunl0配置的 MTU 是 1440,導致大數(shù)據包無法發(fā)送至tunl0,因此 Pod 沒有收到報文,接口調用失敗。
解決方法:修改云主機網卡 MTU 值為 1440,或者修改 calico 的 MTU 值為 1500,保持鏈路兩端 MTU 值一致。
集群 pod 訪問對象存儲超時
環(huán)境信息:公有云環(huán)境,Kubernetes 集群節(jié)點和對象存儲在同一私有網絡下,網絡鏈路無防火墻限制 k8s 集群開啟了節(jié)點自動彈縮(CA)和 Pod 自動彈縮(HPA),通過域名訪問對象存儲,Pod 使用集群 DNS 服務,集群 DNS 服務配置了用戶自建上游 DNS 服務器
排查過程:
- 使用 nsenter 工具進入 pod 容器網絡命名空間測試,ping 對象存儲域名不通,報錯 unknown server name,ping 對象存儲 lP 可以連通。
-
telnet
對象存儲 80/443 端口可以連通。 -
paping
對象存儲 80/443 端口無丟包。 - 為了驗證 Pod 創(chuàng)建好以后的初始階段網絡連通性,將以上測試動作寫入 dockerfile,重新生成容器鏡像并創(chuàng) pod,測試結果一致。
通過上述步驟,判斷 Pod 網絡連通性無異常,超時原因為域名解析失敗,懷疑問題如下:
- 集群 DNS 服務存在異常
- 上游 DNS 服務存在異常
- 集群 DNS 服務與上游 DNS 通訊異常
- pod 訪問集群 DNS 服務異常
根據上述方向排查,集群 DNS 服務狀態(tài)正常,無報錯。測試 Pod 分別使用集群 DNS 服務和上游 DNS 服務解析域名,前者解析失敗,后者解析成功。至此,證明上游 DNS 服務正常,并且集群 DNS 服務日志中沒有與上游 DNS 通訊超時的報錯。定位到的問題:Pod 訪問集群 DNS 服務超時
此時發(fā)現(xiàn),出現(xiàn)問題的 Pod 集中在新彈出的 Kubernetes 節(jié)點上。這些節(jié)點的kube-proxy
Pod 狀態(tài)全部為pending,沒有正常調度到節(jié)點上。因此導致該節(jié)點上其他 Pod 無法訪問包括 dns 在內的所有 Kubernetes service。
再進一步排查發(fā)現(xiàn)kube-proxy
Pod 沒有配置 priorityclass 為最高優(yōu)先級,導致節(jié)點資源緊張時為了將高優(yōu)先級的應用 Pod 調度到該節(jié)點,將原本已運行在該節(jié)點的 kube-proxy 驅逐。
解決方法:將kube-proxy
設置priorityclass
值為system-node-critical
最高優(yōu)先級,同時建議應用 Pod 配置就緒探針,測試可以正常連通對象存儲域名后再分配任務。
審核編輯:湯梓紅
-
網絡
+關注
關注
14文章
7600瀏覽量
89286 -
kubernetes
+關注
關注
0文章
227瀏覽量
8757
原文標題:Kubernetes 網絡排錯骨灰級中文指南
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
Kubernetes 網絡模型如何實現(xiàn)常見網絡任務
阿里云上Kubernetes集群聯(lián)邦
Kubernetes 從懵圈到熟練:集群服務的三個要點和一種實現(xiàn)
如何部署基于Mesos的Kubernetes集群
![如何部署基于Mesos的<b class='flag-5'>Kubernetes</b><b class='flag-5'>集群</b>](https://file.elecfans.com/web2/M00/49/F4/pYYBAGKhvHyAeRChAAA0TSb8yhI120.png)
淺談Kubernetes集群的高可用方案
![淺談<b class='flag-5'>Kubernetes</b><b class='flag-5'>集群</b>的高可用方案](https://file.elecfans.com/web2/M00/49/F9/pYYBAGKhvIGAVHUHAAAG-7AjgXQ173.png)
Kubernetes網絡模型介紹以及如何實現(xiàn)常見網絡任務
Kubernetes網絡模型的基礎知識
Kubernetes 集群的功能
Kubernetes集群的關閉與重啟
Kubernetes的集群部署
各種網絡組件在 Kubernetes 集群中是如何交互的
![各種<b class='flag-5'>網絡</b>組件<b class='flag-5'>在</b> <b class='flag-5'>Kubernetes</b> <b class='flag-5'>集群</b>中是如何交互的](https://file1.elecfans.com/web2/M00/88/8B/wKgaomRsG7WARog6AAAcsZxqjWw389.png)
評論