浅谈Docker Bridge网络模式
Contents
本文将简单介绍一下Docker的3中网络模式,然后着重介绍bridge模式的数据传输过程,浅谈Docker容器与宿主机 之间,以及与外部世界的数据传输过程。
Docker的3种网络模式
我们知道,当Docker Daemon启动时,会创建3种网络模式供Docker容器使用:bridge, host 和none模式。
可以通过 docker network ls
看到如下结果
|
|
其中none 将容器加入到一个没有网络接口的特殊网络栈,进入使用none网络的容器执行ifconfig
会看到
|
|
而host网络模式会将容器直接加到Docker宿主机的网络栈中,这样会是的数据传输更快速,但同时因为失去了隔离 的网络环境,容器可以直接更改和影响宿主机网络,增添了更过不安全的因素。
而最被广泛应用的就是bridge网络模式了,这也是Docker创建容器的默认网络模式。当运行Docker Daemon后,执行
ifconfig
会发现多出了一个叫docker0的网络接口
|
|
这就是Docker Daemon为容器提供的隔离与宿主机网络栈的网络接口,只能被Docker容器所使用。 下面这张图展示了Docker的3中网络模式。
创建容器时,可以通过--net
来指定容器使用哪种网络,例如docker run -itd --net=host busybox
。
容器与Docker宿主机之间通信
通过bridge桥接模式,实现容器与宿主机间通信的根本在于veth pair技术。 可以再次参照上图。
- 利用veth pair技术在宿主机上创建两个虚拟网络接口,veth0 和 veth1。而veth pair技术的特性可以保证 无论哪个接口接收到网络报文,都会将报文传输给另一方。
- Docker Daemon将vth0添加到docker0网桥上,保证了宿主机的网络报文能够发给veth0,也就是能发给veth1。
- Docker Daemon将veth1添加到容器所属的网络命名空间(namespaces)下,veth1在容器内部看来就是eth0。 一方面,宿主机发给veth0的网络报文能立刻被容器接收到,实现容器如宿主机间的网络连通;另一方面,Docker容器 单独使用veth1,实现容器与宿主机之间,以及容器与容器之间的网络隔离。
外部世界访问Docker容器
利用veth pair技术,实现了容器与宿主机之间的网络通信,但由于docker0与宿主机的eth0并不属于同一网段, 外部世界并不能直接访问Docker容器的内部服务。对此,Docker使用NAT(Network Address Translation) 的方式,将提供内部服务的端口(port0)与宿主机的某个接口(port1)进行绑定,如此一来,外部世界访问Docker容器 内部服务的流程为:
- 外部世界访问宿主机的IP与端口号:host-ip-addr:port1
- 宿主机接收到请求后,由于DNAT规则,会将host-ip-addr:port1替换为docker-container-ip:port0
- 由于能够识别容器IP,宿主机将请求发给veth pair, 容器接收到请求并开始内部服务
这也是为什么当我们想要将容器的服务暴露给外部时,需要使用-P
或者-p host-port:container-port
来绑定映射端口。
例如docker run -d -p 80:5000 training/webapp python app.py
。
Docker容器访问外部世界
Docker容器访问外部世界会用到IP forwarding技术,具体流程为:
- Docker容器向outer-world-ip:port2发起请求,Linux内核会自动为进程分配一个可用端口(port3),如此请求源为 docker-container-ip:port3。
- 请求通过veth pair到达docker0处,docker0网桥开启了IP forwarding功能,将请求发送至宿主机eth0处。
- 宿主机处理请求时,使用SNAT规则,将源地址docker-container-ip:port3替换成了host-ip-addr:port3,并 将报文放给外界。
- 值得注意的是,外部响应请求时,响应报文的目的地IP地址是宿主机地址,而宿主机转发给Docker容器时,并不是用 DNAT规则转换,应为容器绑定的端口是为了提供内部服务的,不能被占用,这里是用iptables的规则实现的,使得宿主机 上发往docker0网桥的报文,如果数据报所处的连接已经建立,则无条件接受,并转至原来的连接上,即回到Docker容器内部。
这就是docker0网络数据传输的简要流程分析,docker0是Docker使用中最基本、最常用的网络模式,了解它的传输过程 对配置更高级的网络环境也有帮助。
参考引用
本文除了引用已经给出的链接外,主要参考了**《Docker源码分析》(孙宏亮著 机械工业出版社)**一书,以及Docker 官方文档 的网络部分。
Author Wenfeng
LastMod 2016-05-20