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

时间:2013-10-12 14:46:18

标签: docker port lxc linux-containers

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

17 个答案:

答案 0 :(得分:378)

我也对这个问题感兴趣。

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

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

  1. stop正在运行的容器

    docker stop test01
    
  2. commit容器

    docker commit test01 test02
    

    注意:以上,test02是我从test01容器构建的新图片。

  3. 从提交的图片中重新run

    docker run -p 8080:8080 -td test02
    
  4. 第一个8080是本地端口,第二个8080是容器端口。

答案 1 :(得分:203)

您可以通过直接编辑hostconfig.json文件来更改端口映射 /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

您可以通过docker inspect <container_name>命令以及&#34; Id&#34;的值来确定[hash_of_the_container]。字段是哈希。

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

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

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

答案 2 :(得分:26)

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

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

答案 3 :(得分:16)

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

$ docker run -p <public_port>:<private_port> -d <image>  

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

答案 4 :(得分:13)

在Fujimoto Youichi的例子test01是一个容器,而test02是一个图像。

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

$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01

(使用-P将端口暴露给随机端口而不是手动分配。

答案 5 :(得分:8)

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

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

  1. 如果您之前的容器不在任何已命名的容器中,请创建一个新网络。

    docker network create my_network

  2. 将现有容器加入创建的网络

    docker network connect my_network my_existing_container

  3. 启动反向代理服务(例如nginx),发布您需要的端口,加入同一网络

    docker run -d --name nginx --network my_network -p 9000:9000 nginx

    可选择删除nginx中的 default.conf

    docker exec nginx rm /etc/nginx/conf.d/default.conf

  4. 创建新的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容器。

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

  5. 重新启动nginx

    docker restart nginx

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

    编辑:

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

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

答案 6 :(得分:6)

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

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

docker ps -a

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

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

停止容器:

docker stop <NAME>

更改文件

vi config.v2.json

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

并更改档案

vi hostconfig.json

"PortBindings": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],
     "8888/tcp": [
         {
             "HostIp": "",
             "HostPort": "8888"
         } 
     ]
 }

重新启动您的泊坞窗,它应该可以正常工作。

答案 7 :(得分:6)

要在Windows 10上更改容器的HostPort

# list all containers
$ docker ps -a
$ docker stop docker101tutorial 
# Use grep or rg 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
$ grep -rl --include=config.v2.json fff0a4b22d /var/lib/docker/containers/
/var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/config.v2.json
# edit it
$ vi /var/lib/docker/containers/c1eda20b30f058bce9f8ece3b47a21641df5b399770e12ab57416a954d3c8bbf/hostconfig.json
  • i进入插入模式。
  • "HostPort":"80"更改为"HostPort":"8092"
  • Escape并输入:wq。按Enter
  • 请勿立即启动/停止docker101tutorial。否则,对HostPort的更改将被还原。
  • 右键单击Docker Desktop托盘图标,然后单击重新启动。
  • 在Docker Desktop的容器列表中,查看您的容器。显示的端口应更改为8092
  • 启动容器。现在,它将映射到主机上的端口8092

基于@holdfenytolvaj答案。

答案 8 :(得分:4)

我们使用诸如ssh之类的方便工具来轻松完成此操作。

我正在使用ubuntu主机和基于ubuntu的docker映像。

  1. 在docker内部,已安装openssh-client。
  2. 外部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" "在主机上)。

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

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

我已经用netcat测试过了。

答案 9 :(得分:2)

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

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}

这只是一个不适合我的方案的推荐方法,因为我无法阻止容器,我希望也会帮助你。

答案 10 :(得分:2)

  1. 停止docker引擎和该容器。
  2. 转到/var/lib/docker/containers/${container_id}目录并编辑hostconfig.json
  3. 编辑PortBindings.HostPort您要进行的更改。
  4. 启动docker引擎和容器。

答案 11 :(得分:0)

作为response@Fujimoto-Youichi的补充

在创建容器时,您也可以使用$ docker run -P CONTAINER随机映射端口,但要注意安全性!

  

-P--publish-all的等效项:“它将所有公开的端口发布到随机端口”,

然后运行docker inspect CONTAINER来查找端口映射,如下图所示:

docker inspect for a rabbitmq container show all ports mapping

docker run中了解有关docker run -P的更多信息

答案 12 :(得分:0)

简短的回答:您无法将端口映射分配给现有的Docker容器

答案 13 :(得分:0)

我正在开发一个 dockerizer go 包,用于在 docker 容器中部署批处理应用程序。我的包包含一个 MessageBroker 组件,该组件具有 3 个要发布的端口:jobAgentPort、backendPort、frontendPort。

我将长话短说,建议最好设计一个嵌入到服务器/代理/代理中的 endpointProvider 组件。

也就是说,容器部署至少是一个 2 步过程。

  1. endpointProvider 组件通过 jobId 或类似键创建并缓存在相关包中。
  2. 服务器/代理/代理内置于二进制文件中,您的代码在其中接受由 endpointProvider 输出的 endpointConfig 组件。

例如 server/proxy/broker 构造函数有一个签名: NewMessageBroker(epc *EndpointConfig) *MessageBroker。然后,使用 docker-client api 创建容器映像,最后启动容器 (docker run) 并使用暴露端口值的 endpointConfig 发布端口。

答案 14 :(得分:-2)

"docker run -p 8761:8761 --name ."

答案 15 :(得分:-3)

<块引用>

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

非常简单。有两件事,一是您机器上的本地服务器端口,如 800,8080 等,第二个是您要映射的容器端口。 Docker Port mapping

 docker run -p 8080:8080 <Image ID> 

要获取图像 ID,您可以使用

docker ps

答案 16 :(得分:-8)

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

  1. 停止现有容器
      

    sudo docker stop NAME

  2. 现在使用新端口映射重新启动
      

    sudo docker run -d -p 81:80 NAME

  3. 其中:

      

    “ - d”到背景/ deamon the docker

         

    “ - p”启用端口映射

         

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

         

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