如何将端口映射分配给现有的Docker容器?

问题描述 投票:320回答:12

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

docker port lxc linux-containers
12个回答
392
投票

我也对这个问题感兴趣。

正如@Thasmo所提到的,只能使用docker run命令指定端口转发。 其他命令,docker start没有-p选项,docker port只显示当前转发。

要添加端口转发,我始终按照以下步骤操作:

  1. stop跑步集装箱 docker stop test01
  2. 容器的commit docker commit test01 test02 注意:上面的test02是我用test01容器构建的新图像。
  3. 从承诺的形象重新qazxsw poi qazxsw poi

第一个8080是本地端口,第二个8080是集装箱端口。


1
投票
  1. 停止docker引擎和该容器。
  2. 转到ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "目录并编辑iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT} iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT} iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}
  3. 编辑你想要改变的/var/lib/docker/containers/${container_id}
  4. 启动docker引擎和容器。

0
投票

作为hostconfig.jsonPortBindings.HostPort的补充

您也可以在创建容器时使用response随机映射端口,但要注意安全性!

@Fujimoto-Youichi eq to $ docker run -P CONTAINER:“它将所有暴露的端口发布到随机端口”,

然后运行-P到fin端口映射,如下图所示:

--publish-all

docker inspect CONTAINER中阅读更多关于docker inspect for a rabbitmq container show all ports mapping的信息


-2
投票

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

  1. 下载kitematic
  2. 进入容器的设置页面,在ports选项卡上,可以直接修改已发布的端口。
  3. 再次启动容器

-9
投票

如果您只想更改正在运行的容器的端口,请执行以下操作:

  1. 停止现有容器 sudo码头工人停止NAME
  2. 现在使用新端口映射重新启动 sudo docker run -d -p 81:80 NAME

在哪里:

“-d”到后台/守护进程的docker

“-p”启用端口映射

用于访问浏览器的“81”外部(公开)端口

“80”内部docker容器监听端口


222
投票

您可以通过直接编辑run上的docker run -p 8080:8080 -td test02 文件来更改端口映射

您可以通过hostconfig.json命令确定[hash_of_the_container],并且“Id”字段的值是哈希值。

/var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

因此,您无需使用此方法创建图像。您也可以在此处更改重启标志。

附:您可以访问docker inspect <container_name>以了解如何根据主机正确重启docker引擎。我使用1) stop the container 2) stop docker service (per Tacsiazuma's comment) 3) change the file 4) restart your docker engine (to flush/clear config caches) 5) start the container 重新启动在Ubuntu 16.04上运行的docker引擎


27
投票

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

但是,您可以动态添加新的网络接口,例如, https://docs.docker.com/engine/admin/,如果您需要在正在运行的容器中公开服务而不停止/重新启动它。


16
投票

不确定是否可以将端口映射应用于正在运行的容器。您可以在运行与创建新容器不同的容器时应用端口转发。

sudo systemctl restart docker

将开始运行容器。 Pipework解释了端口重定向。


13
投票

在Fujimoto Youichi的例子中,$ docker run -p <public_port>:<private_port> -d <image> 是一个容器,而This tutorial是一个图像。

在执行test01之前,您可以删除原始容器,然后再次为容器指定相同的名称:

test02

(使用docker run将端口暴露给随机端口而不是手动分配)。


11
投票

编辑hostconfig.json现在似乎无法正常工作。它只会以暴露但未发布到主机的端口结束。承诺和重新创建容器对我来说不是最好的方法。没有人提到$ docker stop container01 $ docker commit container01 image01 $ docker rm container01 $ docker run -d -P --name container01 image01

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

  1. 如果您之前的容器不在任何已命名的容器中,请创建一个新网络 -P
  2. 将现有容器加入已创建的网络 docker network
  3. 启动反向代理服务(例如nginx),发布所需的端口,加入同一网络 docker network create my_network (可选)删除nginx中的default.conf docker network connect my_network my_existing_container
  4. 创建一个新的nginx配置 docker run -d --name nginx --network my_network -p 9000:9000 nginx 将配置复制到nginx容器。 docker exec nginx rm /etc/nginx/conf.d/default.conf
  5. 重启nginx 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; } }

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

编辑:

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

docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf

7
投票

如果你运行docker restart nginx它会产生一个新的图像,这很可能不是你想要的。

如果要更改当前图像,请执行以下操作:

upstream my_service { server my_existing_container:9000; } server { listen 9000; proxy_pass my_service; }

获取目标容器的ID并转到:

docker run <NAME>

停止容器:

docker ps -a

更改文件

cd /var/lib/docker/containers/<conainerID><and then some:)>

并更改文件

docker stop <NAME>

重新启动docker它应该可以工作。


5
投票

我们使用像ssh这样的方便工具来轻松实现这一目标。

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

  1. 在docker里面安装了openssh-client。
  2. 外部docker(主机)安装了openssh-server服务器。

当需要映射出新端口时,

在docker里面运行以下命令

vi config.v2.json

"Config": {
    ....
    "ExposedPorts": {
        "80/tcp": {},
        "8888/tcp": {}
    },
    ....
},
"NetworkSettings": {
....
"Ports": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],

172.17.0.1是docker接口的ip(你可以通过在主机上运行vi hostconfig.json "PortBindings": { "80/tcp": [ { "HostIp": "", "HostPort": "80" } ], "8888/tcp": [ { "HostIp": "", "HostPort": "8888" } ] } 来获得这个)。

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

如果你还需要一个端口,你可以杀死ssh并使用新端口再添加一行-R。

我用netcat测试了这个。


4
投票

如果你对Docker深度配置IPtables不满意,那么你的另一种方式就是你的朋友。

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

这只是一个技巧而不是推荐的方式,这适用于我的场景,因为我无法阻止容器,我希望也会帮助你。

© www.soinside.com 2019 - 2024. All rights reserved.