我不确定我是否误解了这里的某些内容,但似乎只能通过从映像创建新容器来设置端口映射。是否有办法将端口映射分配到现有的Docker容器?


当前回答

如果“现有”指的是“正在运行”,那么(目前)不可能添加端口映射。

然而,如果你需要在一个运行的容器中公开一个服务,而不需要停止/重新启动它,你可以动态地添加一个新的网络接口,例如管道。

其他回答

使用实例在Docker Desktop下修改容器的HostPort(适用于Windows 10 / MacOS)

# list all containers
$ docker ps -a
$ docker stop docker101tutorial 
# Use grep to get id of container
$ docker inspect docker101tutorial | grep -i id
        "Id": "sha256:fff0a4b22d6f3d2eb8d2748b8a8bbc9967ea87199988acee8e86ac70bce9c3eb",
# run plain ubuntu docker image with shell and change it's namespace to docker host
# https://stackoverflow.com/questions/60408574/how-to-access-var-lib-docker-in-windows-10-docker-desktop/60411313#60411313
# https://forums.docker.com/t/the-location-of-images-in-docker-for-windows/19647/4
$ docker run -it --privileged --pid=host ubuntu nsenter -t 1 -m -u -i sh
# We want to find out the directory of docker101tutorial container. We are looking for:
# `"Image":"sha256:fff0a4b22d6f3d2eb8d2748b8a8bbc9967ea87199988acee8e86ac70bce9c3eb"`
# in /var/lib/docker/containers/*/config.v2.json
$ find /var/lib/docker/containers/ -name config.v2.json -exec grep -H fff0a4b22d {} \;
/var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/config.v2.json
# edit it
$ vi /var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/hostconfig.json

按i键插入模式。 修改"HostPort":"80"为"HostPort":"8092" 按“退出”键,输入:wq。按回车。 现在不启动/停止docker101tutorial。否则,对HostPort的修改将被恢复。 右键单击Docker桌面托盘图标,然后单击“重新启动”。 在Docker Desktop的容器列表中,查看您的容器。显示的端口应该变为8092。 启动容器。现在它将被映射到主机上的端口8092。

基于@holdfenytolvaj的答案。

对于Windows和Mac用户,还有另一种非常简单友好的方法来更改映射端口:

下载kitematic 进入容器的“设置”页面,在“端口”页签中,可以直接在那里修改已发布的端口。 再次启动容器

我们可以使用方便的工具,如SSH来轻松完成这一任务。

我使用ubuntu主机和基于docker镜像的ubuntu。

在docker内部安装了openssh-client。 外部docker(主机)安装了openssh-server服务器。

当需要绘制一个新端口时,

在docker中运行以下命令

ssh -R8888:localhost:8888 <username>@172.17.0.1

其中“172.17.0.1”为docker接口的IP (你可以通过跑步得到这个 Ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" " on the host)。

在这里,我有本地8888端口映射回主机8888。您可以根据需要更改端口。

如果您还需要一个端口,您可以终止ssh,并使用新端口向其添加多一行-R。

我已经用netcat测试过了。

编辑hostconfig。Json现在似乎不工作。它只以暴露该端口而不将其发布到主机而结束。提交和重新创建容器对我来说不是最好的方法。没人提到docker网络吗?

最好的解决方案是在同一网络中使用反向代理

Create a new network if your previous container not in any named ones. docker network create my_network Join your existing container to the created network docker network connect my_network my_existing_container Start a reversed proxy service(e.g. nginx) publishing the ports you need, joining the same network docker run -d --name nginx --network my_network -p 9000:9000 nginx Optionally remove the default.conf in nginx docker exec nginx rm /etc/nginx/conf.d/default.conf Create a new nginx config server { listen 9000; location / { proxy_pass http://my_existing_container:9000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } Copy the config to nginx container. docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf Restart nginx docker restart nginx

优点:要发布新端口,你可以安全地停止/更新/重新创建nginx容器,而不需要触及业务容器。如果你需要nginx的零停机时间,可以添加更多的反向代理服务加入同一个网络。此外,一个容器可以加入多个网络。

编辑:

对于反向代理非http服务,配置文件有点不同。这里有一个简单的例子:

upstream my_service {
    server my_existing_container:9000;
}

server {
    listen 9000;
    proxy_pass my_service;
}

可以通过直接编辑hostconfig修改端口映射。Json文件 /var/lib/docker/containers/ hash_of_the_container / hostconfig。/var/snap/docker/common/var-lib-docker/containers/[hash_of_the_container]/hostconfig. Json或/var/snap/docker/common/var-lib-docker/containers/[hash_of_the_container]/hostconfig. Json。如果你安装Docker作为一个snap. json,我相信。

你可以通过docker inspect <container_name>命令来确定[hash_of_the_container],“Id”字段的值就是哈希值。

停止容器(docker Stop <container_name>)。 停止docker服务(根据Tacsiazuma的评论) 修改文件。 重新启动docker引擎(刷新/清除配置缓存)。 启动容器(docker Start <container_name>)。

所以你不需要用这种方法创建一个图像。您还可以在这里更改重启标志。

附注:您可以访问https://docs.docker.com/engine/admin/了解如何根据您的主机正确重新启动docker引擎。我使用sudo systemctl restart docker重新启动在Ubuntu 16.04上运行的docker引擎。