返回 登录
0

夜来Docker声 新型容器网络方案知多少

自从Docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求。容器网络从早期只是主机内部的网络,现已迅速发展成跨主机的网络,即新型容器网络。本文将重点介绍几种新型容器网络及其典型代表。
Docker容器固有4种网络模式:
早期的容器网络,就是主机内部的网络,想要把服务暴露出去需要通过iptables做端口映射。下面简单介绍一下docker原生的几种网络模式以及如何通过这几种模式实现容器之间的互联。
1. Bridge模式
Bridge模式,顾名思义就是Linux的网桥模式,网桥类似于物理交换机的功能,docker在安装完成后,便会在系统上默认创建一个Linux网桥, 名称为docker0 并为其分配一个子网,默认为172.17.0.0/16,针对有docker创建的每一个容器,均为其创建一个虚拟的以太网设备(veth peer)。其中一端关联到网桥上,另一端映射到容器类的网络空间中。然后从这个虚拟网段中分配一个IP地址给这个接口。 其网络模型如下:
图片描述
跨主机访问示意:
图片描述

2.HOST模式
Host模式顾名思义就是共用主机的网络,它的网络命名空间和主机是同一个,使用宿主机Namespace、IP和端口。

3.Container模式
使用已经存在容器的网络的Namespace,相当于多个容器使用同一个网络协议栈,k8s中的pod中多个容器之间的网络和存储的贡献就是使用这种模式。

4.None模式
在容器创建时,不指定任何网络模式。由用户自己在适当的时候去指定。下面我们就手动使用none模式来实现两个容器之间的互通。

为了和之前的docker0网桥不冲突 先创建一个网段
docker network create –driver=bridge –subnet=10.168.0.1/24 example
查看Linux的网络信息会发现有一个名叫example的网桥
brctl show
创建一个容器 使用none模式的网络
docker run –net=none –idt alpine:3.4 sh test1
查看此时的容器的pid
pid = docker inspect –f ‘{{.State.Pid}}’
在主机上来看 容器就是一个进程,进程id就是刚才通过docker inspect获取到的
连接test1的命名空间 方面操作
ln –s /proc/pid/ns/net/var/run/netns/pid
列出所有的网络命名空间
ip netns list
现在我们创建一个veth peer 可以把veth对理解成一个网线的两头,数据从一个数据流入,必然从另一个数据流出。如果我们把veth的一头“插入”test1这个容器的命名空间中,另一台接在网桥上是不是就可以实现容器想通呢,答案是肯定的。
创建veth peer
ip link add vethhost-1 type veth peer name vethcontainer-1
ip link set vethhost-1 up
ip link set vethcontainer-1 up
将vethcontainer-1放入test1这个空间中
ip link set vethcontainer-1netns pidipipnetnsexecpid ip addr 10.168.0.2/24 dev vethcontainer-1
将veth peer的另一端接入网桥
brctl addif example vethhost-1
按着上述方法再次创建一个容器,分配一个不同的地址便可以实现容器之间的访问。

通过对docker固有的网络模型介绍可以看出,docker本身的网络功能还不是特别的完善,对于容器间跨主机通信,网络隔离等功能均不能很好的实现。
无论是之前的虚拟技术,还是现在的容器化技术,网络一直都是一个比较复杂难以解决的问题,docker官方也意识到这个问题的存在,所以在推出自己方案的同时,积极拥抱第三方解决方案。

新型容器网络方案及典型代表
新型容器网络指跨主机的网络,分为两大类——隧道方案和路由方案。 Overlay,OVS,Flannel和Weave网络方案都是隧道方案的典型,路由方案典型代表包括Calico和Macvlan。

一个简单的各种方案对比图
图片描述

一、隧道方案
隧道方案对底层的网络没有过高的要求,一般来说,只要是在一个三层可达网络里,就能构建出一个基于隧道的容器网络。问题也很明显,随着节点规模的增长复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下这是需要考虑的一个点。

典型代表:
1)Weave:UDP广播,本机建立新的BR,通过PCAP互通。
2)Open vSwitch(OVS):基于VxLAN和GRE协议
3)Flannel:UDP广播、VxLan。
4)Overlay: docker 官方开发,v1.9后推出

1、Weave网络方案
Weave容器网络由Zett.io公司开发,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器。外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。
图片描述
Weave容器网络运行原理

Weave容器网络具有以下特性:
1)Weave网络中不同主机上的Docker可以彼此通信。除此之外,Dockers可以通过Weave DNS发现模块实现的主机名发现彼此。
2)Weave可以穿越防火墙并在部分连接的网络中操作。同时weave支持流量加密,允许主机通过不可信网络彼此连接。
3)与其他解决方案不同,Weave不依赖分布式存储(例如etcd和consul)来交换路由信息,而是自己构建路由网络,并且当新对等体添加和退出时实现谣言协议以交换网络拓扑。

2、OVS网络方案
Open vSwitch是一个由Nicira Networks主导的开源项目,通过运行在虚拟化平台上的虚拟交换机,为本台物理机上的容器或者虚拟机提供二层网络接入。Open vSwitch的目标,是做一个具有产品级质量的多层虚拟交换机。通过可编程扩展,可以实现大规模网络的自动化(配置、管理、维护)。
图片描述

图片描述

OVS容器网络具有以下特点:
1)通过open vswitch模拟一个交换机;
2)非常适合虚机环境;
3)可以直接和SDN集成;
4)不改变现有物理拓扑;
5)封包解包消耗内存;
6)使用了隧道技术,增加运维难度。
7) ovs 在创建点对点的GRE通道需要手动创建

