k8s☞02-1切换使用runtime-containerd

阅读量: zyh 2020-08-25 18:17:44
Categories: > Tags:

基础

需要注意的是,替换runtime,需要重新下载镜像。这会严重的加大Pod的恢复时间。

特别是在国内,一些镜像因为某些不可描述的原因,可能会无法下载成功。

另外,虽然镜像一样,但是containerd无法去找到docker本地的镜像缓存。至少我还没找到解决方式。。。

配置必要系统环境

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

sudo modprobe overlay
sudo modprobe br_netfilter

# Setup required sysctl params, these persist across reboots.
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

安装

containerd可以从docker源中获取

# add repo
yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# install
yum install containerd.io
# modify containerd config
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

修正配置/etc/containerd/config.toml,更改存储根路径

root=""

修正配置/etc/containerd/config.toml,使用 systemd cgroup driver

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

修正配置/etc/containerd/config.toml,使用国内163镜像源

    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = ["http://hub-mirror.c.163.com","https://registry-1.docker.io"]

更改runtime

当使用kubeadm安装集群的时候:

配置选项可以参考https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration

启动参数可以参考 https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/

我们需要将kubelet的runtime变更为containerd

# 手动追加runtime参数到kubelet配置:/var/lib/kubelet/kubeadm-flags.env
--cgroup-driver=systemd --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock

安装客户端工具crictl

https://kubernetes.io/zh/docs/tasks/debug-application-cluster/crictl/

wget 'https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.22.0/crictl-v1.22.0-linux-amd64.tar.gz'
tar xf crictl-*.tar.gz
cp crictl /usr/local/bin/

配置客户端工具

vim /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: true

endpoint的地址根据选用的runtime指定,不出意外应该是下面三个:

查看当前k8s所用的镜像版本

docker images | grep k8s.gcr.io
k8s.gcr.io/kube-apiserver:v1.22.4
k8s.gcr.io/kube-controller-manager:v1.22.4
k8s.gcr.io/kube-scheduler:v1.22.4
k8s.gcr.io/kube-proxy:v1.22.4
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4

✨当然,不仅仅有k8s自身镜像,还有其它部署的镜像。

拉取镜像到containerd本地库

根据上面的指令填充

full_version=1.22.4
cat>crictl-pull-images.sh<<EOF
#!/bin/bash
# kubeadm config images list
images=(
kube-apiserver:v${full_version}
kube-controller-manager:v${full_version}
kube-scheduler:v${full_version}
kube-proxy:v${full_version}
pause:3.5
etcd:3.5.0-0
coredns:1.8.4
)
for imageName in \${images[@]};
do
    crictl pull registry.aliyuncs.com/google_containers/\${imageName}
    ctr --namespace k8s.io images tag registry.aliyuncs.com/google_containers/\${imageName} k8s.gcr.io/\${imageName}
done
EOF

保存先不执行脚本。

ctr -n k8s.io 指定位于k8s.io命名空间的镜像

逐个更新

💥千万不能docker和containerd同时启动

# nodeName 
nodeName=k8s01
# 驱逐node
kubectl drain ${nodeName} --ignore-daemonsets
# 校验是否只有 daemonsets pod
kubectl get all --all-namespaces -o wide| grep ${nodeName}
# 关闭kubelet
systemctl stop kubelet
# 关闭runtime
systemctl stop docker && systemctl disable docker

确保节点上异常的信息,在本文档实施过程中,出现 docker 和 kubelet 关闭的情况下,容器进行依然运行占用端口,导致containerd启动的时候无法正常运行Pod.

# 检查是否有异常端口
ss -tnalp
# 启动 containerd
systemctl start containerd && systemctl enable containerd && systemctl stop kubelet
# 执行拉取容器镜像的脚本
bash crictl-pull-images.sh
# 启动 kubelet
systemctl restart kubelet
# 恢复 node
kubectl uncordon ${nodeName}