Docker 和 netstat:netstat 不显示端口,由 docker 容器暴露

Posted

技术标签:

【中文标题】Docker 和 netstat:netstat 不显示端口,由 docker 容器暴露【英文标题】:Docker and netstat: netstat is not showing ports, exposed by docker containers 【发布时间】:2016-07-27 01:57:58 【问题描述】:

我通过类似的方式将容器的 docker 端口暴露给主机

docker run -p 80:80 ...

然后我尝试使用netstat 显示所有侦听端口以进行调试,例如:

netstat -at

奇怪的是 netstat 不会显示带有暴露端口的 docker 容器,尽管它们正在侦听并回复浏览器。

如何让netstat 显示那些暴露的端口?


更新: 我在 Debian 8 Jessie 上运行它。这是我的工作:

docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                                      NAMES
9dfa08bab50d        workflows-nginx     "/bin/sh -c '/usr/sbi"   2 hours ago         Up 2 hours                  0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   workflows-nginx
d0b0c3f90f13        workflows-django    "/bin/sh -c 'python /"   7 hours ago         Up 3 hours                  0.0.0.0:8000->8000/tcp                     workflows-django
99a857c92533        workflows-db        "/docker-entrypoint.s"   7 hours ago         Up 3 hours                  5432/tcp                                   workflows-db

这里 docker 报告容器端口被转发到主机。此外,如果我停止 workflows-nginx 容器,它将停止通过 http(端口 80)响应浏览器。如果我再次启动它,它会再次开始响应。

这是sudo netstat -at | less的输出:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 *:ssh                   *:*                     LISTEN     
tcp        0      0 localhost:ipp           *:*                     LISTEN     
tcp        0      0 *:15672                 *:*                     LISTEN     
tcp        0      0 *:postgresql            *:*                     LISTEN     
tcp        0      0 localhost:smtp          *:*                     LISTEN     
tcp        0      0 *:25672                 *:*                     LISTEN     
tcp        0      0 *:48142                 *:*                     LISTEN     
tcp        0      0 *:sunrpc                *:*                     LISTEN     
tcp        0      0 *:epmd                  *:*                     LISTEN     
tcp        0      0 bob-acer:34866          104.16.33.249:http      ESTABLISHED
tcp        0      0 bob-acer:42380          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42543          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42525          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:44076          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42944          ***.com:https ESTABLISHED
tcp        0      0 localhost:epmd          localhost:50831         ESTABLISHED
tcp        0      0 bob-acer:42655          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42384          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:44626          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42390          ***.com:https ESTABLISHED
tcp        0      0 localhost:50831         localhost:epmd          ESTABLISHED
tcp        0      0 bob-acer:48301          c2.52.c0ad.ip4.st:https ESTABLISHED
tcp        0      0 bob-acer:42151          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42205          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:42539          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:44737          ***.com:https ESTABLISHED
tcp        0      0 bob-acer:39648          77.94.164.251:https     ESTABLISHED
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
tcp6       0      0 localhost:ipp           [::]:*                  LISTEN     
tcp6       0      0 [::]:postgresql         [::]:*                  LISTEN     
tcp6       0      0 localhost:smtp          [::]:*                  LISTEN     
tcp6       0      0 [::]:44794              [::]:*                  LISTEN     
tcp6       0      0 [::]:8000               [::]:*                  LISTEN     
tcp6       0      0 [::]:amqp               [::]:*                  LISTEN     
tcp6       0      0 [::]:sunrpc             [::]:*                  LISTEN     
tcp6       1      0 localhost:58497         localhost:ipp           CLOSE_WAIT

如您所见,端口 80 和端口 443 均未报告。 workflows-django 的 8000 端口由于某种原因在 IPv6 接口上打开。此外,我忘记在主机上禁用 postgres,但它们仍然不会与 postgres 容器 workflows-db 发生冲突。

一切都在我的本地笔记本上运行,所以我想不会与主机有任何混淆。

我的 docker 版本是:

docker --version
Docker version 1.10.3, build 20f81dd

回答:这与 docker EXPOSE 参数有关。如果您在 dockerfile 中写入这一行并使用 -p 运行容器,则该端口将在 netstat 中可见。如果你使用 -p 但不写 EXPOSE,你的端口不会被 netstat 列出。

【问题讨论】:

快到 2021 年了,还没有解决办法吗? ?????? 【参考方案1】:

netstat 应该显示暴露的端口。这是一个例子

anovil@anovil-Latitude-E6440:docker$ sudo netstat -at|grep 3030
anovil@anovil-Latitude-E6440:docker$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
anovil@anovil-Latitude-E6440:docker$ docker run -d -p 3030:80 httpd:2.4
4310ac5fbdbc7314ab4d23e34099a710a3a8790dcf2c6d0a84202c1de5c9fd30
anovil@anovil-Latitude-E6440:docker$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                  NAMES
4310ac5fbdbc        httpd:2.4           "httpd-foreground"   3 minutes ago       Up 3 minutes        0.0.0.0:3030->80/tcp   hungry_fermat
anovil@anovil-Latitude-E6440:docker$ sudo netstat -at|grep 3030
tcp6       0      0 [::]:3030               [::]:*                  LISTEN
anovil@anovil-Latitude-E6440:docker$ sudo netstat -tulpn|grep 3030
tcp6       0      0 :::3030                 :::*                    LISTEN      10294/docker-proxy
anovil@anovil-Latitude-E6440:docker$ 

