首页 > 其他分享 >网络组件Flannel总结

网络组件Flannel总结

时间:2022-11-05 15:01:22浏览次数:51  
标签:总结 kube Flannel 01 master IP 组件 k8s flannel

一、Flannel简介

1.1、Flannel原理架构

github地址:https://github.com/flannel-io/flannel

flannel最早由CoreOS开发,它是容器编排系统中最成熟的网络插件示例之一。随着CNI概念的兴起,flannel也是最早实现CNI标准的网络插件(CNI标准也是由CoreOS提出的)。flannel的功能非常简单明确,解决容器跨节点访问的问题。flannel的设计目的是为集群中的所有节点重新规划IP地址的使用规则,从而使得集群中的不同节点主机创建的容器都具有全集群“唯一”且“可路由的IP地址”,并让属于不同节点上的容器能够直接通过内网IP通信。那么节点是如何知道哪些IP可用,哪些不可用,即其他节点已经使用了哪些网段,flannel就用到了etcd的分布式协同功能。

flannel网络中pod跨主机转发流程

flannel在架构上分为管理面和数据面,管理面主要包含一个etcd,用于协调各个节点上容器分配的网段,数据面即在每个节点上运行一个flanneld进程。与其他网络方案不同的是,flannel采用的是no server架构,即不存在所谓的控制节点,简化了flannel的部署与运维。集群内所有flannel节点共享一个大的容器地址段(在我们的例子中就是10.0.0.0/16),flanneld一启动便会观察etcd,从etcd得知其他节点上的容器已占用网段信息,然后像etcd申请该节点可用的IP地址段(在大网段中划分一个,例如10.0.2.0/24),并把该网段和主机IP地址等信息都记录在etcd中。flannel通过etcd分配了每个节点可用的IP地址段后,修改了Docker的启动参数,例如--bip=172.17.18.1/24限制了所在节点容器获得的IP范围,以确保每个节点上的Docker会使用不同的IP地址段,需要注意的是,这个IP范围是有flannel自动分配的,由flannel通过保存在etcd服务中的记录确保它们不会重复,无需用户手动干预。flannel的底层实现实质上是一种overlay网络(除了Host-Gateway模式),即把某一协议的数据包封装在另一种网络协议中进行路由转发。flannel在封包的时候会观察etcd的数据,在其他节点向etcd更新网段和主机IP信息时,etcd感知到,在向其他主机上的容器转发网络包,用对方的容器所在主机的IP进行封包,然后将数据发往对应主机上的flanneld,再交由其转发给目的容器。

flannel架构图

flannel网络模式

Flannel 网络模型 (后端模型),Flannel目前有三种方式实现 UDP/VXLAN/host-gw

  • UDP:早期版本的Flannel使用UDP封装完成报文的跨越主机转发,其安全性及性能略有不足。
  • VXLAN:Linux 内核在在2012年底的v3.7.0之后加入了VXLAN协议支持, 因此新版本的Flannel也有UDP转换为VXLAN,VXLAN本质上是一种tunnel(隧道) 协议,用来基于3层网络实现虚拟的2层网络,目前flannel 的网络模型已经是基于VXLAN的叠加(覆盖)网络,目前推荐使用vxlan作为其网络模型。
  • Host-gw:也就是Host GateWay,通过在node节点上创建到达各目标容器地址的路由表而完成报文的转发,因此这种方式要求各node节点本身必须处于同一个局域网(二层网络)中,因此不适用于网络变动频繁或比较大型的网络环境,但是其性能较好。

Flannel 组件

  • Cni0:网桥设备,每创建一个pod都会创建一对veth pair,其中一端是pod中的eth0,另一端是Cni0网桥中的端口(网卡),Pod中从网卡eth0发出的流量都会发送到Cni0网桥设备的端口(网卡)上,Cni0设备获得的ip地址是该节点分配到的网段的第一个地址。
  • Flannel.1: overlay网络的设备,用来进行vxlan报文的处理(封包和解包),不同node之间的pod数据流量都从overlay设备以隧道的形式发送到对端。

1.2、flannel UDP模式跨主机通信

容器跨节点通信实现流程:假设在节点A上有容器A(10.244.1.96),在节点B上有容器B(10.244.2.194)。此时容器A向容器发送一个ICMP请求报文(ping)。

