文章

🧑🏻‍💻 Kubernetes 部署

KubeEdge 由云和边缘组成。它建立在 Kubernetes 之上,为联网、应用部署和云与边缘之间的元数据同步提供核心基础设施支持。

🧑🏻‍💻 Kubernetes 部署

KubeEdge 由云和边缘组成。它建立在 Kubernetes 之上,为联网、应用部署和云与边缘之间的元数据同步提供核心基础设施支持。

0 - 资源列表

类型操作系统主机名IP(内网)所需软件
云端服务器Centos 7.4k8s-master172.31.62.175Docker, Kubernetes cluster, cloudcore
边缘服务器Ubuntu 20.04.6node0192.168.224.133Docker, MQTT(选用), edgecore

注意:配置时使用的云端服务器 IP 均指内网 IP,可执行 ifconfig 命令查询。本文中所有 IP 地址应根据实际修改。

由于云端和边缘系统不同,故操作有差异,为避免混淆,本文将分为两个部分,分别记录云端和边缘端的配置过程。

1 - 云端服务器

1.1 - 准备环境

关闭防火墙:

1
2
systemctl stop firewalld
systemctl disable firewalld

关闭 selinux:

1
2
sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
setenforce 0  # 临时

关闭 swap:

1
2
swapoff -a  # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab  # 永久

根据规划设置主机名:

1
hostnamectl set-hostname k8s-master

添加 /etc/hosts 配置文件:

1
2
3
4
cat >> /etc/hosts << EOF
172.31.62.175 k8s-master
192.168.224.133 node1
EOF

将桥接的 IPv4 流量传递到 IPTABLES 的链:

1
2
3
4
5
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

时间同步:

1
2
yum install ntpdate -y
ntpdate time.windows.com

1.2 - 安装 Docker

拉取仓库镜像并下载:

1
2
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-18.06.1.ce-3.el7

设置开机自启,启动 Docker:

1
systemctl enable docker && systemctl start docker

查看 Docker 版本,检验是否安装成功:

1
docker --version

输出:Docker version 18.06.1-ce, build e68fc7a

配置 Docker 加速镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": [
    "https://docker.hpcloud.cloud",
    "https://docker.m.daocloud.io",
    "https://docker.unsee.tech",
    "https://docker.1panel.live",
    "http://mirrors.ustc.edu.cn",
    "https://docker.chenby.cn",
    "http://mirror.azure.cn",
    "https://dockerpull.org",
    "https://dockerhub.icu",
    "https://hub.rat.dev"
  ]
}
EOF

重新载入 Docker 守护进程:

1
systemctl daemon-reload

重启 Docker:

1
systemctl restart docker

1.3 - 安装 Kubernetes

添加阿里云 YUM 软件源:

1
2
3
4
5
6
7
8
9
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装 kubeadm,kubelet 和 kubectl。其版本依赖较为严重,务必按照指定版本安装:

1
2
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable kubelet

1.4 - 初始化 Kubernetes 集群

启动 k8s 节点,注意替换 --apiserver-advertise-address= 为主机内网实际 IP 地址,检查 --kubernetes-version 与安装的 Kubernetes 版本是否一致。

1
2
3
4
5
6
kubeadm init \
  --apiserver-advertise-address=192.168.100.242 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.18.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

成功后将得到以下输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 172.31.62.175:6443 --token 9lww95.rz7tw9731n8ixuwq \
    --discovery-token-ca-cert-hash sha256:da2a1c4c361399a45963eb5d147bf3db26fe8451502bf7cb2771363680f3ea51

启用 Kubectl:

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

可以执行 kubectl get nodes 测试主节点是否成功部署 k8s。此时主节点应为 NotReady 状态,需要安装网络插件 flannel。

1
2
NAME     STATUS      ROLES        AGE    VERSION
master   NotReady    master       4h4m   v1.18.0

安装 flannel:

1
2
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

