调试一个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用户)一样简单:
或查找进程(如在初始 pid 命名空间中看到的,而不是容器的):
通常,人们会搜索每个 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
命令需要它才能正常工作: