[头脑风暴] 解读Docker Bridge网络模型
背景
这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia
# 不带端口映射启动容器
docker run -it -d luksa/kubia
# 连接到默认的Bridge网桥,容器IP是 172.17.0.2
之后,在宿主机使用容器IP和8080 端口可访问该容器nodejs服务
对此我有几个疑问,这几个疑问在我看来有点与我之前对docker 网络的认知相冲突。
Q1. 不是说如果容器没有端口映射,容器内外隔离吗,怎么在宿主机内使用容器IP还可以访问容器?
Q2. 容器IP:80 访问不到容器内nodejs服务,容器IP:8080可以访问,这个8080从哪里来?
头脑风暴
首先排除一些同事说法:这个容器是以host
网络模型连到宿主机,所以可以在宿主机通过容器IP访问。
- All containers without a --network specified, are attached to the default bridge network.
- In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.
对于问题1,我有个误区:没有端口映射,容器内外网络隔离,宿主机是无法访问容器的。
在网桥上,各个容器有自己的eth0网卡,容器所有的网络请求都通过eth0向外传递。但是为了实现容器之间的通信,容器必须增加一个网络设备veth,并将它们加到宿主机上的docker0网桥之上,实现不同网段数据包的转发功能,进而具备通信能力。
宿主机也在这个网桥上,我们在宿主机使用容器IP访问容器,实际上是走的网桥网络,能直接寻址容器 (不需要映射 端口一说)。
Q3.那端口映射到底起什么作用呢?
网桥模型确保了网桥内容器可相互访问,但除此之外的网络(127.0.0.1/宿主机物理IP 这些均其他网络)均不能访问容器, 这也正是bridge网络隔离的效果。
考虑到外界与与容器通信的情况,我们知道容器只是活在宿主机上的一个进程而已,如何让外界追溯到特定的容器呢?
docker使用的是端口绑定的方式,并将外界的端口流量转发到目的端口,也就是特定的容器之上,这就实现了外界和容器之间的通信
- 绑定宿主机的回环地址127.0.0.1
docker run -it -d -p 127.0.0.1:8080:8080 luksa/kubia
那么在宿主机内只能使用127.0.0.1:8080
可访问容器
- 绑定宿主机的物理地址 10.201.80.126
docker run -it -d -p 10.201.80.126:8080:8080 luksa/kubia
那么在宿主机内可使用物理IP10.201.80.126:8080
访问容器,这样局域网机器就能访问到容器了 3. 不写IP,这样会绑定到0.0.0.0,也就是宿主机所有的网卡。
docker run -it -d -p 8080:8080 luksa/kubia
很显然,宿主机内回环地址和物理地址
均可以访问该容器了。
再回到上面的Q2问题,通过容器IP:8080
访问容器,8080是哪里来的?
8080是容器内nodejs进程的监听端口,我们在构建镜像时本就无所谓使用expose指令
The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published.
所以在docekr ps时候,并不会在PORTS列显示任何内容,但是通过容器IP可直接连通容器内进程监听端口。
为啥访问容器IP:8080 就可以访问容器内nodejs提供的服务?
这是因为容器镜像在构建的时候,一般在0.0.0.0
地址上监听请求,这意味着程序在所有地址的8080端口上监听请求。
这样就延伸出一个有趣的现象,让我们进入容器内部:
docker exec -it 3cc9f428fc25 bash
curl 127.0.0.1:8080
curl 127.0.0.2:8080
curl 127.0.1:8080
curl 172.17.0.2:8080
curl 172.17.2:8080
几个看起来错误的IP竟然也可以访问nodejs服务, 这正是nodejs在http://0.0.0.0:8080
地址监听请求的结果。
# 截取自该镜像构建源码: https://github.com/luksa/kubia-qps/blob/master/kubia-qps/app.js
var www = http.createServer(handler);
www.listen(8080);
# nodejs: server.listen([port[, host[, backlog]]][, callback]) api
If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.
猜想,验证,源码支持,解答了我一开始的几个疑问,对容器Bridge的网络认知进一步加深。
总结输出
- bridge网桥内容器通过容器IP相互访问,外部网络隔离
- docker run -p 参数通过端口映射,让容器内外部网络(宿主机)可以访问容器
- 一般情况下,对外提供web服务的docker镜像会在0.0.0.0 地址上监听请求
- https://en.wikipedia.org/wiki/0.0.0.0
- https://github.com/luksa/kubia-qps/blob/master/kubia-qps/app.js
- https://linuxize.com/post/check-listening-ports-linux/
[头脑风暴] 解读Docker Bridge网络模型的更多相关文章
- Docker bridge探索
作者:ellen.sun链接:http://blog.daocloud.io/docker-bridge/著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 早期的二层网络中,bri ...
- XMind 是一个全功能的思维导图和头脑风暴软件,为激发灵感和创意而生
XMind 是一个全功能的思维导图和头脑风暴软件,为激发灵感和创意而生 https://www.xmind.cn/
- Docker bridge br0 pipework
Docker Centos7 下建立 Docker 桥接网络 - weifengCorp - 博客园https://www.cnblogs.com/weifeng1463/p/7468497.html ...
- 深入解读docker网络与kubernetes网络
前言:你是否学习使用k8s很久很久了可是对于网络这块仍旧似懂非懂呢? 您是否对网上一堆帖子有如下的抱怨: 打开多个博客,然后发现有区别么? 明显是直译过来的,越看越迷糊 “因为xxx,所以yyy”,. ...
- [docker]docker0网络模型探究
docker0网络模型step by step 将docker的ns软链到linux ns $ ln -s /var/run/docker/netns /var/run/netns 查看ns,无 $ ...
- 数人云CTO解读Docker 1.12和金融业容器化
7月29日 数人云 在上海举办金融沙龙,邀请上交所和近二十家来自银行.保险.证券的IT技术专家一同探讨容器技术在金融业中的最佳实践.数人云CTO肖德时在会上将传统金融行业通过容器可以解决的四大问题做了 ...
- Docker bridge、host、container other、overlay 网络模式
docker run创建Docker容器时,可以用--net 选项指定容器的网络模式,Docker有以下5种网络模式: bridge模式:使用–net =bridge指定,默认设置: host模式:使 ...
- 一文解读Docker (转)
最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料.本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学 ...
- Python头脑风暴4
IT是全国平均薪资最高的行业,2017年全国最高,人均13点4万每年. 但技术固然好,创业拼的还是世界观下的创意. 蘑菇街,并夕夕,TikTok,头条,哪个不是创意用IT技术的现实化?? 未来,大平台 ...
随机推荐
- django框架基础-路由系统-长期维护
################## 路由系统介绍 ####################### 路由系统就是路径和函数的对应关系, 路由系统可以看成支撑你这个网站的目录,就像是一本书一样 ...
- 响应式WEB页面开发实践
转自:https://github.com/markyun/My-blog/issues/27 最近得到一个新任务单,让我用一套页面适应所有主流终端(Android.iPhone.iPad.PC),而 ...
- 吴裕雄--天生自然HTML学习笔记:HTML 标题
在 HTML 文档中,标题很重要. HTML 标题 标题(Heading)是通过 <h1> - <h6> 标签进行定义的. <h1> 定义最大的标题. <h6 ...
- Scarpy框架安装教程
在一切之前,建议升级pip,如果版本太低,安装会失败 升级pip命令: python -m pip install --upgrade pip 如果上面的命令不能用,用下面这个 easy_instal ...
- js中的call
//例1 <script> window.color = 'red'; document.color = 'yellow'; var s1 = {color: 'blue' }; func ...
- javascript中的function命名空間與模擬getter、setter
function的命名空間 在javascript中,function也可以擁有自己的命名空間例如以下這段程式碼: 12345678 function () { return 'I am A';} A ...
- SpringBoot 处理 POST Json 传参枚举
在 Spring 框架中对枚举类型的序列化/反序列化是有限制的. 假设如下面这样在某些情况下就不能正常工作: 123456789 public enum PayChannelEnum implemen ...
- 广州CVTE招聘-测试开发工程师
内推邮箱:keweisheng@cvte.com 地点:广州 公司简介 CVTE成立于2005年,总部位于广州科学城,旗下设有多家独立的子公司,在香港设有全球服务中心,在国内设有21个营销服务中心和近 ...
- runR
Linux下使用R 运行linux下的R脚本 编写R文件 新建后缀名为R的文件 写入R程序 在脚本首行加入 1 运行R文件 这里有两种方式 大专栏 runR进入R的环境">进入R的环 ...
- IO和流
I/O和流 I/O是Input和Output的缩写 从读写设备,包括硬盘文件,内存,键盘输入,屏幕输出,网路 输入输出"内容"(字节或文本) 流是对输入输出设备的一种抽象 从流中读 ...