此时执行 kubectl get pods -n kube-system 查看状态,发现 flannel 一直处于 Pending,即拉取状态。这是因为 flannel 默认的镜像仓库在国内无法访问,因此我们需要更改镜像源(具体操作来自这篇文章),将 kube-flannel.yml 文件中 image: 后的镜像替换为以下两个:

  • registry.cn-hangzhou.aliyuncs.com/liuk8s/flannel:v0.21.5
  • registry.cn-hangzhou.aliyuncs.com/liuk8s/flannel-cni-plugin:v1.1.2

执行 kubectl apply -f ,等待片刻,再次执行 kubectl get pods -n kube-system 查看状态,可以发现 flannel 拉取成功,所有进程均为 Running 运行状态:

1
2
3
4
5
6
7
8
9
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-7ff77c879f-p2j58             1/1     Running   0          8d
coredns-7ff77c879f-ttjjv             1/1     Running   0          8d
etcd-k8s-master                      1/1     Running   0          8d
kube-apiserver-k8s-master            1/1     Running   0          8d
kube-controller-manager-k8s-master   1/1     Running   0          8d
kube-proxy-9lj6x                     1/1     Pending   0          18h
kube-proxy-zg66s                     1/1     Running   0          8d
kube-scheduler-k8s-master            1/1     Running   0          8d

执行 kubectl get nodes,主节点为 Ready 状态。

1
2
NAME         STATUS     ROLES        AGE   VERSION
k8s-master   Ready      master       8d    v1.18.0

2 - 边缘服务器

2.1 - 准备环境

关闭防火墙(永久):

1
sudo systemctl disable --now ufw

关闭 selinux(Ubuntu 默认关闭)。可通过以下命令确认关闭:

1
2
sudo apt install -y policycoreutils
sestatus

关闭 swap(永久):

1
sed -ri 's/.*swap.*/#&/' /etc/fstab

根据规划设置主机名:

1
hostnamectl set-hostname node0

添加 /etc/hosts 配置文件:

1
2
3
4
cat >> /etc/hosts << EOF
172.31.62.175 k8s-master
192.168.224.133 node0
EOF

将桥接的 IPv4 流量传递到 IPTABLES 的链:

1
2
3
4
5
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

时间同步:

1
2
apt install ntpdate -y
ntpdate time.windows.com

2.2 - 安装 Docker

离线安装,Docker 版本:18.09.0。

访问 Docker 存档库,下载对应版本的安装包。(树莓派是 arm 架构存档库)

解压:

1
tar xzvf /PATH/TO/FILE.tar.gz

拷贝命令到 /usr/bin 目录下:

