文档章节

Docker启动容器时的port公开方式,破除一些含糊的地方

Q_J
 Q_J
发布于 2016/07/08 13:07
字数 1392
阅读 275
收藏 0

以前就好奇docker run时的port公开方式-p 8080:8080和--expose(或者Dockerfile里的EXPOSE)的区别,

当时相信了stackoverflow上高手的回答Difference between "expose" and "publish" in docker - Stack Overflow,提到

如果什么都不指定,那么除了该容器自己,谁都不能访问那个port。

**后来有一天细看Docker的网络的时候,觉得不应该是这样。**从Docker主机之外的确不能访问,这点没有疑问,可是从Docker主机之内或者其他容器,其实能够访问,而且很合理。

Docker在主机上做了个docker0网卡172.17.0.1。又为每个容器创建了一个vethXxxx网卡。

网卡是有两头的,一头接外边,一头接容器,就像管道。

这个veth网卡,一头给了容器做eth0 172.17.0.N,另一头被默认地被加入到docker0网卡上,相当把所有的容器的网卡都插到一个hub上了,这就是互通的基础。

照这么说,在其中一个容器里侦听eth0的端口,那么主机和其他容器都应该能够访问到才对。


实验环境: Mac OS X EI Capitan 10.11.5

$ docker-machine -v
docker-machine version 0.8.0-rc1, build fffa6c9
$ docker -v
Docker version 1.12.0-rc3, build 91e29e8, experimental

启动一个容器,什么-p -P --expose都不指定。 就用busybox吧,很小。起了以后就是一个bash等在那儿。

$ docker run -it busybox

得到他的ip,一般第一个启动的就是172.17.0.2。

/ # ifconfig eth0 |grep 'inet addr:'
          inet addr:172.17.0.2  ...

在容器里执行一个netcat侦听端口7777。 一旦得到连接就发送date命令的结果给对方。

/ # nc -ll -p 7777 -e date

在别的容器里连接这个端口

$ docker run busybox nc 172.17.0.2 7777
Fri Jul  8 03:50:34 UTC 2016

能通!

在docker主机里连接这个端口

$ docker-machine ssh default nc 172.17.0.2 7777
Fri Jul  8 03:49:40 UTC 2016

自然也能通。

因为不是在Linux主机上,所以这里的docker主机实际值docker-machine这个boot2docker虚拟机。

这个现象应该不是因为实验版本导致的问题,就是这么设计的。

  • 如果什么都不指定,那么从Docker主机以及其他容器,都能访问那个port。

  • 当有时候忘了加-p端口映射选项就启动了容器做了一堆事儿之后,如果立刻想从Docker主机外访问的,可是却舍不得退出容器,那就还有补救机会。

就在Docker主机里用iptables加个端口转发规则,(VirtualBox里也可以加一个端口映射让本地访问):

$ docker ssh default
docker@default:~$ sudo iptables -A PREROUTING -t nat -p tcp --dport 7777 -j DNAT --to 172.17.0.2:7777

或者在真正的Mac OS X上加个路由,允许经Docker主机(一般为192.168.99.100)访问到172.17.0.N

sudo route -n add 172.17.0.0/24 192.168.99.100

  • 而对于-p 7777:7777这样的用法,这是没有疑问的,的确就在Docker主机上被加了个端口转接的rule了,所以和从Docker主机之外能够访问这个端口了。

  • 剩下一个--expose 7777(或者Dockerfile里的EXPOSE 7777),实质没有什么用,也许是给发现服务用的。并没有对iptables做任何改变。

  • 直到-P(--publish-all)时才会被用到--expose里的端口信息。

  • 就是说, 只有既指定--expose 7777(或者Docerfile里的EXPOSE 7777)又指定-P(--publish-all)时,才会有实际动作。但这是把Docker主机上的随机端口映射给容器里的7777,所以一般不用。

例如,先做一个EXPOSE 7777端口的Docker image。

$ cat Dockerfile
FROM busybox
EXPOSE 7777
$ docker build -t busybox_expose_7777 - < Dockerfile
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM busybox
 ---> 2b8fd9751c4c
Step 2 : EXPOSE 7777
 ---> Running in bddf30c42dcd
 ---> 2c92defacdd4
Removing intermediate container bddf30c42dcd
Successfully built 2c92defacdd4

然后运行时加上 --publish-all,

docker run -it --publish-all busybox_expose_7777
/ # nc -ll -p 7777 -e date

这时再看看到底Docker主机的哪个端口被映射到容器里的7777了。

docker ps
...
fca504f3bc49        busybox_expose_7777   "sh"  ... 0.0.0.0:32769->7777/tcp   nostalgic_galileo

