CLOSE_WAIT 在 kubernetes 節點上不可見
調試一個
tcp: out of memory
錯誤,我發現一個程序(來自一個容器)在CLOSE_WAIT
狀態上有很多連接,也就是08
當我 cat 時/proc/XXX/net/tcp
但是 netstat 或 ss 都沒有顯示那些洩露的連接。
133: 0E03540A:9D9C 804CC2AD:01BB 08 00000000:00059D7A 00:00000000 00000000 0 0 316215 1 ffff8f677201df00 20 4 0 10 -1
134: 0E03540A:8316 80A7E940:01BB 08 00000000:00000000 00:00000000 00000000 0 0 255647 1 ffff8f67c9592600 20 4 1 10 -1
135:0E03540A:8874 808C7D4A:01BB 08 00000000:00037EED 00:0000000000000000000000000000000000000.000000 0 0 331603 1 FFFFFF68E37A7200 20 4 1 10-1
136: 1 136:0EDEBIDY000BC. 0EE0EBCC. 0EE0BCC.E222222222222222222222222222222222222222。 1 FFFF8F67BD1EDF00 20 4 0 10 -1
137:0E03540A:DAEC 804CC2AD:01BB 08 00000000:0005B41A 00:00000000000000000000000000000000000000000. 0 0 0 0 0 216048 1 FFFFFF567DAF9AF80 20
4.0138:0.0138:0.11 138:0.11 138: 00000000 0 0 243082 1 ffff8f67db637200 20 4 30 10 -1
140: 0E03540A:BAE4 800FB16C:01BB 08 00000000:000D8432 00:00000000 00000000 0 0 245062 1 ffff8f67640f8980 20 4 1 10 -1
141: 0E03540A:9754 804CC2AD:01BB 08 00000000:00003186 00:00000000 00000000 0 0 298890 1 ffff8f676e1a5f00 20 4 1 10 -1
142: 0E03540A:C6FC 800FB16C:01BB 08 00000000:000658C9 00:00000000 00000000 0 0 299343 1 ffff8f68dcef5580 20 4 0 10 -1
143: 0E03540A:CB24 804CC2AD:01BB 08 00000000:0005BBB4 00:00000000 00000000 0 0 316285 1 ffff8f6772019300 20 4 1 10 -1
144: 0E03540A:8204 80A7E940:01BB 08 00000000:0005DD3A 00:00000000 00000000 0 0 217390 1 ffff8f67dbc20000 20 4 0 10 -1
145: 0E03540A:8BC8 80016642:01BB 08 00000000:00059847 00:00000000 00000000 0 0 275095 1 ffff8f67b6d7a600 20 4 1 10 -1
146: 0E03540A:C612 8005FB8E:01BB 08 00000000:0003EC48 00:00000000 00000000 0 0 252281 1 ffff8f67cf014280 20 4 1 10 -1
為什麼 netstat 沒有顯示這些連接以及如何在不深入研究每個程序細節的情況下獲取它們?
如果您從主機查看此內容,則您處於初始網路命名空間而不是容器的網路命名空間中:這些連接或狀態不可見,因為它們未由初始網路命名空間的網路堆棧處理。當在程序目錄中跟踪一個條目時
/proc
,這個條目是從程序的角度來看的……有時,有時會顯示相關的命名空間資訊,但工具並不意味著使用它。所以你必須先切換到研究程序的網路命名空間。
就像(使用root使用者)一樣簡單:
nsenter -t XXX --net -- ss -tn
或查找程序(如在初始 pid 命名空間中看到的,而不是容器的):
nsenter -t XXX --net -- ss -tnp state CLOSE-WAIT
通常,人們會搜尋每個 pod(或其他技術中的容器)而不是每個程序。各種容器技術允許從容器名稱中檢索 PID 程序(例如:LXC’s
lxc-info -Hp -n containername
或 Docker’sdocker inspect --format '{{.State.Pid}}' containername
),但如果後端不是 Docker,我不知道 Kubernetes 是否以及如何使用這些資訊。同樣對於某些工具來說,它比這更困難一些,因為例如
/sys
應該重新安裝/sys/class/net
以反映新的網路命名空間的介面視圖:現在將有兩個命名空間要更改:目標程序的命名空間和臨時掛載命名空間(不損壞初始,也不使用可能沒有所需命令的目標)。無論如何,該ss
命令純粹在套接字上執行,不需要這個。例如,過時的
brctl show
命令需要它才能正常工作:nsenter -t XXX --net -- unshare --mount -- sh -c 'mount -t sysfs sysfs /sys; brctl show'