K8s网络组件之Flannel:VXLAN模式
K8s网络模型: CNI(容器网络接口)
CNI(Container Network Interface,容器网络接口):是一个容器网络规范,Kubernetes网络采用的就是这个CNI规 范,负责初始化infra容器的网络设备。
CNI二进制程序默认路径:/opt/cni/bin/
项目地址:https://github.com/containernetworking/cni
以Flannel网络组件为例,当部署Flanneld后,会在每台宿主机上生成它对应的CNI配置文件(它其实是一个ConfigMap),从而告诉Kubernetes要使用 Flannel 作为容器网络方案。
CNI配置文件默认路径:/etc/cni/net.d
当 kubelet 组件需要创建 Pod 的时候,先调用dockershim它先创建一个 Infra 容器。然后调用 CNI 插件为 Infra 容器配置网络。
这两个路径可在kubelet启动参数中定义:
--network-plugin=cni
--cni-conf-dir=/etc/cni/net.d
--cni-bin-dir=/opt/cni/bin
下面放置着CNI网络插件的二进制程序,通过这些程序完成与cni的对接
[root@k8s-master ~]# ls /opt/cni/bin/ bandwidth dhcp flannel host-local loopback portmap sbr tuning bridge firewall host-device ipvlan macvlan ptp static vlan
CNI配置文件默认路径:/etc/cni/net.d
[root@k8s-master ~]# ls /etc/cni/net.d/ 10-flannel.conflist [root@k8s-master ~]# cat /etc/cni/net.d/10-flannel.conflist { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] }
这里面就包含了配置内容
所以cni参数都是在kubelet上面配置的,以为它负责创建容器并且为其配置容器网络
CNI的配置是有下面三个参数,第一个就是启用cni网络插件,也就是k8s要使用cni就必须启用
简单说cni就是网络组件的接口,好让第三方的网络都能接入到k8s网络里面来
--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin
K8s网络组件之Flannel
Flannel是CoreOS维护的一个网络组件,Flannel为每个Pod提供全局唯一的IP,Flannel使用ETCD来存储Pod子网与Node IP之间的关系。flanneld守护进程在每台主机上运行,并负责维护ETCD信息和路由数据包。
这句话体现的几点:
守护进程
使用存储etcd来pod子网和nodeip之前关系,使用ETCD存储子网
提供全局的IP
项目地址: https://github.com/coreos/flannel
YAML地址:https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
K8s网络组件之Flannel:部署
在这个文件当中需要了解这个,配置网络相关的信息,配置子网和工作模式,这两个你可能需要修改,Backend:指定工作模式
net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } }
使用的是deamonset部署的
apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds-amd64 namespace: kube-system
在部署之前需要做的事情
10.244.0.0/16 这是一个大的子网,会确保每个node都分配到独立的网段
• Network:指定Pod IP分配的网段,与controller-manager配置的保持一样
--allocate-node-cidrs=true
--cluster-cidr=10.244.0.0/16
• kubeadm部署:/etc/kubernetes/manifests/kube-controller-manager.yaml
• 二进制部署:/opt/kubernetes/cfg/kube-controller-manager.conf
我这里部署集群默认是配置好了,就不需要修改了
[root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-controller-manager.yaml - command: - kube-controller-manager - --allocate-node-cidrs=true - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf - --bind-address=127.0.0.1 - --client-ca-file=/etc/kubernetes/pki/ca.crt - --cluster-cidr=10.244.0.0/16 [root@k8s-master ~]# cat /opt/kubernetes/cfg/kube-controller-manager.conf KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --leader-elect=true \ --master=127.0.0.1:8080 \ --bind-address=127.0.0.1 \ --allocate-node-cidrs=true \ --cluster-cidr=10.244.0.0/16 \ --service-cluster-ip-range=10.0.0.0/24 \ --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \ --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \ --root-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \ --experimental-cluster-signing-duration=87600h0m0s"
如果部署了calico那么先删除,在一个k8s网络当中只能使用一个网络组件
[root@k8s-master ~]# kubectl delete -f calico.yaml [root@k8s-master ~]# rm -f /etc/cni/net.d/10-calico.conflist /etc/cni/net.d/calico-kubeconfig [root@k8s-master ~]# kubectl apply -f kube-flannel.yml [root@k8s-master ~]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE kube-flannel-ds-amd64-lb6vm 1/1 Running 0 139d kube-flannel-ds-amd64-lxxdq 1/1 Running 0 139d kube-flannel-ds-amd64-vl4fn 1/1 Running 0 139d
K8s网络组件之Flannel:工作模式
UDP:最早支持的一种方式,由于性能最差,目前已经弃用。
VXLAN:Overlay Network方案,源数据包封装在另一种网络包里面进行路由转发和通信
Host-GW:Flannel通过在各个节点上的Agent进程,将容器网络的路由信息写到主机的路由表上,这样一来所有的主机都有整个容器网络的路由数据了。
Directrouting:同时支持VXLAN和Host-GW工作模式
公有云VPC:ALIYUN,AWS
K8s网络组件之Flannel:VXLAN模式
隧道模式内部自己实现了封装方式,VETP设备用于封包和解包
VTEP设备进行封装和解封装的对象是二层数据帧,这个工作是在Linux内核中完成的。
[root@k8s-master ~]# ifconfig cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.1 netmask 255.255.255.0 broadcast 10.244.0.255 inet6 fe80::ec98:8bff:fea1:554d prefixlen 64 scopeid 0x20<link> ether ee:98:8b:a1:55:4d txqueuelen 1000 (Ethernet) RX packets 35973 bytes 9023583 (8.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 40472 bytes 28071561 (26.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:b9:2e:09:e2 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.179.99 netmask 255.255.255.0 broadcast 192.168.179.255 inet6 fe80::54c7:3ae8:3659:6b97 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:b4:88:32 txqueuelen 1000 (Ethernet) RX packets 5674009 bytes 2565682866 (2.3 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6213197 bytes 4945068979 (4.6 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::2027:5aff:fef0:9316 prefixlen 64 scopeid 0x20<link> ether 22:27:5a:f0:93:16 txqueuelen 0 (Ethernet) RX packets 3604 bytes 2986402 (2.8 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2830 bytes 585691 (571.9 KiB) TX errors 1 dropped 8 overruns 0 carrier 1 collisions 0 vethf5cad454: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::6401:bbff:fe31:76bd prefixlen 64 scopeid 0x20<link> ether 66:01:bb:31:76:bd txqueuelen 0 (Ethernet) RX packets 6 bytes 509 (509.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 13 bytes 1000 (1000.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@k8s-master ~]# ip route 10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 宿主机查看目标网段址10.244.2.10,那么就会走这个路由表 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 这个路由表的下一条是 10.244.1.0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.0
K8s网络组件之Flannel
项目地址: https://github.com/coreos/flannel
YAML地址:https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
下面看看vxlan模式下,不同主机的pod通信
Pod1容器当中发出了数据包,这个数据包会到达宿主机上面的cni0这个网桥,前面的流程和docker流程一样,只要发送数据包肯定要到达cni0,cni0在这里充当了网桥的作用,二层交换,容器以cni0的网桥作为网关,不管是不是处于同网段都会到达cni0网桥这里,这是第一步
第二步 数据包已经到达了宿主机上面,宿主机上面的网络协议栈可以看到这个数据包的,所以会根据路由表转发到flannel.1这张虚拟网卡,也即是来到了隧道的入口
[root@k8s-master ~]# ip route 10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 宿主机查看目标网段址10.244.2.10,那么就会走这个路由表 10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 这个路由表的下一条是 10.244.1.0 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.0
这样数据包来到宿主机查看宿主机上面的路由表发到下一跳即flannel.1设备
flannel.1设备这个设备是完成vetp这个设备封装的,就相当于隧道的入口,之后就要使用xvlan对其进行封装,封装之后再走宿主机上面的网络,这里数据的封包是二层的
封装包必须要有目标的mac地址
flannel.1就是vetp设备,基于二层去封装,那么必须知道目标mac地址是谁,这里源IP目标IP都知道
查看这个网卡的arp信息,这两个就是地址就是另外两台机器上面的 flannel.1 mac地址
[root@k8s-master ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kubia-859d757f8c-74g6s 1/1 Running 0 124d 10.244.2.4 k8s-node2 <none> <none> kubia-859d757f8c-97znt 1/1 Running 0 124d 10.244.0.14 k8s-master <none> <none> kubia-859d757f8c-9mjf9 1/1 Running 0 124d 10.244.1.5 k8s-node1 <none> <none> [root@k8s-master ~]# ifconfig flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.0.0 [root@k8s-node1 ~]# ifconfig flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.1.0 [root@k8s-node2 ~]# ifconfig flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.244.2.0 其实在flanneld进程启动后,就会自动添加其他节点ARP记录,可以通过ip neigh show dev flannel.1命令查看 [root@k8s-master ~]# ip neigh show dev flannel.1 10.244.2.0 lladdr 4a:5a:f0:f5:19:5e PERMANENT 10.244.1.0 lladdr b6:68:f7:5e:af:9c PERMANENT 这个走的是二层的 [root@k8s-master ~]# bridge fdb show dev flannel.1 b6:68:f7:5e:af:9c dst 192.168.179.100 self permanent 4a:5a:f0:f5:19:5e dst 192.168.179.101 self permanent
找到宿主机的IP就可以向这个宿主机发送UDP的数据包
K8s网络组件之Flannel:VXLAN模式
目录 返回
首页