使用kubeadm(v1.25.0)安装Kubernetes集群

2022.08.23,Kubernetes v1.25新版本发布啦!

很多Kubernetes的安装教程都已经老旧了,版本不一致的教程会让你多走很多弯路,想安装最新版本(v1.25.0)Kubernetes集群的客观请往下看。

本文容器运行时使用的是:containerd,注意不是Docker Engine。

说明:

v1.24 之前的 Kubernetes 版本直接集成了 Docker Engine 的一个组件,名为 dockershim
这种特殊的直接整合不再是 Kubernetes 的一部分 (这次删除被作为 v1.20
发行版本的一部分宣布)。

所以这里v1.25使用containerd作为容器运行时。


环境准备及说明:

服务器准备:

Centos和Ubuntu都可以,某些细节上会有略微区别,文章中会注明。

我的环境:Ubuntu(20.04)。使用Mulitpass构建了三台ubuntu系统的虚拟机。

blueMac:~ blue$ multipass list
Name                    State             IPv4             Image
k8s-master              Running           192.168.64.3     Ubuntu 20.04 LTS
k8s-node1               Running           192.168.64.4     Ubuntu 20.04 LTS
k8s-node2               Running           192.168.64.5     Ubuntu 20.04 LTS

macOS下Multipass搭建ubuntu 20.04虚拟机请参考这篇文章:
https://blog.csdn.net/qq_34628724/article/details/126872890

ubuntu 20.04安装docker 20.10.18请参考这篇文章:

https://blog.csdn.net/qq_34628724/article/details/126873666


前置操作:

1. 禁用交换分区
swapoff -a #临时

#永久
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
#or vim /etc/fsta,注释swap这一行
/swap.img	none	swap	sw	0	0
#reboot后永久生效
2. 关闭防火墙

虚拟机默认关闭了防火墙,没关闭的执行以下命令:

systemctl stop firewalld
systemctl disable firewalld
ufw status
3. 禁用SELinux

ubuntu:默认没开启

centos:

setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
4. 设置时区
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl restart rsyslog
5. hosts设置
192.168.64.3 k8s-master
192.168.64.4 k8s-node1
192.168.64.5 k8s-node2
6. 安装containerd

已经安装过docker的,containerd.io包含了containerd和runc,但不包含 CNI 插件。按此步骤安装CNI插件。

没有安装过docker的,按此步骤安装containerd、runc、CNI插件。

7. 修改cgroupfs 驱动

注意: 很多教程因为使用的是docker,所以会修改docker的cgroup驱动为systemd,如下:

#修改docker-driver vim /etc/docker/daemon.json , 新增以下行
    "exec-opts": ["native.cgroupdriver=systemd"],
#重启docker
systemctl daemon-reload
systemctl restart docker

但是:我们用的是containerd,按如下方式修改cgroup驱动,同时把自定义镜像重载沙箱镜像一并修改了:

mv /etc/containerd/config.toml /etc/containerd/config.toml.orig #备份
containerd config default > /etc/containerd/config.toml #生成默认配置文件
# vim /etc/containerd/config.toml,如下修改对应行
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            ......
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = true # 将false改为true
            
[plugins."io.containerd.tracing.processor.v1.otlp"]
    endpoint = "https://docker.mirrors.ustc.edu.cn/" #改成中科大镜像源,可按需修改成阿里、华为等镜像源
    insecure = false
    protocol = ""
    
[plugins."io.containerd.grpc.v1.cri"]
    netns_mounts_under_state_dir = false
    restrict_oom_score_adj = false
    #sandbox_image = "k8s.gcr.io/pause:3.6"
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8" # 修改成这样

#重启containerd
systemctl daemon-reload 
systemctl restart containerd
8. 转发 IPv4 并让 iptables 看到桥接流量

通过运行 lsmod | grep br_netfilter 来验证 br_netfilter 模块是否已加载。

若要显式加载此模块,请运行 sudo modprobe br_netfilter

为了让 Linux 节点的 iptables 能够正确查看桥接流量,请确认 sysctl 配置中的 net.bridge.bridge-nf-call-iptables 设置为 1。

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
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

# 应用 sysctl 参数而不重新启动
sudo sysctl --system
9. 安装kubelet、kubeadm、kubectl

有条件的可按此步骤直接通过Google Cloud下载安装。
国内用户通过阿里云的源下载安装工具包:

#更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
#下载 Google Cloud 公开签名秘钥(用阿里云替换)
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - 
sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
#下载并锁定版本
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
#设置kubelet开机启动
systemctl daemon-reload
systemctl enable kubelet && systemctl start kubelet
#如果有需要安装指定版本的,也一起附上命令
apt-get install -y kubelet=1.23.5-00 kubeadm=1.23.5-00 kubectl=1.23.5-00

为了避免不必要的错误,以上操作在所有节点都执行。


使用 kubeadm 创建集群

生成默认配置文件:

以下操作在 k8s-master 节点执行。

kubeadm config print init-defaults > kubeadm.yaml

需要修改一些参数,附上我的kubeadm.yaml

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.64.3	#修改为master的ip
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: k8s-master #修改为master节点的hostname
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers	#修改为阿里云镜像源
kind: ClusterConfiguration
kubernetesVersion: 1.25.0 #可以指定版本
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/12	#指定service和pod的子网络地址,根据需要自行修改
scheduler: {}

