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 容器暴露的主要内容,如果未能解决你的问题,请参考以下文章