如何切换容器运行时为containerd

为何要弃用Docker


https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md

在Kuberntes平台中,为了解决与容器运行时(例如Docker)集成问题,在早期社区推出CRI(Container Runtime Interface,容器运行时接口),以支持更多的容器运行时。而Docker本身并不支持CRI(容器运行时接口)这一Kubernetes运行时API,Kubernetes用户一直以来所使用的其实是名为“dockershim”的桥接服务。Dockershim能够转换Docker API与CRI,但在后续版本当中,Kubernetes将不再提供这项桥接服务。

Kubernetes计划弃用的其实是kubelet中的dockershim模块,为什么这么做呢?我们先看当使用Docker作为容器运行时之后,调用链是这样的。

kubelet-->CRI(dockershim)-->dockerd)-->containered)-->shim)-->runc)-->container

这样会有以下几个问题,因此Kuberntes决定弃用Docker

  1. 调用链比较复杂,多层封装和调用,导致性能降低、提升故障率不易排查
  2. Docker network和Docker volume并不在Kubernetes需要的功能中,这些用不到的功能本身可能带来安全隐患
  3. Kubernetes需要花费精力维护dockershim这个模块

如何应对?


在未来的Kubernetes版本彻底放弃Docker支持之前,需要引入受支持的容器运行时。

除了Docker之外,CRI还支持很多容器运行时

容器运行时 说明
containerd containered与Docker相兼容,相比Docker轻量很多,目前较为成熟
cri-o/podman 都是红帽(RedHat)项目,目前红帽主推podman

如何切换容器运行时为containered


关闭Docker和kubelet

1
2
3
systemctl stop kubelet
systemctl stop docker.socket
systemctl stop docker

配置先决条件

加载overlaybr_netfilter模块

1
2
3
4
5
6
7
cat << EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

配置内核参数

1
2
3
4
5
6
7
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

sudo sysctl --system

安装containerd

从官方Docker仓库安装containerd.io软件包,以下以CentOS为例

说明
可以在安装Docker引擎中找到为各种Linux发行版设置Docker存储库和安装containerd.io软件包的说明。

1
2
3
4
5
yum install yum-utils device-mapper-persistent-data lvm2 -y
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install containerd.io -y

创建containerd默认配置文件

1
2
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

启动containerd

1
systemctl start containerd

修改containerd配置文件

编辑/etc/containerd/config.toml文件,修改以下三个配置

配置说明

  • sandbox_image:配置pause容器镜像Tag
  • SystemdCgroup:配置containerd是否使用systemd cgroup驱动
  • endpoint:配置镜像加速器地址,在新版containerd中可能搜不到,可忽略不配置
1
2
3
4
5
6
7
8
9
10
...
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2"
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
...
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://lerc8rqe.mirror.aliyuncs.com"]
...

重启containerd使配置生效

1
systemctl restart containerd

配置kubelet使用containerd

编辑/etc/sysconfig/kubelet文件,添加以下内容

1
KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd

重启kubelet使配置生效

1
systemctl restart kubelet

验证

执行以下命令确认对应node节点CONTAINER-RUNTIME列是否是containerd://x.x.x

1
kubectl get node -o wide

cri-tools管理工具


将容器运行时切换为containerd后,就无法再通过docker命令进行查看镜像和容器等操作,那么通过什么进行管理呢,这就需要通过crictl了。crictl为CRI兼容的容器运行时提供了一个CLI,这允许CRI运行时开发人员无需设置Kubernetes组件就可以调试他们的运行时。

安装crictl

critools发布页面下载与Kubernetes版本对应的crictl压缩包,本文以Kubernetes v1.20.0和amd64为例

说明
要下载对应体系构架的哦~

1
2
3
4
5
6
7
8
9
10
11
# 使用wget下载安装
VERSION="v1.20.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz

# 使用curl下载安装
VERSION="v1.20.0"
curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz

配置crictl

编辑/etc/crictl.yaml文件配置crictl连接containerd

1
2
3
4
5
6
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
disable-pull-on-run: false

验证

1
2
crictl image ls
crictl ps

更多crictl用法可参考命名帮助或官方文档

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
# crictl --help
NAME:
crictl - client for CRI

USAGE:
crictl [global options] command [command options] [arguments...]

VERSION:
v1.20.0

COMMANDS:
attach Attach to a running container
create Create a new container
exec Run a command in a running container
version Display runtime version information
images, image, img List images
inspect Display the status of one or more containers
inspecti Return the status of one or more images
imagefsinfo Return image filesystem info
inspectp Display the status of one or more pods
logs Fetch the logs of a container
port-forward Forward local port to a pod
ps List containers
pull Pull an image from a registry
run Run a new container inside a sandbox
runp Run a new pod
rm Remove one or more containers
rmi Remove one or more images
rmp Remove one or more pods
pods List pods
start Start one or more created containers
info Display information of the container runtime
stop Stop one or more running containers
stopp Stop one or more running pods
update Update one or more running containers
config Get and set crictl client configuration options
stats List container(s) resource usage statistics
completion Output shell completion code
help, h Shows a list of commands or help for one command

GLOBAL OPTIONS:
--config value, -c value Location of the client config file. If not specified and the default does not exist, the program's directory is searched as well (default: "/etc/crictl.yaml") [$CRI_CONFIG_FILE]
--debug, -D Enable debug mode (default: false)
--image-endpoint value, -i value Endpoint of CRI image manager service (default: uses 'runtime-endpoint' setting) [$IMAGE_SERVICE_ENDPOINT]
--runtime-endpoint value, -r value Endpoint of CRI container runtime service (default: uses in order the first successful one of [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock]). Default is now deprecated and the endpoint should be set instead. [$CONTAINER_RUNTIME_ENDPOINT]
--timeout value, -t value Timeout of connecting to the server in seconds (e.g. 2s, 20s.). 0 or less is set to default (default: 2s)
--help, -h show help (default: false)
--version, -v print the version (default: false)

参考文档