关于镜像下载:

注意:不需要手动去一个一个镜像下载然后替换tag,也不用写成shell脚本,如下执行即可:

#可以提前下载镜像,避免init初始化时漫长的等待
#查看所需镜像及版本
kubeadm config images list
#下载镜像
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers

关于kubelet:

如果此时使用systemctl status kubelet会发现kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环,无需在意,control-plane启动好了就正常了。

**注意:**很多教程会让你修改kubelet的Cgroup驱动,比如:

修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf文件,在KUBELET_KUBECONFIG_ARGS尾部增加--cgroup-driver=cgroupfs;或者是修改/var/lib/kubelet/kubeadm-flags.env,在KUBELET_KUBECONFIG_ARGS尾部增加--cgroup-driver=systemd

**但是:**我们不需要。在版本 1.22 中,如果用户没有在 KubeletConfiguration 中设置 cgroupDriver 字段, kubeadm init 会将它设置为默认值 systemd。v1.22版本以上应该也是如此,如果不放心,我们也可以显示的设置systemd

# kubeadm.yaml增加以下内容:
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd

开始初始化:

kubeadm init --config kubeadm.yaml

这是一个漫长的过程,取决于你的网络状况,一开始会先下载所需镜像,可以启动另一个窗口,crictl images可以看到陆续在下载所需的镜像,也可以按上面步骤提前下载再进行初始化,速度会快很多。

成功后出现如下内容:

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

Alternatively, if you are the root user, you can run: #root用户执行这个

  export KUBECONFIG=/etc/kubernetes/admin.conf

......

Then you can join any number of worker nodes by running the following on each as root: #重点:记住这个命令

kubeadm join 192.168.64.3:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:5483215764fb45bc4f86325a2bd90326e51a37a2637275a0e3bf77e0d30c6263

kubeadm启动master:



#默认情况下,出于安全考虑,你的集群不会在master(控制面节点)上部署Pod。如果你想在控制面节点上部署Pod,执行:
kubectl taint nodes --all node-role.kubernetes.io/master-
#将 Master 恢复成 Master Only 状态
kubectl taint nodes <node-name> node-role.kubernetes.io/master=:NoSchedule

配置pod网络

如果无法访问raw.githubusercontent.com,先配置hosts,增加如下(可能会变更,可通过https://www.ipaddress.com/查看):

140.82.113.3 github.com
185.199.108.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com

这里使用calico网络插件,附上官网,我们安装的是最新版v3.24。

安装 Tigera Calico:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml

安装 Calico:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml

确认所有 pod 都在运行:

watch kubectl get pods -n calico-system

控制平面节点隔离:

如果出现master无法部署pod的情况,查看taint并删除:

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

成功则提示:node/k8s-master untainted

**注意:**默认情况下,出于安全原因,你的集群不会在控制平面节点上调度 Pod。很多教程里写的是kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-,注意这个node-role.kubernetes.io/master-在v1.25中已经被弃用了,所以我们把这个选项去掉,否则命令执行会报错error: taint "node-role.kubernetes.io/master" not found

如何将 Master 恢复成 Master Only 状态:

kubectl taint nodes <node-name> node-role.kubernetes.io/master=:NoSchedule

使用以下命令确认您现在在集群中有一个节点:

此时我们的master节点从NotReady变成Ready了!下一步,添加worker节点。

# kubectl get nodes -o wide
NAME         STATUS   ROLES           AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-master   Ready    control-plane   3h33m   v1.25.0   192.168.64.3   <none>        Ubuntu 20.04.4 LTS   5.4.0-125-generic   containerd://1.6.8

添加worker节点:

在从节点 k8s-node1、k8s-node2 执行:

kubeadm join 192.168.64.3:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:5483215764fb45bc4f86325a2bd90326e51a37a2637275a0e3bf77e0d30c6263 --v=5

此时执行kubectl get nodes可以看到三个节点都已经变成Ready状态了!

NAME         STATUS   ROLES           AGE     VERSION
k8s-master   Ready    control-plane   9h      v1.25.0
k8s-node1    Ready    <none>          5h50m   v1.25.0
k8s-node2    Ready    <none>          5h43m   v1.25.0

关于报错:

如果遇到这种报错:

Unfortunately, an error has occurred:
	timed out waiting for the condition

This error is likely caused by:
	- The kubelet is not running
	- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
	- 'systemctl status kubelet'
	- 'journalctl -xeu kubelet'

注意查看systemctl status kubeletjournalctl -xeu kubelet的输出,里面隐藏了报错原因。

如果出现“network”之类的error,那问题大概率是pod网络配置出现问题。

如果出现“cgroup”之类的error,那有可能是containerd和kubelet的cgroup driver不一致

如果出现镜像pull之类的error,那可能是网络问题导致镜像拉取不下来,比如 sandbox_image 的镜像默认是从这这 k8s.gcr.io/pause:3.6 拉取的。

报错后需执行kubeadm reset进行环境清理,然后再重新执行kubeadm init操作。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值