您需要验证自己的一些基本事项:

    您是否以提升的权限运行 netstat?非 root 用户可能会错过一些东西 您的 docker 容器是否与您预期的一样在同一主机上运行?检查docker ps docker ps 是否列出端口转发?就像从上面一样,你应该能够看到像这样的东西0.0.0.0:3030->80/tcp

还要注意,docker-proxy 是在主机上运行的。 上面的所有命令都假定您在 linux 上运行。 这是用 ubuntu 15.10 测试的

如果您仍然觉得缺少转发,请回发您的操作系统、docker 版本等。

谢谢,

【讨论】:

感谢您的详细解答。我做了你建议的每一项检查,并将结果写在我的问题中(见更新)。尽管如此,netstat 不会报告 docker 端口,尽管它们确实有效。 感觉跟dockerEXPOSE参数有关。如果您在 dockerfile 中写入这一行并使用-p 运行容器,则该端口将在 netstat 中可见。如果您使用-p 但不写EXPOSE,则您的端口不会被netstat 列出。尚未检验此假设。 当我使用 sudo 命令运行 netstat 时,它对我有用。我忘记了 docker 正在以特权权限运行【参考方案2】:

此代码将向您显示打开的端口以及容器内的 pid:

container_name=some_container_name
c_pid=`docker container inspect -f ".State.Pid" $container_name`
nsenter -t $c_pid -n netstat -anp

【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常质量更好,并且更有可能吸引投票。【参考方案3】:

回答问题永远不会太晚。

使用netstat -tln,而不是netstat -at

如果您通知netstat--numeric 选项,答案很简单。通过使用此选项,netstat 将打印带有 数字 的地址,而不是 有意义的字符串。然后你可以像你提到的那样grep它们。下面展示了它是如何工作的。

[root@A01-R26-I52-155-3002023 ~]# netstat -tl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 localhost.localdom:smux 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18121 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18122 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18123 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18124 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18125 0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN     
tcp        0      0 localhost.localdo:18928 0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:20080           0.0.0.0:*               LISTEN     
tcp        0      0 A01-R26-:univ-appserver 0.0.0.0:*               LISTEN     
tcp        0      0 A01-R26-:univ-appserver 0.0.0.0:*               LISTEN     
tcp        0      0 localhost.:search-agent 0.0.0.0:*               LISTEN     
tcp        0      0 localhost:mosaicsyssvc1 0.0.0.0:*               LISTEN     
tcp        0      0 A01-R26-I52-155-300:ssh 0.0.0.0:*               LISTEN     
tcp6       0      0 [::]:37611              [::]:*                  LISTEN     
tcp6       0      0 [::]:sunrpc             [::]:*                  LISTEN     
tcp6       0      0 [::]:microsan           [::]:*                  LISTEN     
tcp6       0      0 [::]:commtact-http      [::]:*                  LISTEN     
[root@A01-R26-I52-155-3002023 ~]# netstat -tln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:199           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18121         0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18122         0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18123         0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18124         0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18125         0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:18928         0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:20080           0.0.0.0:*               LISTEN     
tcp        0      0 10.217.52.155:1233      0.0.0.0:*               LISTEN     
tcp        0      0 10.218.52.155:1233      0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:1234          0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:1235          0.0.0.0:*               LISTEN     
tcp        0      0 10.217.52.155:22        0.0.0.0:*               LISTEN     
tcp6       0      0 :::37611                :::*                    LISTEN     
tcp6       0      0 :::111                  :::*                    LISTEN     
tcp6       0      0 :::20001                :::*                    LISTEN     
tcp6       0      0 :::20002                :::*                    LISTEN

【讨论】:

别忘了在提升模式下使用 sudo 运行它。【参考方案4】:

它们已列出,但与您可能期望的方式不同。如果您正在寻找 ipv4 监听端口,您将看不到它(除非我相信如果您同时使用 EXPOSE 和发布 (-p) 机制),但您将看到的是 docker IPv6 上的代理,例如对于 mysql 容器:

netstat -tlpn4
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::3306                 :::*                    LISTEN      9608/docker-proxy

【讨论】:

以上是关于Docker 和 netstat:netstat 不显示端口,由 docker 容器暴露的主要内容,如果未能解决你的问题,请参考以下文章

查看端口或者进程命令(netstat & lsof)

学习docker遇到的错误和解决方案

Netstat查看端口状态,netstat命令详解

在输入了netstat -n后,为啥没有出现任何有用的信息

linux中netstat和ss的区别?

traceroutenetstatpingtelnet 网络工具 之 netstat