(1)容器A发出ICMP请求报文,通过IP封装后的形式为10.244.1.96(源)--->10.244.2.194(目的),通过容器A内的路由表匹配到应该将IP包发送到网关10.244.1.1(cni0网桥)。

此时的ICMP报文以太网帧格式

(2)到达cni0的IP包目的地IP 10.244.2.194,匹配到节点A上第一条路由规则(10.244.0.0),内核通过查本机路由表知道应该将RAW IP包发送给flannel0接口。

(3)flannel0 为tun设备,发送给flannel0接口的RAW IP包(无MAC信息)将被flanneld进程接收,flanneld进程接收RAW IP包后在原有的基础上进行UDP封包,UDP封包的形式为172.16.130.140:{系统管理的随机端口}--->172.16.130.164;8285。

注:172.16.130.164是10.244.2.194这个目的容器所在宿主机的IP地址,flanneld通过查询etcd很容易得到,8285是flanneld监听端口。

(4)flanneld将封装好的UDP报文经eth0发出,从这里可以看出网络包在通过eth0发出前先是加上UDP头(8个字节),再加上IP头(20个字节)进行封装,这也是flannel0的MTU要被eth0的MTU小28个字节的原因,即防止封包的以太网帧超过eth0的MTU,而在经过eth0时被丢弃。

此时,完整的封包后的ICMP以太网帧格式

(5)网络包经过主机网络从节点A到达节点B。

(6)主机B收到UDP报文后,Linux内核通过UDP端口号8285将包交给正在监听的flanneld。

(7)运行在hostB中的flanneld将UDP包解封包后得到RAW IP包:10.244.1.96--->10.244.2.194。

(8)解封包后的RAW IP包匹配到主机B上的路由规则(10.244.2.0),内核通过查本机路由表知道应该将RAW IP包发送到cni0网桥。

此时,完整的解封包后的以太网帧格式

(9)cni0网桥将IP包转发给连接在该网桥上的容器B,由docker0转发到目标容器,至此整个流程结束。回程报文将按上面的数据流原路返回。

flannel UDP 模式数据流简图

1.3、flannel VXLAN模式数据通信

(1)同UDP Backend模式,容器A中的IP包通过容器A内的路由表被发送到cni0。

(2)到达cni0中的IP包通过匹配hostA中的路由表发现通过10.244.2.194的IP包应该交给flannel1.1接口。

(3)flannel1.1作为一个VTEP设备,收到报文后将按照VTEP的配置进行封包。首先,通过etcd得知10.244.2.194属于节点B,并得到节点B的IP。然后,通过节点A中的转发表得到节点B对应的VTEP的MAC,根据flannel1.1设备创建时的设置参数(VNI、localIP、Port)进行VXLAN封包。

(4)通过host A 跟host B 之间的网络连接,VXLAN包到达hostB的eth1接口。

(5)通过端口8472,VXLAN包被转发给VTEP设备flannel1.1进行解包。

(6)解封装后的IP包匹配hostB中的路由表(10.244.2.0),内核将IP包转发给cni0。

(7)cni0将IP包转发给连接在cni0上的容器B。

flannel VXLAN模式工作原理

1.4、flannel Host-gw模式数据通信

(1)同UDP、VXLAN模式一致,通过容器A的路由表IP包到达cni0。

(2)到达cni0的IP包匹配到hostA中的路由规则(10.244.2.0),并且网关为172.16.130.164,即hostB,所以内核将IP包发送给hostB(172.16.130.164)。

(3)IP包通过物理网络到达hostB的eth1。

(4)到达hostB eth1的IP包匹配到hostB中的路由表(10.244.2.0),IP包被转发给cni0。

(5)cni0 将IP包转发给连接在cni0上的容器B。

二、flannel环境部署

#环境准备
192.168.247.81 k8s-flannel-master-01 kubeapi.flannel.com  2vcpu 4G 50G  ubuntu20.04
192.168.247.84 k8s-flannel-node-01                        2vcpu 4G 50G  ubuntu20.04
192.168.247.85 k8s-flannel-node-02                        2vcpu 4G 50G  ubuntu20.04

#关闭swap
swapoff  -a
sed -i 's@/swap.img@#/swap.img@g' /etc/fstab

#关闭防火墙
ufw disable && ufw status

