Kubernetes系统上Pod网络的实现依赖于第三方插件,而Flannel是由CoreOS主推的目前比较主流的容器网络解决方案,CNI插件有两种功能:网络配置和网络策略,由于flannel比较简单,并不支持网络策略,flannel项目自身只是一个框架,真正提供网络功能的是它的后端实现,目前,Flannel支持三种不同后端实现,分别是:
- UDP
- VXLAN
- host-gw
UDP是Flannel项目最早支持的一种方式,是性能最差的方式,目前已被废弃。
用的最多的是VXLAN和host-gw模式的部署
来自: https://www.cnblogs.com/kevingrace/p/6859114.html
对上图的简单说明 (Flannel的工作原理可以解释如下): -> 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。 -> Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。 -> 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。 这样整个数据包的传递就完成了,这里需要解释三个问题: 1) UDP封装是怎么回事? 在UDP的数据内容部分其实是另一个ICMP(也就是ping命令)的数据包。原始数据是在起始节点的Flannel服务上进行UDP封装的,投递到目的节点后就被另一端的Flannel服务 还原成了原始的数据包,两边的Docker服务都感觉不到这个过程的存在。 2) 为什么每个节点上的Docker会使用不同的IP地址段? 这个事情看起来很诡异,但真相十分简单。其实只是单纯的因为Flannel通过Etcd分配了每个节点可用的IP地址段后,偷偷的修改了Docker的启动参数。 在运行了Flannel服务的节点上可以查看到Docker服务进程运行参数(ps aux|grep docker|grep "bip"),例如“--bip=182.48.25.1/24”这个参数,它限制了所在节 点容器获得的IP范围。这个IP范围是由Flannel自动分配的,由Flannel通过保存在Etcd服务中的记录确保它们不会重复。 3) 为什么在发送节点上的数据会从docker0路由到flannel0虚拟网卡,在目的节点会从flannel0路由到docker0虚拟网卡? 例如现在有一个数据包要从IP为172.17.18.2的容器发到IP为172.17.46.2的容器。根据数据发送节点的路由表,它只与172.17.0.0/16匹配这条记录匹配,因此数据从docker0 出来以后就被投递到了flannel0。同理在目标节点,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的172.17.46.0/24这个记录上,自然的被投递到了docker0网卡。 pipework的思路 pipework是一个单机的工具,组合了brctl等工具,可以认为pipework解决的是宿主机上的设置容器的虚拟网卡、网桥、ip等,可以配合其他网络使用。 如果容器数量不多,想简单的组一个大的3层网络,可以考虑weave 如果容器数量很多,而且你们的环境复杂,需要多个子网,可以考虑open vswitch或者fannel weave的总体网络性能表现欠佳, flannel VXLAN 能满足要求,一般推荐用flannel
Flannel VXLAN模式配置
官方网站 https://github.com/coreos/flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
输出如下结果表示运行正常:
[root@kube ~]# kubectl get ds -n kube-system //ds 是 daemonset NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-flannel-ds-amd64 3 3 3 3 3 beta.kubernetes.io/arch=amd64 61d kube-flannel-ds-arm 0 0 0 0 0 beta.kubernetes.io/arch=arm 61d kube-flannel-ds-arm64 0 0 0 0 0 beta.kubernetes.io/arch=arm64 61d kube-flannel-ds-ppc64le 0 0 0 0 0 beta.kubernetes.io/arch=ppc64le 61d kube-flannel-ds-s390x 0 0 0 0 0 beta.kubernetes.io/arch=s390x 61d kube-proxy 3 3 3 3 3 beta.kubernetes.io/os=linux 61d [root@kube ~]#
运行正常后,flanneld会在宿主机的/etc/cni/net.d目录下生成自已的配置文件,kubelet将会调用它。
网络插件运行成功后,Node状态才Ready
[root@kube ~]# kubectl get node NAME STATUS ROLES AGE VERSION kube.master Ready master 61d v1.15.0 kube.node1 Ready60d v1.15.0 kube.node2 Ready 61d v1.15.0 [root@kube ~]#
当前路由:
[root@kube ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.2.61.30 0.0.0.0 UG 100 0 0 ens192 10.2.61.0 0.0.0.0 255.255.255.224 U 100 0 0 ens192 10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 10.244.1.0 10.244.1.0 255.255.255.0 UG 0 0 0 flannel.1 10.244.2.0 10.244.2.0 255.255.255.0 UG 0 0 0 flannel.1 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 [root@kube ~]#
flannel 配置文件:
root@kube deploy]# kubectl edit configmap kube-flannel-cfg -n kube-system # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 data: cni-conf.json: | { "name": "cbr0", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } kind: ConfigMap metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"cni-conf.json":"{\n \"name\": \"cbr0\",\n \"plugins\": [\n {\n \"type\": \"flannel\",\n \"delegate\": {\n \"hairpinMode\": true,\n \"isDefaultGateway\": true\n }\n },\n {\n \"type\": \"portmap\",\n \"capabilities\": {\n \"portMappings\": true\n }\n }\n ]\n}\n","net-conf.json":"{\n \"Network\": \"10.244.0.0/16\",\n \"Backend\": {\n \"Type\": \"vxlan\"\n }\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"flannel","tier":"node"},"name":"kube-flannel-cfg","namespace":"kube-system"}} creationTimestamp: "2019-07-11T10:05:58Z" labels: app: flannel tier: node name: kube-flannel-cfg namespace: kube-system resourceVersion: "993" selfLink: /api/v1/namespaces/kube-system/configmaps/kube-flannel-cfg uid: afcc9c68-6a2a-4708-bef6-8c149b563824 ~
Flannel VXLAN之Directrouting模式配置
net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan", //必须加逗号 "Directrouting": true } }
Flannel host-gw 配置
与Directrouting类似,将flannel的configmap对象改为:
net-conf.json: | { "Network": "10.244.0.0/16", #默认网段 "Backend": { "Type": "VXLAN", "Directrouting": true #增加 } }
需要删除原有 flannel 配置