Docker—网络模式

Docker网络实现原理:linux

Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优点之一是转发效率较高。 Linux 经过在内核中进 行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不须要真正同外部网络设备通讯,速度要快不少;Docker 容器网络利用此技术,它在本地主机和容器内分别建立一个虚拟接口,并让它们彼此连通 (这样的一对接口叫作 veth pair )docker


Docker 建立一个容器的时候,会执行以下操做:缓存

  • 建立一对虚拟接口,分别放到本地主机和新容器中; 服务器

  • 本地主机一端桥接到默认的 docker0 或指定网桥上,并具备一个惟一的名字,如 vethf9; 网络

  • 容器一端放到新容器中,并修更名字做为 eth0,这个接口只在容器的名字空间可见; ide

  • 从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 vethf9。 oop

完成这些以后,容器就可使用 eth0 虚拟网卡来链接其余容器和其余网络url


网络模式须要开启linux系统转发功能,查看linux系统中是否开启转发功能:spa

#sysctl net.ipv4.ip_forwardcode

net.ipv4.ip_forward = 1

设置:sysctl -w  net.ipv4.ip_forward=1


几种网络模式:

  • Nat       --net=bridge (默认的网桥),Docker经过宿主机的网桥(docker0)来连通内部和宿主机的网络,实现了容器与宿主机和外界之间的网络通讯

wKiom1dulh2yrIN2AAGTl56K4HY447.png670825.png

Bridge桥接模式的实现步骤主要以下:
(1)Docker Daemon利用veth pair技术,在宿主机上建立两个虚拟网络接口设备,假设为veth0和veth1。而veth pair技术的特性能够保证不管哪个veth接收到网络报文,都会将报文传输给另外一方。
(2)Docker Daemon将veth0附加到Docker Daemon建立的docker0网桥上。保证宿主机的网络报文能够发往veth0。
(3)Docker Daemon将veth1添加到Docker Container所属的namespace下,并被更名为eth0。如此一来,保证宿主机的网络报文若发往veth0,则当即会被eth0接收,实现宿主机到Docker Container网络的联通性;同时,也保证Docker Container单独使用eth0,实现容器网络环境的隔离性。
同时Docker采用NAT(Network Address Translation,网络地址转换)的方式(可自行查询实现原理),让宿主机之外的世界能够主动将网络报文发送至容器内部。
经过Bridger网桥模式实现:
(1)容器拥有独立、隔离的网络栈
(2)容器和宿主机之外的世界经过NAT创建通讯


  • Host     --net=host (告诉docker不要将容器网络放在隔离的名字容器中,即不要容器化容器内的网络,该模式下的Docker Container和host宿主机共享同一个网络namespace,即container和宿主机同样,使用宿主机的eth0)

wKioL1dulqmTJgLdAAFw8MGrZXo278.png

Docker Container的host网络模式在实现过程当中,因为不须要额外的网桥以及虚拟网卡,故不会涉及docker0以及veth pair。父进程在建立子进程时,若是不使用CLONE_NEWNET这个参数标志,那么建立出的子进程会与父 进程共享同一个网络namespace。Docker就是采用了这个简单的原理,在建立进程启动容器的过程当中,没有传入CLONE_NEWNET参数标 志,实现Docker Container与宿主机共享同一个网络环境,即实现host网络模式。
Docker Container的网络模式中,host模式是bridge桥接模式很好的补充。采用host模式的Docker Container,能够直接使用宿主机的IP地址与外界进行通讯,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可使用宿主机的端口,无需额外进行NAT转换。固然,有这样的方便,确定会损失部分其余的特性,最明显的是Docker Container网络环境隔离性的弱化,即容器再也不拥有隔离、独立的网络栈。另外,使用host模式的Docker Container虽然可让容器内部的服务和传统状况无差异、无改造的使用,可是因为网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将再也不拥有全部的端口资源,缘由是部分端口资源已经被宿主机自己的服务占用,还有部分端口已经用以bridge网络模式容器的端口映射。


  • Other container  --net=container:NAME_or_ID  (让docker将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有本身的文件系统、进程列表和资源限制,但会和已存在的容器共享IP地址和端口等网络资源,二者进程能够直接经过lo 环回接口通讯)

wKiom1dulv7gYHzNAAEMt_iJ7EU066.png

上图右侧的Docker Container即采用了other container网络模式,它能使用的网络环境即为左侧Docker Container brdige桥接模式下的网络
Docker Container的other container网络模式在实现过程当中,不涉及网桥,一样也不须要建立虚拟网卡veth pair。

完成other container网络模式的建立只须要两个步骤:
(1) 查找other container(即须要被共享网络环境的容器)的网络namespace;
(2) 将新建立的Docker Container(也是须要共享其余网络的容器)的namespace,使用other container的namespace
在这种模式下的Docker Container能够经过localhost来访问namespace下的其余容器,传输效率较高。虽然多个容器共享网络环境,可是多个容器造成的总体依然与宿主机以及其余容器造成网络隔离。另外,这种模式还节约了必定数量的网络资源。可是须要注意的是,它并无改善容器与宿主机之外世界通讯的状况。


  • None     --net=none   (让Docker将新容器放到隔离的网络栈中,但不进行网络配置,以后用户能够本身进行配置,容器内部只能使用loopback网络设备,不会再有其余的网络资源)


网络相关的命令:

-b BRIDGE or --bridge=BRIDGE --指定容器挂载的网桥
--bip=CIDR --定制 docker0 的掩码
-H SOCKET... or --host=SOCKET... --Docker 服务端接收命令的通道
--icc=true|false --是否支持容器之间进行通讯
--ip-forward=true|false --容器之间的通讯
--iptables=true|false --禁止 Docker 添加 iptables 规则
--mtu=BYTES --容器网络中的 MTU

下面2个命令选项既能够在启动服务时指定,也能够 Docker 容器启动( docker run )时候指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 docker run 时能够覆盖设置的默认值:
--dns=IP_ADDRESS... --使用指定的DNS服务器
--dns-search=DOMAIN... --指定DNS搜索域

下面这些参数只有在docker run执行时使用,主要针对容器特性:
-h HOSTNAME or --hostname=HOSTNAME --配置容器主机名
--link=CONTAINER_NAME:ALIAS --添加到另外一个容器的链接
--net=bridge|none|container:NAME_or_ID|host --配置容器的桥接模式
-p SPEC or --publish=SPEC --映射容器端口到宿主主机
-P or --publish-all=true|false --映射容器全部端口到宿主主机


上述网络模式理论主要来自连接:

http://www.infoq.com/cn/articles/docker-source-code-analysis-part7

相关文章
相关标签/搜索