#配置时间同步
apt install chrony -y
cat > /etc/chrony/chrony.conf <<EOF
server ntp.aliyun.com iburst
stratumweight 0
driftfile /var/lib/chrony/drift
rtcsync
makestep 10 3
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
keyfile /etc/chrony.keys
commandkey 1
generatecommandkey
logchange 0.5
logdir /var/log/chrony
EOF
systemctl restart chrony

#安装并启用docker
apt -y install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt update
apt install docker-ce -y

#配置docker加速
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://reg-mirror.qiniu.com",
"https://registry.docker-cn.com",
"https://a7h8080e.mirror.aliyuncs.com"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "200m"
},
"storage-driver": "overlay2"
}
EOF
systemctl restart docker
docker info #查看docker版本及加速是否生效

#安装cri-dockerd
curl -LO https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.6/cri-dockerd_0.2.6.3-0.ubuntu-focal_amd64.deb
apt install ./cri-dockerd_0.2.6.3-0.ubuntu-focal_amd64.deb

#安装kubelet、kubeadm、kubectl
apt update && apt install -y apt-transport-https curl
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF apt-get update apt install -y kubelet kubeadm kubectl systemctl enable kubelet #整合kubelet和cri-dockerd # vim /usr/lib/systemd/system/cri-docker.service # cat /usr/lib/systemd/system/cri-docker.service [Unit] Description=CRI Interface for Docker Application Container Engine Documentation=https://docs.mirantis.com After=network-online.target firewalld.service docker.service Wants=network-online.target Requires=cri-docker.socket [Service] Type=notify #ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-cache-dir=/var/lib/cni/cache --cni-conf-dir=/etc/cni/net.d ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl restart cri-docker #配置kubelet mkdir /etc/sysconfig/ vim /etc/sysconfig/kubelet #初始化master # kubeadm config images list #查看所需的容器镜像 registry.k8s.io/kube-apiserver:v1.25.3 registry.k8s.io/kube-controller-manager:v1.25.3 registry.k8s.io/kube-scheduler:v1.25.3 registry.k8s.io/kube-proxy:v1.25.3 registry.k8s.io/pause:3.8 registry.k8s.io/etcd:3.5.4-0 registry.k8s.io/coredns/coredns:v1.9.3

#拉取镜像 kubeadm config images pull --cri-socket unix:///run/cri-dockerd.sock #拉取镜像 #初始化集群 kubeadm init --control-plane-endpoint="kubeapi.flannel.com" \ --kubernetes-version=v1.25.3 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12 \ --token-ttl=0 \ --cri-socket unix:///run/cri-dockerd.sock \ --upload-certs

#master添加
kubeadm join kubeapi.flannel.com:6443 --token 9qajrn.br48bhnpqyhq593p \
--discovery-token-ca-cert-hash sha256:4b72b489daf2bb7052c67065339796f966a666de6068735babf510259c0717ca \
--control-plane --certificate-key 19db0bbf09af6973df6cd0ad93b974be028bbabcde41c714b5ecc3616487a776
#node添加
kubeadm join kubeapi.flannel.com:6443 --token 9qajrn.br48bhnpqyhq593p \
--discovery-token-ca-cert-hash sha256:4b72b489daf2bb7052c67065339796f966a666de6068735babf510259c0717ca \
--cri-socket unix:///run/cri-dockerd.sock

[root@k8s-flannel-master-01 ~]# mkdir -p $HOME/.kube
[root@k8s-flannel-master-01 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-flannel-master-01 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-flannel-master-01 ~]# 
[root@k8s-flannel-master-01 ~]# kubectl get node -owide
NAME                    STATUS     ROLES           AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-flannel-master-01   NotReady   control-plane   13m   v1.25.3   192.168.247.81   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
k8s-flannel-node-01     NotReady   <none>          83s   v1.25.3   192.168.247.84   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
k8s-flannel-node-02     NotReady   <none>          79s   v1.25.3   192.168.247.85   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
[root@k8s-flannel-master-01 ~]# 
[root@k8s-flannel-master-01 ~]# kubectl get pod -A
NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE
kube-system   coredns-565d847f94-khn5v                        0/1     Pending   0          128m
kube-system   coredns-565d847f94-xsvrp                        0/1     Pending   0          128m
kube-system   etcd-k8s-flannel-master-01                      1/1     Running   0          128m
kube-system   kube-apiserver-k8s-flannel-master-01            1/1     Running   0          128m
kube-system   kube-controller-manager-k8s-flannel-master-01   1/1     Running   0          128m
kube-system   kube-proxy-ccsp9                                1/1     Running   0          115m
kube-system   kube-proxy-jlhdb                                1/1     Running   0          128m
kube-system   kube-proxy-wdnjh                                1/1     Running   0          115m
kube-system   kube-scheduler-k8s-flannel-master-01            1/1     Running   0          128m
[root@k8s-flannel-master-01 ~]#

