Docker:有啥方法可以列出正在运行的 docker 容器中打开的套接字?

Posted

技术标签:

【中文标题】Docker:有啥方法可以列出正在运行的 docker 容器中打开的套接字?【英文标题】:Docker: any way to list open sockets inside a running docker container?Docker:有什么方法可以列出正在运行的 docker 容器中打开的套接字? 【发布时间】:2017-03-14 00:35:33 【问题描述】:

我想在正在运行的 docker 容器中执行 netstat 以查看打开的 TCP 套接字及其状态。但是,在我的一些 docker 容器上,netstat 不可用。有没有办法在不使用 netstat 的情况下,通过一些 docker API 来获取打开的套接字(及其状态,以及它们连接到的 IP 地址(如果有))? (顺便说一句,我的容器使用 docker-proxy - 即不直接桥接)

我想我可以直接查看 /proc 文件系统,但在这一点上,我还不如 docker cp netstat 进入容器并执行它。我想知道 docker 是否可以为此提供任何设施。

【问题讨论】:

【参考方案1】:

您可以使用nsenter 命令在 Docker 容器的网络命名空间内的主机上运行命令。只需获取 Docker 容器的 PID:

docker inspect -f '.State.Pid' container_name_or_id

例如,在我的系统上:

$ docker inspect -f '.State.Pid' c70b53d98466
15652

一旦你有了 PID,就用它作为nsenter 的目标 (-t) 选项的参数。例如,在容器网络命名空间内运行netstat

$ sudo nsenter -t 15652 -n netstat
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     

请注意,即使容器没有安装 netstat,这仍然有效:

$ docker exec -it c70b53d98466 netstat
rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container_linux.go:247: starting container process caused \"exec: \\\"netstat\\\": executable file not found in $PATH\"\n"

nsenterutil-linux 包的一部分)

【讨论】:

此方案是否适用于windows、mac等其他平台? @Rao,可能:nsenter 是一个 Linux 命令,因此您需要能够登录到实际用于托管 Docker 容器的 Linux VM。当然,该 VM 需要有可用的 nsenter 命令。 你可以使用这个 sn-p 来获取所有 docker 的所有 netstat ***.com/questions/37171909/… 在 AWS EKS 节点上,我是 root,但得到:sudo nsenter -t 14207 -n netstat 返回 nsenter: cannot open /proc/14207/ns/net: No such file or directory。我可以看到它说的路径不存在,但似乎无法做任何事情来询问它。有人遇到过这个吗? nsenter => 权限被拒绝 sudo nsenter => bash: sudo: command not found【参考方案2】:

@larsks 答案中的两个命令合并为一行 - 无需复制粘贴 PID(只需替换 container_name_or_id):

sudo nsenter -t $(docker inspect -f '.State.Pid' container_name_or_id) -n netstat

【讨论】:

旁注:需要添加另一个sudo,以便命令为... $(sudo docker inspect ...,否则如果不在root shell 中运行,该命令将失败。【参考方案3】:

如果你安装了iproute2包,你可以使用

sudo nsenter -t $(docker inspect -f '.State.Pid' container_name_or_id) -n ss

sudo nsenter -t $(docker inspect -f '.State.Pid' container_name_or_id) -n ss -ltu

它将显示TCPUDP

【讨论】:

【参考方案4】:

如果你想要它们全部(所有容器)试试这个。

$ for i in `docker ps -q` ; do sudo nsenter -t $(docker inspect -f '.State.Pid' $i) -n netstat ; done

【讨论】:

【参考方案5】:

我尝试了其他解决方案,但我的同事给了我这个解决方案,但它对我不起作用。以为我会在这里为像我这样的其他人提一下,供我以后参考哈哈。

docker exec -it [容器名称] bash

grep -v “rem_address” /proc/net/tcp

【讨论】:

【参考方案6】:

server:docker 容器 ls

CONTAINER ID    IMAGE              COMMAND                  CREATED          STATUS           PORTS       NAMES

80acfa804b59    admirito/gsad:10   "docker-entrypoint.s…"   18 minutes ago   Up 10 minutes    80/tcp      gvmcontainers_gsad_1

【讨论】:

这是错误的。这只会给你五个 Dockerimage 声明的端口和那些显式暴露的端口(在这两种情况下,容器进程是否实际上正在侦听都无关紧要......)

以上是关于Docker:有啥方法可以列出正在运行的 docker 容器中打开的套接字?的主要内容,如果未能解决你的问题,请参考以下文章

仅列出停止的 Docker 容器

docke镜像上传到dockerhub仓库和阿里云docker仓库的方法

如何在 docker 容器内部运行 docker命令

Docker - 无法连接到正在运行的映像

Docker 基础命令 简要入门

Docker 查询停止删除和重启容器