容器网络演化
容器网络的发展与演讲
容器技术很火,经常为人所提及,尤其是开源容器工具 Docker,已在不少数据中心里有广泛应用。容器主要是对软件和其依赖环境的标准化打包,将应用之间相互隔离,并能运行在很多主流操作系统上。这样看来容器和虚拟机技术很类似,容器是 APP 层面的隔离,而虚拟化是物理资源层面的隔离,容器解决了虚拟技术的不少痛点问题,很多时候容器可以和虚拟机结合在一起使用,这也是目前数据中心主流的做法。
除了容器网络安全,如何更好的链接不同 Kubernetes 集群孤岛,如何链接异构容器云平台,这些都是一系列的网络问题需要考虑。容器网络技术也在持续演进,从 Docker 本身的动态端口映射网络模型,到 CNCF 的 CNI 容器网络接口到 Service Mesh+CNI 层次化 SDN。
端口映射
Bridge 模式
Bridge 模式,即 Linux 的网桥模式,Docker 在安装完成后,便会在系统上默认创建一个 Linux 网桥,名称为 docker0 并为其分配一个子网,针对有 Docker 创建的每一个容器,均为其创建一个虚拟的以太网设备(veth peer)。其中一端关联到网桥上,另一端映射到容器类的网络空间中。然后从这个虚拟网段中分配一个 IP 地址给这个接口。其网络模型如下:
Host 模式
Host 模式,即共用主机的网络,它的网络命名空间和主机是同一个,使用宿主机 Namespace、IP 和端口。
Container 模式
Container 模式,使用已经存在容器的网络的 Namespace,相当于多个容器使用同一个网络协议栈,Kubernetes 中的 Pod 中多个容器之间的网络和存储的贡献就是使用这种模式。
None 模式
None 模式,在容器创建时,不指定任何网络模式。由用户自己在适当的时候去指定。
容器网络接口
CNI(Container Network Interface)是 Google 和 CoreOS 主导制定的容器网络标准,它是在 RKT 网络提议 的基础上发展起来的,综合考虑了灵活性、扩展性、IP 分配、多网卡等因素。CNI 旨在为容器平台提供网络的标准化。不同的容器平台(比如目前的 Kubernetes、Mesos 和 RKT)能够通过相同的接口调用不同的网络组件。简单来说,容器 runtime 为容器提供 network namespace,网络插件负责将 network interface 插入该 network namespace 中并且在宿主机做一些必要的配置,最后对 namespace 中的 interface 进行 IP 和路由的配置。
这个协议连接了两个组件:容器管理系统和网络插件,具体的事情都是插件来实现的,包括:创建容器网络空间(network namespace)、把网络接口(interface)放到对应的网络空间、给网络接口分配 IP 等。目前采用 CNI 提供的方案一般分为两种,隧道方案和路由方案。
Callico
Callico 容器网络和其他虚拟网络最大的不同是,它没有采用 Overlay 网络做报文转发,提供了纯三层网络模型。三层通信模型表示每个容器都通过 IP 直接通信,要想路由工作能够正常,每个容器所在的主机节点必须有某种方法知道整个集群的路由信息,Callico 采用 BGP 路由协议,使得全网所有的 Node 和网络设备都记录到全网路由,然而这种方式会产生很多的无效路由,对网络设备路由规格要求较大,整网不能有路由规格低的设备。另外,Callico 实现了从源容器经过源宿主机,经过数据中心路由,然后到达目的宿主机,最后分配到目的容器,整个过程中始终都是根据 BGP 协议进行路由转发,并没有进行封包,解包过程,这样转发效率就会快得多,这是 Callico 容器网络的技术优势。
Flannel
Flannel 是 CoreOS 提出用于解决容器集群跨主机通讯的网络解决方案。Flannel 实质上是一种覆盖网络 Overlay network,也就是将 TCP 数据包装在另一种网络包里面进行路由转发和通信,目前已支持 UDP、VXLAN、AWS VPC、GCE 路由等数据转发方式,其中以 VXLAN 技术最为流行,很多数据中心在考虑引入容器时,也考虑将网络切换到 Flannel 的 VXLAN 网络中来。Flannel 为每个主机分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可在主机间路由,容器间无需 NAT 和端口映射就可以跨主机通讯。Flannel 让集群中不同节点主机创建容器时都具有全集群唯一虚拟 IP 地址,并连通主机节点网络。
Flannel 可为集群中所有节点重新规划 IP 地址使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且“不重复的”的 IP 地址,让不同节点上的容器能够直接通过内网 IP 通信,网络封装部分对容器是不可见的。源主机服务将原本数据内容 UDP 封装后根据自己的路由表投递给目的节点,数据到达以后被解包,然后直接进入目的节点虚拟网卡,然后直接达到目的主机容器虚拟网卡,实现网络通信目的。Flannel 虽然对网络要求较高,要引入封装技术,转发效率也受到影响,但是却可以平滑过渡到 SDN 网络,VXLAN 技术可以和 SDN 很好地结合起来,值得整个网络实现自动化部署,智能化运维和管理,较适合于新建数据中心网络部署。
Weave
Weave 实质上也是覆盖网络,Weave 可以把不同主机上容器互相连接的网络虚拟成一个类似于本地网络的网络,不同主机之间都使用自己的私有 IP 地址,当容器分布在多个不同的主机上时,通过 Weave 可以简化这些容器之间的通信。Weave 网络中的容器使用标准的端口提供服务(如 MySQL 默认使用 3306),管理微服务是十分直接简单的。每个容器都可以通过域名来与另外的容器通信,也可以直接通信而无需使用 NAT,也不需要使用端口映射或者复杂的联接。部署 Weave 容器网络最大的好处是无需修改你的应用代码。
Weave 通过在容器集群的每个主机上启动虚拟路由器,将主机作为路由器,形成互联互通的网络拓扑,在此基础上,实现容器的跨主机通信。要部署 Weave 需要确保主机 Linux 内核版本在 3.8 以上,Docker 1.10 以上,主机间访问如果有防火墙,则防火墙必须彼此放行 TCP 6783 和 UDP 6783/6784 这些端口号,这些是 Weave 控制和数据端口,主机名不能相同,Weave 要通过主机名识别子网。Weave 网络类似于主机 Overlay 技术,直接在主机上进行报文流量的封装,从而实现主机到主机的跨 Underlay 三层网络的互访,这是和 Flannel 网络的最大区别,Flannel 是一种网络 Overlay 方案。
Macvlan 网络方案
Macvlan 是 Linux kernel 比较新的特性,允许在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface 有自己独立的 MAC 地址,也可以配置上 IP 地址进行通信。Macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。Macvlan 和 Bridge 比较相似,但因为它省去了 Bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,Macvlan 自身也完美支持 VLAN。
不同的容器网络方案,适用于不同的应用场景,就看企业如何选择了,从难易度上来讲,Callico 最简单,其次 Flannel,Weave 最复杂,从网络技术来看,Weave 和 Flannel 都是网络封装技术,区别在于封装的位置在网络设备上还是主机上。
服务网格 CNI
服务网格是当下的一个热点,业界有些声音说服务网格是下一代 SDN,但是 Service Mesh 并不能替代 CNI,与 CNI 一起提供层次化微服务应用所需要的网络服务。
CNI 需要交付给容器云 L2-4 层细化至微服务内部的每个 Pod 容器应用终端交付所需要的 L2 网络连接,L3 路由,L2-4 层安全隔离,容器云整体安全,负载均衡,etc……虽然现有的 CNI 仅提供非常有限的功能,此部分可通过后边介绍的 NSX Datacenter 完整交付。
Service Mesh 更多的致力于微服务应用层面的服务治理,致力于 L5-7 层网络服务,服务网格在每一个应用容器前部署一个 Sidecar Envoy 应用代理,提供微服务间的智能路由,分布式负载均衡,流量管理,蓝绿,金丝雀发布,微服务弹性,限流熔断,超时重试,微服务间的可视化,安全等等。但是 Service Mesh 并不会替代 CNI,他们工作在不同的 SDN 层次,CNI 更多工作在 L2-4 层,Mesh 在 5-7 层 application SDN。Mesh 不能独立于 CNI 部署。根据 Gartner 报告指出,在 2020 年,几乎 100%容器云都将内置 Service mesh 技术。而目前开源的 Istio Service Mesh 仅提供单一 Kubernetes 集群内部微服务治理,缺失异构容器云,跨云能力。
从物理机到虚拟机,再到容器,这是服务器虚拟化技术发展的必然趋势,容器解决虚拟机的使用限制,但也将网络引入更复杂的境地,数据中心网络要去适应这种变化,要去适配容器,所以才出现了百花齐放的容器网络方案,这些方案都是为容器而生,从网络层面去适配容器。希望本文能作为一个引子,让业界的同仁能更好在容器化的浪潮下更好的劈波斩浪。