就是这个32769端口了。那访问Docker主机的32769端口看看。

(Docker主机的ip一般是192.168.99.100(可以从DOCKER_HOST环境变量里看出来))

$ nc 192.168.99.100 32769
Fri Jul  8 11:14:08 UTC 2016

的确如此。

真真是聊胜于无的东西,难以置信谁会用这个。却搞得不好理解,文档也说的不明不白。


对于新型的,不用VirtualBoxDocker for Mac或者Docker for Windows,会怎么样呢?

结果:在其他容器里也是可以访问别的容器的端口的。在docker主机里就不知道了,因为进不去,不过应该是行的。

这两种都直接利用Mac/Windows自带的虚拟设备API(例如Hypervisor.framework)直接生成一个linux虚拟机作为docker主机,

而且它刻意淡化这个虚拟机的存在,我暂时找不到命令进入这个虚拟机,所以没做完这个实验,不过无所谓了,原理一样,应该是一样的结果。

顺便,这种新型工具,以xhyve虚拟机为基础,非常轻巧好用,连VirtualBox都不用装了,一切和以前一样的用法,除了docker-machine命令不起作用。

具体的可以看zchee/docker-machine-driver-xhyve: Docker Machine driver plugin for xhyve (native OSX hypervisor)

© 著作权归作者所有

Q_J

Q_J

粉丝 12
博文 67
码字总数 54682
作品 0
日本
私信 提问
在不重启动容器的情况下,允许从外部访问到容器内部的端口

目前的docker,还没有实现好热备份,一旦退出容器,即使commit到image里再启动那个image,也只不过省了文件状态恢复的时间,却不会省下db启动时分析巨大的数据文件所需的时间。 所以有必要,在...

Q_J
2016/07/26
41
0
跟我一起学docker(七)--网络

1.容器对外服务 当容器内运行一些网络应用,要让外部访问这些应用时,可以通过 -P 或 -p 参数来指定端口映射。 使用 -P 映射时,Docker会随机映射一个49000 ~49900 的端口至容器内部开放的...

IT人故事
2018/07/04
0
0
docker~大叔对术语的解释

接触和使用docker已经有1年多了,起初对概念本身理解的不是很好,或者说,没有找到一本比较好的书,在自己的研究下,对docker一些基本的概念有了自己的一些认识和看法,现在分享给正在学习d...

mcy247
2017/12/05
0
0
可能是把Docker的概念讲的最清楚的一篇文章

本文只是对Docker的概念做了较为详细的介绍,并不涉及一些像Docker环境的安装以及Docker的一些常见操作和命令。 阅读本文大概需要15分钟,通过阅读本文你将知道一下概念: 容器 什么是Docke...

snailclimb
2018/06/26
0
0
这可能是把Docker的概念讲的最清楚的一篇文章

本文只是对Docker的概念做了较为详细的介绍,并不涉及一些像Docker环境的安装以及Docker的一些常见操作和命令。 阅读本文大概需要15分钟,通过阅读本文你将知道一下概念: 容器 什么是Docke...

java高级架构牛人
2018/06/27
26
0

没有更多内容

加载失败,请刷新页面

加载更多

Dubbo-自适应拓展机制

背景 在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等,这些都是Dubbo的基础组件。这些基础组件的拓展不是在系统框架启动阶段被加载,而是拓展方...

rock-man
17分钟前
4
0
Kali安装fcitx输入法(五笔)

安装fcitx > sudo apt-get install fcitx-rime fcitx-config-gtk3 重启 > sudo reboot fcitx配置 效果就是这样 配置输入法切换 系统设置...

yeahlife
19分钟前
3
0
IE之css3效果兼容

本文转载于:专业的前端网站▷IE之css3效果兼容 一、兼容css阴影效果(ie滤镜) 1.Shadow,阴影 .shadow { -moz-box-shadow: 3px 3px 4px #000; -webkit-box-shadow: 3px 3px 4px #000; box-sha...

前端老手
22分钟前
3
0
NiushopB2C开源商城功能列表说明:

B2C单商户免费版:PC商城+微商城 B2C单商户标准版:PC商城+微商城组合套餐+阶梯优惠核销功能 B2C单商户企业版:PC商城+微商城拼团+组合套餐阶梯优惠+核销功能 B2C单商户分销版:PC商城+微商城...

niushop-芳
24分钟前
3
0
图片如何转GIF图片呢

如何将生活中拍摄的好玩有趣的图片制作成GIF动图呢?相信很多小伙伴都不知道要如何制作,其实制作方法非常的简单,下面分享一个图片转GIF动图的方法,希望这个方法能够帮助大家在与好友斗图时...

白米稀饭2019
30分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部