1
cp docker/* /usr/bin/

使用 vi /usr/lib/systemd/system/docker.service,写入如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
docker.service

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target

载入 Docker 守护进程:

1
systemctl daemon-reload 

设置开机自启,启动 Docker:

1
systemctl enable docker && systemctl start docker

查看 Docker 版本,检验是否安装成功:

1
docker --version

输出:Docker version 18.09.0, build 4d60db4

配置 Docker 加速镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": [
    "https://docker.hpcloud.cloud",
    "https://docker.m.daocloud.io",
    "https://docker.unsee.tech",
    "https://docker.1panel.live",
    "http://mirrors.ustc.edu.cn",
    "https://docker.chenby.cn",
    "http://mirror.azure.cn",
    "https://dockerpull.org",
    "https://dockerhub.icu",
    "https://hub.rat.dev"
  ]
}
EOF

重新载入 Docker 守护进程:

1
systemctl daemon-reload

重启 Docker:

1
systemctl restart docker

2.3 - 安装 Kubernetes

版本:1.28.2。

安装软件包:

1
apt-get install -y apt-transport-https ca-certificates curl

下载 Kubernetes GPG 密钥:

1
curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg  https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg

将 GPG 密钥添加到 APT 的密钥管理中:

1
cat /usr/share/keyrings/kubernetes-archive-keyring.gpg |  sudo apt-key add -

指定软件仓库位置:

1
echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

更新软件仓库:

1
apt-get update

安装 1.28.2版本:

1
apt-get install -y kubelet=1.28.2-00 kubeadm=1.28.2-00 kubectl=1.28.2-00

锁定版本,防止自动升级:

1
apt-mark hold kubelet kubeadm kubectl

查看版本:

1
2
3
kubelet --version
kubeadm version
kubectl version

设置 Kubelet 开机启动:

1
systemctl enable kubelet

2.4 - 加入 KubeEdge 节点

将 keadm 安装包上传到节点,解压后进入 keadm 文件夹:

1
2
tar -zxvf keadm-v1.6.1-linux-amd64.tar.gz
cd keadm-v1.6.1-linux-amd64/keadm

在执行加入节点命令之前,由于网络原因,需要提前将节点所需的文件放在 /etc/kubeedge 下:

  • crds 文件夹放置在 /etc/kubeedge 下;
  • kubeedge-v1.6.1-linux-amd64.tar.gz 放置在 /etc/kubeedge 下;
  • edgecore.service 放在 /etc/kubeedge 下。

此处我上传了一份已经配置好的 kubeedge 文件夹到云端服务器,因此直接将文件夹从云端拉取到节点即可:

1
scp -r root@8.155.19.255:/home/www/kubeedge /etc

通过 IPTABLES 信息包过滤系统启动云端和边缘端的端口映射(来自郭健博士论文):

1
sudo iptables -t nat -A OUTPUT -d 172.31.62.175 -j DNAT --to-destination 8.155.19.255 # 在边缘端节点

执行加入命令(注意修改主机名称):

1
./keadm join --cloudcore-ipport=172.31.62.175:10000 --edgenode-name=node0 --kubeedge-version=1.6.1 --token=<云端 keadm gettoken 返回的内容>

若部署过程中出现:kubeedge-v1.8.0-linux-amd64.tar.gz in your path checksum failed and do you want to delete this file and try to download again? [y/N]: ,输入 n 即可。

最终页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
kubeedge-v1.6.1-linux-amd64/
kubeedge-v1.6.1-linux-amd64/edge/
kubeedge-v1.6.1-linux-amd64/edge/edgecore
kubeedge-v1.6.1-linux-amd64/cloud/
kubeedge-v1.6.1-linux-amd64/cloud/csidriver/
kubeedge-v1.6.1-linux-amd64/cloud/csidriver/csidriver
kubeedge-v1.6.1-linux-amd64/cloud/admission/
kubeedge-v1.6.1-linux-amd64/cloud/admission/admission
kubeedge-v1.6.1-linux-amd64/cloud/cloudcore/
kubeedge-v1.6.1-linux-amd64/cloud/cloudcore/cloudcore
kubeedge-v1.6.1-linux-amd64/version

KubeEdge edgecore is running, For logs visit: journalctl -u edgecore.service -b

在云端执行 kubectl get nodes,输出如下:

1
2
3
4
5
6
[root@k8s-master ~]# kubectl get node
NAME         STATUS     ROLES        AGE    VERSION
k8s-master   Ready      master       108d   v1.18.0
node         Ready      agent,edge   13d    v1.19.3-kubeedge-v1.6.1
node0        Ready      agent,edge   13d    v1.19.3-kubeedge-v1.6.1
node1        Ready      agent,edge   13d    v1.19.3-kubeedge-v1.6.1

附 - 重置节点

可能因为各种原因,导致需要重新部署集群。在 node 节点上执行:

1
kubeadm reset

过程会询问是否重置,输入 y 回车确认。

1
2
3
4
5
systemctl stop edgecore
rm -rf /root/.kube
rm -rf /etc/cni/net.d
rm -rf /etc/kubernetes/*
rm /etc/systemd/system/edgecore.service

在 master 节点上删除 node 节点的指令:

1
kubectl delete node <node-name>
本文由作者按照 CC BY 4.0 进行授权