一、版本信息

名称

版本

kubernetes

1.22.5

etcd

3.5.2

docker

19.03.8

flannel

0.14.0

cni

0.8.6

CNI:容器网络接口(Container NetWork Interface)。CNI最初是由CoreOS为rkt容器引擎创建的,目前绝大部分的容器平台都采用CNI标准,已经成为事实标准。(Docker并没有采用CNI标准,而是CNM标准,即Container NetWork Model)

前提条件:通过二进制的方式,部署一个Kubernetes集群,集群部署完成(节点都加入集群,但都是NotReady状态),具体部署方式可参考之前的部署文章。

二、安装CNI

在kubelet官方配置文档中,关于cni的配置一共有三项:

  • --cni-bin-dir string Default: /opt/cni/bin
  • --cni-cache-dir string Default: /var/lib/cni/cache
  • --cni-conf-dir string Default: /etc/cni/net.d

从上面的配置可以看出,我们需要把CNI及其配置文件放知道特定的目录下,或者自己指定不同的目录,并配置到kubelet的启动参数中。本文采用默认配置,则不需要修改kubelet的启动参数配置。

# 1、下载cni
wget https://github.com//containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz

# 2、解压缩到指定目录(kubernetes默认的cni安装路径是/opt/cni/bin,所以需要将cni解压缩到此目录)
mkdir /opt/cni/bin -p
tar xf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin/

# 3、将此目录复制到其余节点
for i in node01 node02;do scp -r /opt/cni/ $i:/opt/;done

# 4、配置cni
cat > /etc/cni/net.d/10-flannel.conflist <<EOF
{
  "name": "cbr0",
  "cniVersion": "0.3.1",
  "plugins": [
    {
      "type": "flannel",
      "delegate": {
        "hairpinMode": true,
        "isDefaultGateway": true
      }
    },
    {
      "type": "portmap",
      "capabilities": {
        "portMappings": true
      }
    }
  ]
}
EOF

# 5、将配置文件复制到其余节点
for i in node01 node02;do scp -r /etc/cni $i:/etc/;done

三、安装flannel

# 1、下载flannel
wget https://github.com/flannel-io/flannel/releases/download/v0.14.0/flannel-v0.14.0-linux-amd64.tar.gz

# 2、解压缩并把二进制flanneld放到指定位置
tar zvxf flannel-v0.17.0-linux-amd64.tar.gz
mv flanneld /usr/local/bin/

# 3、把二进制flanneld复制到其余节点
for i in node01 node02;do scp /usr/local/bin/flanneld $i:/usr/local/bin/;done

# 4、配置flannel
mkdir /etc/kube-flannel/
cat > /etc/kube-flannel/net-conf.json <<EOF
{
    "Network": "172.244.0.0/16",    # kubernetes集群子网网段,要与kubernetes子网段配置保持一致
    "Backend": {
        "Type": "vxlan",
        "DirectRouting": true
    }
}
EOF

# 5、将配置文件复制到其余节点
for i in node01 node02;do scp -r /etc/kube-flannel/ $i:/etc/;done

四、配置flannel的kube-config

通过kube-config使得flannel可以访问kubernetes集群

# 1、为flannel创建service account并初始化集群角色
cat <<EOF | kubectl apply -f -
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups: ['extensions']
  resources: ['podsecuritypolicies']
  verbs: ['use']
  resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
EOF

# 2、生成kube-config
mkdir /opt/flannel
cd /opt/flannel
KUBE_APISERVER="https://172.16.166.87:6443"      # 修改为自己集群的kube-apiserver地址
KUBE_ROOT_CA_FILE="/opt/kubernetes/ssl/ca.pem"   # 修改为自己集群的根证书地址

kubectl config set-cluster kubernetes \
--kubeconfig=flannel.conf \
--embed-certs \
--server=${KUBE_APISERVER} \
--certificate-authority=${KUBE_ROOT_CA_FILE}

kubectl config set-credentials flannel \
--kubeconfig=flannel.conf \
--token=$(kubectl get sa -n kube-system flannel -o jsonpath={.secrets[0].name} | xargs kubectl get secret -n kube-system  -o jsonpath={.data.token} | base64 -d)

kubectl config set-context kubernetes \
--kubeconfig=flannel.conf \
--user=flannel \
--cluster=kubernetes

kubectl config use-context kubernetes \
--kubeconfig=flannel.conf

# 3、将该证书复制到其余节点
for i in node01 node02;do scp -r /opt/flannel/ $i:/opt/;done

五、通过systemd管理flannel并启动

# 1、生成systemd管理flannel的文件
cat > /usr/lib/systemd/system/flanneld.service <<EOF
[Unit]
Description=Flanneld
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service

[Service]
Type=notify
Environment=NODE_NAME=master01             # 此处修改为当前节点的hostname,并保持与kubelet配置中的hostname-override配置的名称一致,否则会报节点NotFound的错误
ExecStart=/usr/local/bin/flanneld \\
  --iface=enp5s0 \\                        # 此处修改为当前节点的物理网卡名称
  --ip-masq \\
  --kube-subnet-mgr=true \\
  --kubeconfig-file=/opt/flannel/flannel.conf

Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

# 2、将该文件复制到其余节点
for i in node01 node02;do scp /usr/lib/systemd/system/flanneld.service $i:/usr/lib/systemd/system/;done

# 3、所有节点启动flannel
systemctl daemon-reload
systemctl start flanneld
systemctl status flanneld
systemctl enable flanneld

# 4、所有节点重启kubelet,此处注意
systemctl restart kubelet

# 5、所有节点启动成功后,都会在各个节点的/run/flannel/目录下生成一个subnet.env的文件,里面记录了当前节点的子网段信息,具体相关信息可以查看之前关于网络的一篇文章
cat /run/flannel/subnet.env 
FLANNEL_NETWORK=172.244.0.0/16
FLANNEL_SUBNET=172.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

此时查看节点状态,发现节点已经是Ready状态,证明flannel安装成功。通过此次安装,可以了解到这种设计的思想,即通过服务接口加grpc访问的方式,实现不同网络插件和kubernetes的解耦,达到了网络插件的可插拔目标。这种思想kubernetes同样使用在了cri(容器运行时接口),后续会再了解cri的相关实现。

参考文章连接:https://soulchild.cn/2509.html