3、Flannel网络方案
Flannel容器网络,是由CoreOS主导的解决方案。Flannel为每一个主机的Docker daemon分配一个IP段,通过etcd维护一个跨主机的路由表,容器之间IP是可以互相连通的,当两个跨主机的容器要通信的时候。会在主机上修改数据包的header,修改目的地址和源地址,经过路由表发送到目标主机后解包。封包的方式,可以支持udp、vxlan、host-gw等,但是如果一个容器要暴露服务,还是需要映射IP到主机侧的。

图片描述

Flannel容器网络具有以下特性:
1)对Mesos框架支持不好;
2)每台主机一个CIDR,三层互通,CIDR不灵活会造成大量IP浪费;
3)主机间有多种封包方式,udp、vxlan、host-gw等;
4)容器间IP联通但对外服务需要映射到主机IP和端口;
5)主机IP网段固定,无法实现容器IP在不同主机间迁移。

4、Overlay网络方案
Overlay网络,指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发,而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制,支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
图片描述

Overlay容器网络具有以下特性:
1)需要升级Docker1.9以上(overlay是docker 1.9版本才加入的特性);
2)不改变现在物理网络拓扑;
3)灵活性高,性能损耗高(至少30%以上);
4)封包解包消耗内存;
5)使用了隧道技术,增加运维难度。

二、路由方案
路由技术从三层或者两层实现跨主机容器互通,没有NAT,效率比较高,和目前的网络能够融合在一起,每一个容器都可以像虚拟机一样分配一个业务的IP。如果几万新的容器IP冲击到路由表里,导致下层的物理设备没办法承受;而且每一个容器都分配一个业务IP,业务IP消耗会很快。

典型代表:
1)Calico:基于BGP协议的路由方案,支持很细致的ACL控制。
2)Macvlan:从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现

1、Calico网络方案
Calico容器网络基于BGP协议,完全通过三层路由实现。由linux主机内核维护路由表,通过路由转发实现容器间通信,这种实现方式没有封包解包操作,所以性能损耗非常小,从技术上来看是一种很优越的方案。
图片描述
Felix,calico agent,在每台需要运行workload的节点上,主要负责配置路由及ACLs等信息来确保endpoint的连通状态;
Etcd,分布式键值存储,主要负责网络元数据一致性,确保calico网络状态的准确性;
BGP client,主要是负责felix写入kernel的路由信息分发到当前calico网络,确保workload间的通信的有效性;
BGP Route Reflector,大规模部署时使用,摒弃所有节点互联的mesh模式;通过一个或者多个BGP Route Reflector来完成集中式的路由分发。

Calico容器网络具有以下特性:
1)需要路由器开启BGP协议支持;
2)纯粹的三层实现;
3)扩展性非常好,没有隧道技术,性能损耗非常小;
4)外界可以直接通过路由访问IP,也可以主机上做端口映射;
5)随着容器数量增加,Linux的iptable表数量会很大,可能会对机器性能有影响
6) 需要开启BGP协议,对于网络改动比较大,如果不想改动网络,也可以尝试其ipip方式。

2、Macvlan 网络方案
Macvlan 是 linux kernel 比较新的特性,允许在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface 有自己独立的 mac 地址,也可以配置上 ip 地址进行通信。macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。macvlan 和 bridge 比较相似,但因为它省去了 bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,macvlan 自身也完美支持 VLAN。

Macvlan的几种支持的模式
1)private mode:过滤掉所有来自其他 macvlan 接口的报文,因此不同 macvlan 接口之间无法互相通信;
2)vepa(Virtual Ethernet Port Aggregator) mode: 需要主接口连接的交换机支持 VEPA/802.1Qbg 特性。所有发送出去的报文都会经过交换机,交换机作为再发送到对应的目标地址(即使目标地址就是主机上的其他 macvlan 接口),也就是 hairpin mode 模式,这个模式用在交互机上需要做过滤、统计等功能的场景;
3)bridge mode:通过虚拟的交换机将主接口的所有 macvlan 接口连接在一起,这样的话,不同 macvlan 接口之间能够直接通信,不需要将报文发送到主机之外。这个模式下,主机外是看不到主机上 macvlan interface 之间通信的报文的。
Docker在1.12之后增加了macvlan的网络模式, 目前此模式还在试验阶段,也仅仅支持macvlan的桥接模式。其拓扑图如下:
图片描述

Macvlan容器网络具有以下特性:
Macvlan 将所有的容器连接在二层网络上,所有的容器相当于在一个交换机上连接,没有封包解包,甚至没有nat表转换,理论上来说应该是所有网络方案中,性能损失最小的一个。
但是macvlan在docker中目前只在试验阶段,网络隔离也很简单,一个docker主机只能创建一个macvlan网络,导致所有的应用只能在一个网段中,这一点来看还不能满足多租户的网络使用。 当大量的容器连接到交换机时,可能会产生ARP风暴。

通过上面的介绍及对比,天玑总结了以下几点:
1)Overlay等依赖隧道技术的解决方案对信息损失会比较大
2)使用BGP对现有网络改动大,但性能损耗比较小。基于Linux的iptable表对网络访问控制策略很丰富。
3)使用macvlan的方式网络性能最好,但是网络隔离暂时不能很好的支持。

欢迎容器圈内人士补充!

评论