我的集群如下
1、使用kubectl cordon命令将k8sn01设置为不可调度。这个名称就是你NAME那一列的名字。新创建的 Pod 就不会调度到当前节点上来。
kubectl cordon k8sn01
2、先维护k8sn01,使用 kubectl drain
命令来维护节点并驱逐节点上的 Pod。
kubectl drain k8sn01 --ignore-daemonsets
#--ignore-daemonsets 参数可以用来忽略 DaemonSet 控制器管理的 Pod,因为这些Pod不用驱逐到其他节点去。
#需要注意的是如果这机器上有pod是其他状态的话会驱逐失败,此命令会一直卡在终端。如:Terminating状态等。。。
此时k8sn01上的pod已经被驱逐到k8sn02上了,可以用如下命令查看。
kubectl get pod -nweb -owide
3、开始更换容器运行时。节点配置、升级内核等操作的时候都可以先将节点进行驱逐,然后再进行维护。
停掉 docker、containerd 和 kubelet ,千万小心,不要停错节点了。
systemctl stop kubelet
systemctl stop docker
systemctl stop containerd
containerd config default > /etc/containerd/config.toml #生成配置
vim config.toml
修改默认的 pause 镜像为国内的地址
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/k8sxio/pause:3.5"
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["阿里云自己的加速地址"]
修改 kubelet 配置,将容器运行时配置为 containerd
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
//配置中我们增加了两个参数,--container-runtime 参数是用来指定使用的容器运行时的,可选值为 docker 或者 remote,默认是 docker,由于我们这里使用的是 containerd 这种容器运行时,所以配置为 remote 值(也就是除 docker 之外的容器运行时都应该指定为 remote),然后第二个参数 --container-runtime-endpoint 是用来指定远程的运行时服务的 endpiont 地址的,在 Linux 系统中一般都是使用 unix 套接字的形式,比如这里我们就是指定连接 containerd 的套接字地址 unix:///run/containerd/containerd.sock。
//其实还应该配置一个 --image-service-endpoint 参数用来指定远程 CRI 的镜像服务地址,如果没有指定则默认使用 --container-runtime-endpoint 的值了,因为 CRI 都会实现容器和镜像服务的。
重启服务
systemctl daemon-reload
systemctl restart containerd
systemctl restart kubelet
查看节点,可以看见下图我的k8sn01的运行时已经变成了containerd
4、把 k8sn01 节点重新加回到集群中来允许调度 Pod 资源
kubectl uncordon k8sn01
其它节点操作都一样