一、docker容器的4种网络模式:
1、 bridge模式:使用--net=bridge指定,默认设置
桥接模式,一个主机上的容器是通过本主机的网卡来通讯的,每个容器有独立的IP地址,并且在本机上是可以ping通的。
Docker0网卡相当于一个交换机,相当于是在一台主机上创建一个vlan,一台主机上的所有容器都是通过docker0来通讯的,docker0再与主机网络端口路由连接通讯,通过nat方式访问外网。
网络是单向的,可以从内到外,但外网无法访问容器网络。Ip route.可以采用端口映射的方式访问容器内部网络,之前的版本docker-proxy 进程负责实现端口映射功能(userland-proxy=false选项关闭docker-proxy,因为每个docker-proxy会直接消耗4-10M内存和1个进程),这个过程中并没有用到DNAT,而是完全依靠docker-proxy做的4层代理,这点与现在的k8有些区别,k8s用的ip-table内核转发。
打通多个主机上的容器网络,可以用overlay,在主机物理网络之上做虚拟网络来通讯。
2、 Host模式: 使用--net=host指定
主机模式,容器不产生网卡(但容器内可以看到docker0网卡,这并不是容器的),而是直接用主机的IP地址和网络堆栈来通讯,经常是一个主机上只开一个容器,给予其一个端口使用,它没有网路损耗,网络性能最高。
例:host网络模式的mysql容器,在网络性能上与native mysql没有什么差异
3、 None模式: 使用--net=none指定
jnone模式:不分配不指定网卡,主要为了编程服务,可以用户(程序)通过api的方式生成网卡(也可以分配多个网卡)并实现固定IP这样的特殊功能
4、 Container模式: 使用--net=container:NAME_or_ID指定
用的较少,几个容器共用一个network namespace 虚拟网卡,即共享某个容器的TCP/IP栈,共享一个IP,在一个主机上的多个container可以通讯。
例:docker run --name=mybox -it busybox sh >>>> ip a
Docker run --net=container:mybox it busybox sh >>>> ip a
可以看出两个容器的ip栈是完全一样的。
K8s pod的pause容器与用户的容器之间即采用了container网络模式,共享pause的ip地址。
二、docker容器互联的网络方案:
Overlay网络的3种主流报文封包协议,GRE隧道(微软级的协议)、vxlan(标准化的网络厂商级的协议,有硬件支持)、自定义封包隧道,现在更倾向于vxlan,其可以理解为2层交换,虚拟化的网,把容器的IP地址加进来,范围更大一些。Docker使用vxlan封包实现overlay网络。
1 、 coreos做的flannel网络(比较早的)
特点:没有复杂的配置,是自动完成路由(两台主机相当于是两个路由器,路由交换模式实现网络相通)的方式,报文的封装是自动完成的,用的是udp的方式。各容器IP地址不能是重复的。Vxlan是比较标准的方式。
2、 三层路由模式
把每个容器的主机都当成一个路由器,这台主机去分发容器的报文,不需要改变容器的报文,容器网络报文直接直传,不用做封装,可以提升性能。需要开启linux的ipforward的路由转发功能
echo “1” > /proc/sys/net/ipv4/ip_forward
IPVlan三层路由模式,是用容器的IP地址作为转发,是路由模式,需要在路由器上配置路由。需要LINUX kerner 3.19以上版本。K8S也可以使用。
calico的三层路由网络模式,报文通过物理网络走,用BGp网络协议(属于边界网关协议),可以做大规模的容器网络
3、 layer 二层网络模式
Macvlan模式,需要linux内核支持,需要v3.9以上的版本,它是由mac地址对应vlan的,利用mac地址做二层交换。K8s也可以使用
三、 Docker网络插件规范:
Docker如何统一纳入各种容器网络方案呢,运用标准的网络插件规范。容器网络插件的两种标准规范。
1、 Docker的cnm规范
2、 OCI 的 cni规范
接口层很简单,CNI插件是一个可执行文件,配置好容器网络后,给容器返回IP路由等信息,容器内部就可以用ip地址路由通讯。现在一般用CNI规范,docker容器不可能只有一个网卡,可能有多个网卡,可以动态编程方式增删,利用CNI规范。