容器进阶:网络概述
参考:《每天5分钟玩转Docker容器技术》
容器网络可以分为单个host上的容器网络和跨多个host的网络。
单主机网络
docker安装时会自动在host上创建三个网络,如:
[root@test ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d9cf9b2bd659 bridge bridge local
44689f1ca656 host host local
2d6cf648cb7e none null local
即bridge
、host
、none
三个网络。
none网络
顾名思义,none网络就是什么都没有的网络。挂在这个网络下的容器除了lo
,没有其他任何网卡。容器创建时,可以通过--network none
指定使用none网络。
主要应用场景:一些对安全性要求高且不需要联网的应用,如生产随机密码,放到none网络中避免密码被窃取。
host网络
连接到host网络的容器共享Docker host
的网络栈,容器的网络配置与host完全一样。可以通过--network host
指定使用host网络。
主要应用场景:对网络传输效率有较高要求的应用。
使用host网络,会牺牲一些灵活性,比如要考虑端口冲突问题。
bridge网络
docker安装时会创建一个名为docker0
的Linux bridge,如果不指定--network
,创建的容器默认都会挂到docker0
上。
user-defined网络
除了以上三个自动创建的网络,用户也可以根据业务需要创建user-defined
网络。
容器间通信
容器之间可通过IP
、Docker DNS Server
或joined
容器三种方式通信。
容器与外界连接
容器默认可以访问容器网络以外的网络环境。而外界访问容器则需要通过端口映射。
跨主机容器通信
跨主机网络方案包括:
- docker原生的
overlay
和macvlan
; - 第三种方案:
flannel
、weave
、calico
等;
libnetwork & CNM
libnetwork是docker容器网络库,最核心的内容是其定义的Container Network Model(CNM),这个模型对容器网络进行了抽象,由以下三类组件组成:
- Sandbox:容器的网络栈,包含容器的interface、路由表和DNS设置。
- Endpoint:将Sandbox接入Network。一个Endpoint只能属于一个网络,也只能属于一个Sandbox。
- Network:Network包含一组Endpoint,同一Network的Endpoint可以直接通信。
overlay
Docker overlay网络需要一个key-value
数据库用于保存网络状态信息,包括Network、Endpoint、IP等。
Overlay网络相对要复杂一些,支持底层更灵活的转发。目前包括Flannel、OpenV-Switch、Weave、Calico等一系列方案都能实现用Overlay网络来联通不同节点上的Pod。
macvlan
Macvlan是Linux kernel比较新的特性,允许在主机的一个网络接口上配置多个虚拟的网络接口,这些网络interface有自己独立的MAC地址,也可以配置上IP地址进行通信。Macvlan下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。Macvlan和Bridge比较相似,但因为它省去了Bridge的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,Macvlan自身也完美支持VLAN。
在 Docker 中,macvlan 是众多 Docker 网络模型中的一种,并且是一种跨主机的网络模型,作为一种驱动(driver)启用(-d 参数指定),Docker macvlan 只支持 bridge 模式。
flannel
Flannel由CoreOS公司推出,现在主要面向Kubernetes,为其提供底层的网络虚拟化方案。
Flannel采用了典型的覆盖网络的思路,在每个主机上添加一个隧道端点,所有跨主机的流量会经过隧道端点进行隧道封包(典型为VXLAN协议,Docker Swarm也支持),直接发送到对端。
与传统的基于覆盖网络的网络虚拟化方案类似,这种设计的优势在于有很好的扩展性,只要IP连通的主机即可构成同一个虚拟网络,甚至可以跨数据中心。问题也很明显,一个是隧道协议目前还比较难追踪,另一个是解包和封包处理负载重,如果没有硬件进行处理则往往性能会有损耗。另外,当中间路径存在负载均衡设备时,要避免均衡失效。
weave
Weave Net是由Weave公司开发的面向容器的网络虚拟化方案。解决容器网络跨主机问题的思路主要是打通跨主机容器之间的通信,手段无非是用覆盖网络建立隧道,或者通过更改包头进行转发。
Weave Net的设计比较有意思,在每个主机上添加一个路由器,在混杂模式下使用pcap在网桥上截获网络数据包。如果该数据包是要发送到其他主机上的,则通过UDP进行转发,到目的主机所在的路由器上。目的路由器执行相反的过程利用pcap解析网包再发送给网桥。整个过程模拟了一种隧道方式。
这样设计的好处是可以进行细粒度的管理,整个转发过程很容易追踪;潜在的问题是对管理平面(特别是路由器的自动收敛和学习)要求比较复杂,并且执行pcap过程会比较消耗计算资源。实际部署中要考虑结合软件定义网络和硬件处理等手段来缓解这两个问题。
calico
Calico的设计则更为直接,干脆不支持网络虚拟化,直接采用传统的路由转发机制,也是在每个节点上配置一个vRouter,负责处理跨主机的流量。vRouter之间通过BGP自动学习转发策略。
由于Calico不采用隧道格式,而是依赖于传统的IP转发,这就限制了它的应用场景,无法跨数据中心,无法保障中间路径安全。但反之带来了容易管理、转发性能会好的一些优势。
Calico目前支持VM、Docker、Kubernetes、Openstack等多个项目的容器网络功能。Calico项目目前正在与Flannel项目共同发起Canal项目,整合了两者的优势,项目地址在https://github.com/projectcalico/canal。