如何从检查Docker容器中获取暴露的端口?

8
假设我使用以下命令启动一个Docker容器:
docker run -d --name my-container -p 1234 my-image

并且运行docker ps显示该镜像的端口绑定为...

80/tcp, 443 /tcp. 0.0.0.0:32768->1234/tcp

我能否使用docker inspect来获取映射到1234端口的端口号(在本例中为32768)?

类似于使用以下命令解析和获取IP地址...

IP=$(docker inspect -f "{{ .Networksettings.IPAddress }} my-container)

我希望能够做类似于以下的事情

ASSIGNED_PORT=$(docker inspect -f "{{...}} my-container)

我不确定是否可以通过Docker的方式来实现这个操作,但是我想应该有一些命令行技巧(如grep、sed等)可以让我做到这样的事情。

当我运行docker inspect my-container并查看NetworkSettings时...我看到如下内容:

"NetworkSettings": {
        ...
        ...
        ...
        "Ports": {
            "1234/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "32768"
                }
            ],
            "443/tcp": null,
            "80/tcp": null
        },
        ...
        ...
    },

在这种情况下,我希望它能够找到 HostPort,而不需要我告诉它任何关于端口1234的信息(它应该忽略下面的443和80),并返回 32768

我手头没有Docker提示符,可以执行docker inspect -f '{{ .NetworkSettings.Port }}' container_id(我们将进行优化),或者您可以尝试执行docker inspect --format '{{ (index (index .NetworkSettings.Ports "1234/tcp") 0).HostPort }} container_id' - user2915097
请查看我的答案:https://dev59.com/uV0a5IYBdhLWcg3wboIv#30353018 - user2915097
@user2915097 NetworkSettings.Port 不起作用(请参见我在 docker inspect 输出上面所做的编辑)。 - TheJediCowboy
@user2915097 我已经更新了我的问题。我不想告诉它“1234”,因为我可能不知道它。 - TheJediCowboy
当docker inspect深入时,它需要找到1234/tcp下面的内容,当然你可以随时使用jq https://stedolan.github.io/jq/和管道grep进行黑客攻击。 - user2915097
docker port my-container 1234 有帮助吗?请参考http://docs.docker.com/reference/commandline/port/。 - Andy
6个回答

8

执行命令:docker inspect --format="{{json .Config.ExposedPorts }}" src_python_1

结果:{"8000/tcp":{}}

验证(使用docker ps):

e5e917b59e15        src_python:latest   "start-server"         22 hours ago        Up 22 hours         0.0.0.0:8000->8000/tcp                                        src_python_1

3
你能更新一下代码,只获取端口号并将其赋值给一个变量吗? - TheJediCowboy
@TheJediCowboy,现在的问题是如何将结果解析为Shell脚本数组,因为一个容器可能有很多暴露的端口。我会研究一下。目前我所知道的是,docker inspect --format使用Go语言模板包返回结果。 - mondaini
实际上,这个命令从容器内部获取了服务的暴露端口号 - 它并不会显示 HostPort,也就是如何通过 Docker 机器 IP 访问该服务。Alen Komljen(https://dev59.com/PI3da4cB1Zd3GeqPxD5c#31655055)和 Travis Reeder(https://dev59.com/PI3da4cB1Zd3GeqPxD5c#48965777)提供的解决方案是 OP 问题的正确答案。 - david-err

4

由于一个容器可以有多个端口,其中一些是公开的,一些不是,因此与IP地址不同,这并不容易,但以下代码可以解决此问题:

sudo docker inspect name | grep HostPort | sort | uniq | grep -o [0-9]*

如果有多个端口被暴露,它们将会显示在新的一行上。

2

根据你的喜好,有两个好的选择:docker port my-container 1234 | grep -o [0-9]*$docker inspect --format='{{(index (index .NetworkSettings.Ports "1234/tcp") 0).HostPort}}' my-container


1
使用 jq:
docker inspect --format="{{json .}}" my-container | jq '.NetworkSettings.Ports["1234/tcp"][0].HostPort'

docker run 中指定的端口替换1234。


1
以上的答案接近了我的问题并让我找到了正确的方向,但我一直收到以下错误信息:

模板解析错误:模板::1:操作数中有意外的“/”

我在这里找到了答案:https://github.com/moby/moby/issues/27592 这是最终对我有效的方法:
docker inspect --format="{{(index (index .NetworkSettings.Ports \"80/tcp\") 0).HostPort}}" $INSTANCE_ID

0

我曾经使用过docker inspect <container>docker inspect <container>| jq的组合来剥离端口。

在下面的例子中,我正在查看dsb-server容器,并且我要查找的端口是8080/tcp

docker ps

CONTAINER ID        IMAGE                                                                         COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
98b4bec33ba9        xxxxx:dsbv3   "./docker-entrypoint."   6 days ago          Up 6 days           8009/tcp, 0.0.0.0:4848->4848/tcp, 8181/tcp, 0.0.0.0:9013->8080/tcp   dsb-server

去除端口号

docker inspect dsb-server| jq -r '.[].NetworkSettings.Ports."8080/tcp"[].HostPort'

9013

docker inspect --format='{{(index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort}}'

9013


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