为docker容器暴露端口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为docker容器暴露端口相关的知识,希望对你有一定的参考价值。

参考技术A

获得容器IP
//[container_name]为docker容器名称

iptable转发端口
//例:将容器的8000端口映射到宿主机的8001端口

docker commit -a "shijie32177" -m "centos with redis cluster" centos-redis centos-redis:v1
返回
sha256:c044f4f28a4805823dc30605df2b0d15e06ab00ba122db5d00db434266adbd80

docker run -d -p 1001:7001 -p 1002:7002 -p 1003:7003 -p 1004:7004 -p 1005:7005 -p 1006:7006 shijie32177/centos-redis
返回
b4a4c6d6cc688407aa4c102fc459875bc8e3bacdc4b2b1504daebccab522ea1d

如何在没有端口映射的情况下将 docker 容器的 ip 和端口暴露给外部 docker 主机?

【中文标题】如何在没有端口映射的情况下将 docker 容器的 ip 和端口暴露给外部 docker 主机?【英文标题】:How to expose docker container's ip and port to outside docker host without port mapping? 【发布时间】:2014-09-22 02:22:52 【问题描述】:

当我在一个 docker 主机上为同一个 web 图像启动两个 docker 容器时。

两个docker容器在同一个端口上监听5000 两个容器的5000端口被映射到docker主机的不同端口:49155,49156 要从外部docker主机访问两个容器需要通过访问docker主机ip和端口4915549156

有没有解决方案可以通过 docker 主机的 ip 和端口x.x.x.x:5000 从外部 docker 主机访问 docker 容器,而无需端口映射?

不同dock主机上的所有docker容器可以直接相互访问。

【问题讨论】:

问题不清楚。 docker 容器是否与主机“位于”同一网络适配器上?在这种情况下,请使用--net=host。还是要绑定端口不随机? 【参考方案1】:

您可以通过主机上的 IP 别名来完成此操作。

首先,在主机上添加一个与主接口具有不同 IP 地址的虚拟接口。我们将使用 IP 10.0.0.10 调用主接口 eth0,使用 IP 地址 10.0.0.11 调用虚拟接口 eth0:1

 ifconfig eth0:1 10.0.0.11 netmask 255.255.255.0 up 

现在运行容器并将端口 5000 映射到相应的接口。例如:

docker run -p 10.0.0.10:5000:5000 -name container1 <someimage> <somecommand>
docker run -p 10.0.0.11:5000:5000 -name container2 <someimage> <somecommand>

现在您可以在外部使用不同的 IP 地址访问端口 5000 上的每个容器。

【讨论】:

我正在使用 boot2docker,我在 (boot2docker) mac 上看不到 eth0:1 可用,还有什么进一步的步骤让它在 mac 上运行? 试试这个sudo ifconfig en1 inet w.x.y.z netmask 255.255.255.0 alias,其中en1是您要为其添加别名的接口。 我试过了,但它抱怨“来自守护进程的错误响应:无法启动容器 XXXXX:启动用户级代理时出错:监听 tcp 172.16.1.99:80:绑定:无法分配请求的地址”,有什么线索吗? 【参考方案2】:

创建 VM 时,请确保在网络下选择以下选项

Attached to:        Bridged NetworkManager
Adapter Type:       PCnet-Fast III (Am 79C973)
Promiscious Mode    Allow All

RHEL 6.5 / Fedora 20

Install docker, libvrt

确保使用 root 完成以下操作

# chkconfig NetworkManager off
# chkconfig network on  
# service NetworkManager stop
# service network start

/etc/sysconfig/network-scripts 中创建文件 ifcfg-xxxxx

DEVICE=xxxxx
TYPE=Bridge
BOOTPROTO=dhcp
ONBOOT=yes
DELAY=0

并在文件末尾追加ifcfg-p2p1/ifcfg-eth0BRIDGE=xxxx

重启虚拟机

运行

brctl show 

确保桥接连接有一个适配器p2p1eth0 例如

# brctl show
bridge name     bridge id               STP enabled     interfaces
gsbr01          8000.080027595649       no              eth0
virbr0          8000.5254004c1564       yes             virbr0-nic

现在在启动 docker 之前,我们必须使用我们的网桥而不是 docker0 来执行此操作,以 docker -d -b=gsbr01 运行 docker

$ echo 'DOCKER_OPTS="-b=gsbr01"' >> /etc/sysconfig/docker
$ sudo service docker start

检查结果:

# brctl show
bridge name     bridge id               STP enabled     interfaces
gsbr01          8000.080027595649       no              eth0
                                                        veth5806f27
                                                        vethb3e33da
virbr0          8000.5254004c1564       yes             virbr0-nic

docker -d -b=gsbr01

【讨论】:

以上是关于为docker容器暴露端口的主要内容,如果未能解决你的问题,请参考以下文章

运行 apache 的 Docker 容器总是暴露端口 80

Docker 和 netstat:netstat 不显示端口,由 docker 容器暴露

Postgres 9.1 的 Docker 容器未将端口 5432 暴露给主机

似乎无法将 docker 容器端口暴露给主机

Gitlab CI runner 无法暴露嵌套 Docker 容器的端口

无法通过容器的 ip 和通过 http 暴露的端口访问 Docker 容器中的 Web 应用程序