赞
踩
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
swapoff -a #临时
#永久
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
#or vim /etc/fsta,注释swap这一行
/swap.img none swap sw 0 0
#reboot后永久生效
虚拟机默认关闭了防火墙,没关闭的执行以下命令:
systemctl stop firewalld
systemctl disable firewalld
ufw status
ubuntu:默认没开启
centos:
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl restart rsyslog
192.168.64.3 k8s-master
192.168.64.4 k8s-node1
192.168.64.5 k8s-node2
已经安装过docker的,containerd.io包含了containerd和runc,但不包含 CNI 插件。按此步骤安装CNI插件。
没有安装过docker的,按此步骤安装containerd、runc、CNI插件。
注意: 很多教程因为使用的是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
通过运行 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
有条件的可按此步骤直接通过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
为了避免不必要的错误,以上操作在所有节点都执行。
以下操作在 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
如果此时使用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
如果无法访问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。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml
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
在从节点 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 kubelet
和journalctl -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
操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。