【问题标题】:When using Docker, ESTABLISHED connections don't appear in netstat使用 Docker 时,已建立的连接不会出现在 netstat 中
【发布时间】:2016-09-07 09:39:04
【问题描述】:

我有一个在 RHEL 7 上使用 Docker 1.7.0 运行的 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)

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

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

我在客户端看到了不使用 docker 的 ESTABLISHED 连接:

[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-proxy 的 ESTABLISHED 连接?

谢谢

【问题讨论】:

    标签: sockets docker netstat


    【解决方案1】:

    你可以这样做:

    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)

    【讨论】:

    • 实际上这是一个可行的解决方案,但命令应该看起来像sudo nsenter -t &lt;pid&gt; -n netstat | grep ESTABLISHED。注意-n 选项。更多信息可以在这里找到stackoverflow.com/a/40352004/1201488
    • 是的,很抱歉。 -n 是 nsenter 在这里工作所必需的。
    • 对我来说,这表明连接来自本地主机,不知道连接的源地址。有人知道怎么看吗?
    • 使用 'ss' 而不是 'netstat' 可能更好。您可以指定一个可选过滤器并查看连接的两端。示例输入:nsenter -t 73647 -n ss -pnt state established 'dport = 3128' dst 10.1.2.3
    • 只是为了方便。如果这些 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}}
    【解决方案2】:

    你可以使用这个 sn-p 来获取所有 docker 的所有 ESTABLISHED(如果你有 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 LISTEN

    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设置的变量。
    猜你喜欢
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 2013-03-11
    • 2014-05-11
    • 2020-06-07
    • 2018-08-29
    • 2020-05-09
    • 1970-01-01
    相关资源
    最近更新 更多