使用Docker时,netstat命令中不会显示已建立的连接

25

我在运行Docker 1.7.0的RHEL 7上有一个Docker容器。该容器中运行的程序在端口5000上监听TCP连接。 在我的Dockerfile中,我加入了EXPOSE 5000语句,并使用以下命令运行容器:

docker run \
--name myProgram \
--detach \
--publish 5000:5000 \
--volume /home/docker/apps/myProgram/logs:/var/log/myProgram/ \
--volume /home/docker/apps/myProgram/conf:/usr/local/snnotificationreceiver/conf/ \
--restart always \
10.167.152.15:5000/myProgram:1.0.0
当我在主机上执行netstat时,我看到了LISTEN套接字:
[root@server bin]# netstat -naop | grep 5000
tcp6       0      0 :::5000                 :::*                    LISTEN      33595/docker-proxy   off (0.00/0/0)

我可以通过连接到主机IP地址的5000端口来连接应用程序,并且我发送到应用程序的数据会到达。我知道这一点是因为我在我的应用程序日志中看到了它,应用程序也通过套接字发送数据。但是,在Docker主机上使用netstat时,我没有看到任何已建立的连接:

[root@server bin]# netstat -naop | grep ESTABLISHED 

我在客户端看到了已建立的连接,该连接未使用Docker:

[root@client ~]# netstat -naop | grep 5000
tcp        0      0 10.167.43.73:39218      10.167.152.138:5000     ESTABLISHED 21429/telnet         off (0.00/0/0)

我没有找到任何等同于netstat的docker命令或类似命令,这是正常的吗?我该如何查看与容器或docker代理建立的连接?

谢谢

2个回答

30

您可以选择以下两种方式:

docker exec <containerid> netstat -tan | grep ESTABLISHED

如果你的Docker镜像中没有netstat:

docker inspect -f '{{.State.Pid}}' <containerid> # note the PID
sudo nsenter -t <pid> -n netstat | grep ESTABLISHED

nsenter是util-linux软件包的一部分。 (抄袭自@larsks)


2
实际上这是一个可行的解决方案,但命令应该像这样:sudo nsenter -t <pid> -n netstat | grep ESTABLISHED。请注意 -n 选项。更多信息可以在这里找到:https://dev59.com/81kS5IYBdhLWcg3wHTJy#40352004。 - Ivan Velichko
1
是的,对不起。在这里使用nsenter需要-n参数。 - AdvilUser
对我来说,这显示连接来自本地主机,没有关于连接源地址的线索。有人知道如何查看吗? - jjmontes
2
使用“ss”而不是“netstat”可能更可取。您可以指定一个可选的过滤器并查看连接的两端。示例输入:nsenter -t 73647 -n ss -pnt state established 'dport = 3128' dst 10.1.2.3 - Cameron Kerr
仅为方便起见。如果这些Docker容器资源由Kubernetes部署对象(副本集)编排和管理,它们将具有标签io.kubernetes.container.name={.spec.template.spec.containers[*].name}(标签值以jsonpath语法表示,并可以通过kubectl get deployment -owide从CONTAINERS列中查看)。要获取指定的容器名称/ID,请使用docker container ls -f label=io.kubernetes.container.name=my-nginx --format={{.Names}}docker container ls -f label=io.kubernetes.container.name=my-nginx --format={{.ID}} - samm

6
您可以使用此代码片段获取所有已建立的 docker 的信息,只需一行命令(如果您拥有 nsenter)。
docker inspect --format '{{.State.Pid}} {{printf "%.13s" .ID}} {{.Name}}' \
$(docker ps --format '{{.ID}}') | while read dockpid dockid dockname
    do
    echo $dockid $dockname
    sudo nsenter -t $dockpid -n netstat -pan | grep ESTABLISHED
done

注意grep中的“ESTABLISHED”。

您可以使用netstat -pnl检查TCP和UDP监听连接。

docker inspect --format '{{.State.Pid}} {{printf "%.13s" .ID}} {{.Name}}' \
$(docker ps --format '{{.ID}}') | while read dockpid dockid dockname
    do
    echo $dockid $dockname
    sudo nsenter -t $dockpid -n netstat -pnl
done

或仅为TCP监听

docker inspect --format '{{.State.Pid}} {{printf "%.13s" .ID}} {{.Name}}' \
$(docker ps --format '{{.ID}}') | while read dockpid dockid dockname
    do
    echo $dockid $dockname
    sudo nsenter -t $dockpid -n netstat -pnlt
done

应该是 echo $dockid $dockname,因为它使用了前面 read dockpid dockid dockname 设置的变量。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接