#安装flannel
mkdir /opt/bin/
curl -L   https://github.com/flannel-io/flannel/releases/download/v0.20.1/flanneld-amd64 -o /opt/bin/flanneld
chmod +x /opt/bin/flanneld

#拷贝flannel安装文件
https://github.com/flannel-io/flannel/blob/master/Documentation/kube-flannel.yml
[root@k8s-flannel-master-01 ~]# kubectl apply -f kube-flannel.yaml #安装flannel网络插件
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
[root@k8s-flannel-master-01 ~]#
[root@k8s-flannel-master-01 ~]# kubectl get node -owide
NAME                    STATUS   ROLES           AGE    VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-flannel-master-01   Ready    control-plane   158m   v1.25.3   192.168.247.81   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
k8s-flannel-node-01     Ready    <none>          146m   v1.25.3   192.168.247.84   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
k8s-flannel-node-02     Ready    <none>          146m   v1.25.3   192.168.247.85   <none>        Ubuntu 20.04.3 LTS   5.4.0-122-generic   docker://20.10.21
[root@k8s-flannel-master-01 ~]# 
[root@k8s-flannel-master-01 ~]# kubectl get pod -A
NAMESPACE      NAME                                            READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-5n4qv                           1/1     Running   0          5m8s
kube-flannel   kube-flannel-ds-8b97k                           1/1     Running   0          5m8s
kube-flannel   kube-flannel-ds-bbksr                           1/1     Running   0          5m8s
kube-system    coredns-565d847f94-khn5v                        1/1     Running   0          158m
kube-system    coredns-565d847f94-xsvrp                        1/1     Running   0          158m
kube-system    etcd-k8s-flannel-master-01                      1/1     Running   0          158m
kube-system    kube-apiserver-k8s-flannel-master-01            1/1     Running   0          158m
kube-system    kube-controller-manager-k8s-flannel-master-01   1/1     Running   0          158m
kube-system    kube-proxy-ccsp9                                1/1     Running   0          146m
kube-system    kube-proxy-jlhdb                                1/1     Running   0          158m
kube-system    kube-proxy-wdnjh                                1/1     Running   0          146m
kube-system    kube-scheduler-k8s-flannel-master-01            1/1     Running   0          158m
[root@k8s-flannel-master-01 ~]#
[root@k8s-flannel-master-01 ~]# kubectl create deployment nginx  --image=nginx:1.23.2-alpine --replicas=3
deployment.apps/nginx created
[root@k8s-flannel-master-01 ~]# 
[root@k8s-flannel-master-01 ~]# kubectl get pod -owide
NAME                    READY   STATUS    RESTARTS   AGE    IP           NODE                  NOMINATED NODE   READINESS GATES
nginx-5cd78c5d7-2nll4   1/1     Running   0          3m8s   10.244.1.2   k8s-flannel-node-01   <none>           <none>
nginx-5cd78c5d7-gb7f6   1/1     Running   0          3m8s   10.244.2.4   k8s-flannel-node-02   <none>           <none>
nginx-5cd78c5d7-hf6nr   1/1     Running   0          3m8s   10.244.1.3   k8s-flannel-node-01   <none>           <none>
[root@k8s-flannel-master-01 ~]#
[root@k8s-flannel-master-01 ~]# kubectl create service nodeport nginx --tcp=80:80
service/nginx created
[root@k8s-flannel-master-01 ~]# kubectl get svc -l app=nginx
NAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx   NodePort   10.101.156.194   <none>        80:31818/TCP   13s
[root@k8s-flannel-master-01 ~]#
[root@k8s-flannel-master-01 ~]# curl 192.168.247.81:31818
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-flannel-master-01 ~]# 

三、Flannel Pod通信

3.1、Flannel Pod通信抓包

Flannel vxlan架构图

1、flannel通信流程

vxlan报文格式

 

 




标签:总结,kube,Flannel,01,master,IP,组件,k8s,flannel
From: https://www.cnblogs.com/cyh00001/p/16833582.html

相关文章