使用 kubeadm 安装 kubernetes 集群
使用 kubeadm 安装 kubernetes 集群
对于需要学习 kubernetes 的同学来说,必须需要先学会如何搭建一个学习环境(即 kubernetes 集群),然后才能学习更多相关 kubernetes 及云原生的知识。目前随着社区的不断发展,kubernetes 的搭建已经非常方便,有基于 minikube/kind 等工具搭建的单节点集群,其搭建速度非常快(除去拉去镜像的时间,集群本身的搭建时间在分钟级别以内就能完成),但是单节点的 kubernetes 集群只能在本地学习的时候使用,没法部署到线上环境且也不支持多个节点的部署。而 kubeadm 正好为多个节点的 kubernetes 集群的搭建提供了工具,且能使用在大规模的生产环境中进行集群的搭建和部署。kubeadm 提供了简单便捷的方式来安装 kubernetes 集群,用户只需要使用 kubeadm 提供的简单命令来管理集群,如:
- kubeadm init 命令用来初始化一个集群
- kubeadm join 命令用来给已有的一个集群添加新的节点
- kubeadm reset 命令用来给已有的集群做重置操作,相当于删出一个已有集群,注意这个操作会将已有集群中的相关配置全部删除,请谨慎操作!!
下面的实操将以 kubeadm 来安装一个多个节点的 kubernetes 集群。kubeadm 的工作流程可参考:https://www.jianshu.com/p/029465088933
部署环境
本次部署环境在 ubuntu 系统上进行操作,系统版本为 22.04 版本。
必要条件:
- master 节点:必须提供至少 2C CPU 和 8GiB 的内存资源。
- node 节点:必须提供至少 1C CPU 和 1GiB 的内存资源。
安装步骤
初始化操作(所有节点都必须要执行)
所有的节点都必须执行下面脚本,才能安装成功。注意如下脚本都需要在 root 账户下运行。
关闭系统服务
在节点上创建文件 init.sh 脚本,将如下代码拷贝到 init.sh 里面执行初始化操作。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#!/bin/bash
echo "修改DNS配置如有需要"
chattr -i /etc/resolv.conf
cat <<EOF >> /etc/resolv.conf
nameserver 10.10.10.10 # 改成自己需要的
nameserver 10.10.10.11 # 改成自己需要的
EOF
### 关闭swap分区
echo "swapoff ## 临时生效"
swapoff -a
## 永久生效可以编辑/etc/fstab文件 注释掉swap那行 https://www.idceval.com/111.html
sed -ri 's/.*swap.*/#&/' /etc/fstab
echo "关闭防火墙"
ufw disable
echo "关闭selinux"
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config安装必要的软件
在节点上创建文件 run.sh 脚本,将如下代码拷贝到 run.sh 里面执行安装必须的软件,如 docker、kubelet、kubeadm、kubectl 等工具。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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#!/bin/bash
sudo apt update -y && sudo apt upgrade -y
sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable docker.service
systemctl start docker.service
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# Apply sysctl params without reboot
sudo sysctl --system
lsmod | grep br_netfilter
lsmod | grep overlay
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# containerd config
rm -rf /etc/containerd/config.toml
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl daemon-reload && systemctl restart containerd
master 节点上搭建集群
部署服务
在一个 master 节点上创建新的 kubernetes 集群,部署服务之前请确保 初始化操作 都已完成。
修改节点hostname,方便统一管理。
1
hostnamectl set-hostname k8s-master-01
在 master 节点上通过 kube init 命令创建集群。
1
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16 --kubernetes-version stable
拷贝kube/config文件 这样在当前节点可以执行 kubectl指令。
1
2
3mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config在master 节点上安装网络组件。
1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
查看服务是否正常
1
kubectl get pods --all-namespaces
安装过程中遇到的问题
- 由于 kubeadm 要在多个几节点创建集群,集群内 pod 之间的通信需要通过 kubernetes 的cni plugin 来提供,因此需要选择合适的 cni 插件来初始化集群,通过 –pod-network-cidr 参数来指定 pod 的网段。此处选择使用 flannel 网络插件,其他的可参考。
- 由于 kubeadm 初始化时,docker 默认选择 registry.k8s.io 镜像仓库拉取镜像,这个仓库对国内环境不可访问,因此可以指定默认仓库为阿里云的镜像仓库。
- 经过上述两步操作后,集群搭建可能会成功,如果仍报 “registry.k8s.io/pause:3.6” 错误,是因为 kubelet 在创建容器时会去默认仓库(sandbox_image = “registry.k8s.io)拉取镜像,需要将 containerd 中的默认仓库地址修改为阿里云的地址(sandbox_image = “registry.aliyuncs.com/google_containers/pause:3.9”),可参考。
- 解决网络问题及默认仓库后,服务不一定正常启动,碰到的问题可参考,其主要原因是 kubelet 使用 etcd 的静态文件(/etc/kubernetes/manifests)创建静态 pod 的时候会失败,导致集群的 kube-apiserver、kube-controller-manager 等组件一直重启,可以使用
crictl ps -a
和crictl logs
查看相关容器的日志。最终的原因是 ectd 服务不断重启是由于 containerd 中的/etc/containerd/config.toml
文件配置不正确,需要将文件中的SystemdCgroup = false
改为SystemdCgroup = true
,再执行systemctl restart containerd.service
重启 containerd 服务。
添加新的 master 到集群
添加新 master 节点到 kubernetes 集群之前请确保 初始化操作 都已完成,可参考。
修改节点hostname,方便统一管理。
1
hostnamectl set-hostname k8s-master-01
在集群的 master 节点中执行如下命令,获取添加 node 的命令。
1
kubeadm token create --print-join-command
然后,再在 node 节点上执行上述获取的命令,即可将新 node 添加到集群中
在 master上生成用于新 master 加入的证书
1
kubeadm init phase upload-certs --experimental-upload-certs
添加新 master,把新生成的 certificate key 加到 –experimental-control-plane –certificate-key 参数后,执行如下命令:
1
kubeadm join {apiserver-IP:Port} --token {token-key} --discovery-token-ca-cert-hash {ca-cert-key} --experimental-control-plane --certificate-key {certificate-key}
添加新 node 节点到集群
添加新节点到 kubernetes 集群之前请确保 初始化操作 都已完成。
修改节点hostname,方便统一管理。
1
hostnamectl set-hostname k8s-node-01
在集群的 master 节点中执行如下命令,获取添加 node 的命令。
1
kubeadm token create --print-join-command
再在 node 节点上执行上述获取的命令,即可将新 node 添加到集群中:
1
kubeadm join {apiserver-IP:Port} --token {token-key} --discovery-token-ca-cert-hash {ca-cert-key}
卸载集群
驱逐 master/node 上的所有 pod 以及服务。
1
kubectl drain <node_name> --ignore-daemonsets
将 node 节点从集群中剔除出去
1
kubectl delete node <worker node name>
执行清理工作,会删除 /etc/kubernetes 中的所有文件
1
kubeadm reset -f
删除网络插件中的数据
1
rm /etc/cni/net.d/* -rf
参考:
- https://medium.com/@arbnair97/how-to-create-a-kubernetes-cluster-using-kubeadm-in-ubuntu-3e6e475e1252
- https://developer.aliyun.com/article/791138
- https://blog.csdn.net/weixin_43144516/article/details/118445728
- https://www.cnblogs.com/helong-123/p/15637122.html
- https://blog.csdn.net/ldjjbzh626/article/details/128400797
- https://www.cnblogs.com/-ori/p/16971368.html
- https://cloud.tencent.com/developer/article/2170756
- https://www.idceval.com/111.html