一、kubernetes的网络模式
(1)Kubernetes网络需要解决的问题
集群内:
容器与容器之间的通信
Pod和Pod之间的通信
Pod和服务之间的通信
集群外:
外部应用与服务之间的通信
(2)同一pod之间的通信
因为pod内部的容器是共享网络空间的,所以同一pod内的容器直接可以使用localhost访问其他容器。
k8s在启动容器的时候会先启动一个Pause容器,为Pod指派一个唯一的IP地址,
每个Pod里运行着一个Pause容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中。
(3)不同Pod中容器之间的通信
对于此场景,情况相对比较复杂一些,这就需要解决Pod间的通信问题。在Kubernetes通过flannel、calic等网络插件解决Pod间的通信问题。本文以flannel为例说明在Kubernetes中网络模型,flannel是kubernetes默认提供网络插件。
Flannel是由CoreOs团队开发社交的网络工具,CoreOS团队采用L3 Overlay模式设计flannel, 规定宿主机下各个Pod属于同一个子网,不同宿主机下的Pod属于不同的子网。
flannel会在每一个宿主机上运行名为flanneld代理,其负责为宿主机预先分配一个子网,并为Pod分配IP地址。Flannel使用Kubernetes或etcd来存储网络配置、分配的子网和主机公共IP等信息。数据包则通过VXLAN、UDP或host-gw这些类型的后端机制进行转发。
二、flannel
(1)Backend
Flannel支持几种不同的方式,把它们叫做Backend;
a、vxlan
最推荐使用的是vxlan,使用linux kernel的vxlan实现。vxlan backend的配置项有以下几个:
-
- Type: string,backend类型,就是"vxlan"
- VNI: number,vxlan协议中的vni编号,不同的vni号码代表不同网段,类似vlan号,默认是1
- Port: number, 宿主机的udp端口,用来发送封装后的报文,使用linux内核默认配置,8472
- GBP: boolean,是否使用vxlan Group Policy,默认false
- DirectRouting: boolean,是否启用直接路由,当两台宿主机位于同一个网段时,不封装通过路由直接送达,默认false
b、host-gw
host-gw的方式,通过直接路由的方式传送虚拟网络报文。这种方式要求所有宿主机是二层直达的(中间不经过路由),原理和vxlan中的DirectRouting相同。
Vxlan DriectRouting是能够直接路由的时候采用直接路由的方式,否则就通过vxlan,DriectRouting可以跨网段。
Host-gw要求所有宿主机都支持直接路由方式(在同一个二层网络中),并全部采用直接路由的方式,host-gw不能跨网段。
host-gw的配置项只有一个:
-
- Type: string,backend类型,就是"host-gw"
c、UDP
udp只建议调试时使用,或者另外两种方式不能使用的时候(譬如宿主机内核不支持vxlan)使用。
配置项:
-
- Type:string,backend类型,就是"udp"
- Port: number,宿主机udp端口,默认8285
(2)查看flannel的配置
a、集群中每个节点上都有flannel
[root@master ~]# kubectl get pods -n kube-system -o wide |grep flannel
b、查看flannel的configmap配置
[root@master ~]# kubectl get configmap -n kube-system |grep flannel
[root@master ~]# kubectl get configmap kube-flannel-cfg -o json -n kube-system #查看json配置文件
(3)flannel的配置参数
a、
Network: flannel使用的CIDR格式的网络地址,用于为pod配置网络功能;
10.244.0.0/16 ->
master:10.244.0.0/24
node01:10.244.1.0/24
......
node255:10.244.255.0/24
b、
SubnetLen:把Network切分子网供各节点使用时,使用多长的掩码进行切分,默认为24位;
SubnetMin:用于分配给节点使用的子网起始子网地址;如:10.244.10.0/24
SubnetMax:用于分配给节点使用的子网结束子网地址;如:10.244.100.0/24
Backend:各pod间通信的方式;vxlan,host-gw,udp
(4)把flannel的网络配置改成DirectRouting的通信方式
其实关于flannel的配置,部署集群的时候,就应该配置好;
a、直接获取部署k8s集群时,用的flannel的yaml文件,然后修改,再应用一下;
GitHub地址:https://github.com/coreos/flannel#flannel
找到此段落,注意!不能用这个URL直接获取yaml文件,要先选中,然后右键打开,再复制浏览器地址栏里的URL;
地址栏中的地址,如图所示:
[root@master manifests]# pwd
/root/manifests
[root@master manifests]# mkdir flannel
[root@master manifests]# cd flannel/
[root@master flannel]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
[root@master flannel]# vim kube-flannel.yml #编辑此文件,修改为如图:
此时我们用的是vxlan的Directrouting方式,其他方式同理,修改此yaml文件即可;
b、删除flannel,再重新apply,生产环境不能这样做,会导致整个集群不能工作;
[root@master flannel]# kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
稍等片刻,查看发现已经没有flannel了:
c、此时,用刚才修改过的本地yaml文件,重新apply
[root@master flannel]# kubectl apply -f kube-flannel.yml
查看:
d、此时创建几个pod,再抓包,
创建pod:
[root@master manifests]# kubectl apply -f deploy-demo.yaml
连入node02节点上的pod,ping node01节点上的pod:
此时去node01上抓物理网卡的包,发现pod之间直接用的物理网卡通信: