背景
下面我将以这个思维导图来总结一下CRI。
简介
容器运行时(Container Runtime),运行于k8s集群的每个节点中,负责容器的整个生命周期。其中 Docker 是目前应用最广的。
为了解决这些容器运行时和k8s的集成问题,在k8s 1.5版本中,社区推出了 CRI (Container Runtime Interface,容器运行时接口)以支持更多的容器运行时。
分类
CRI是k8s定义的一组 gRPC 服务。kubelet 作为客户端,基于 gRPC 框架,通过 Socket 和容器运行时通信。
它包括两类服务:镜像服务(Image Service)和运行时服务(Runtime Service)。镜像服务提供下载、检查和删除镜像的远程程序调用。运行时服务包含用于管理容器生命周期,以及与容器交互的调用(exec / attach / port-forward等)
可以看到RuntimeService中包括了容器等一些基本操作,同时也包括了sandbox的一些操作。
运行时的层级
高层级运行时
Dockershim, containerd 和 CRI-O 都是遵循 CRI 的容器运行时,称之为高层级运行时(High-level Runtime)。
低层级运行时
OCI (Open Container Initiative,开放容器计划)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范(Image Specification)和运行时规范(Runtime Specification)。
镜像规范定义了 OCI 镜像的标准。高层级运行时将会下载一个 OCI 镜像,并把它解压成 OCI 运行时文件系统包 (filesystem bundle)
运行时规范则描述了如何从 OCI 运行时文件系统包运行容器程序,并且定义它的配置、运行环境和生命周期。如何为新容器设置namepsaces和cgroup,以及挂载根文件系统等等操作。它的一个参考实现是 runC。我们称其为 低层级运行时(Low-levelRuntime)。除runC 以外,也有很多其他的运行时遵循 OCI 标准,例如 kata-runtime。
docker和containerd
对比
Docker 内部关于容器运行时功能的核心组件是 containerd,现在containerd 也可直接和 kubelet 通过 CRI 对接,独立在 Kubernetes 中使用。
相对于 Docker 而言,containerd 减少了 Docker 所需的处理模块 Dockerd 和 Docker-shim,并且对Docker 支持的存储驱动进行了优化,因此在容器的创建启动停止和删除,以及对镜像的拉取上,都具有性能上的优势。运维更方便。
当然 Docker 也具有很多 containerd 不具有的功能,例如支持
zfs 存储驱动,支持对日志的大小和文件限制,在以 overlayfs2 做存储驱动的情况下,可以通过xfs_quota 来对容器的可写层进行大小限制等。
下图中只要红框内是真正的调用链。其他比如docker-cli,storage,network都是docker附加的。
containerd和cri-o对比
功能性来讲,containerd 和 CRI-O都符合 CRI 和 OCI 的标准;
在稳定性上,containerd略胜一筹;
从性能上讲,containerd 胜出。
docker切换到containerd
安装containrd
yum -y install containerd
停止服务
systemctl stop kubelet
systemctl stop docker
systemctl stop containerd
生成containerd默认配置文件
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
更改配置文件
vi /etc/containerd/config.toml
# 这里注意看你的k8s.gcr.io/pause镜像版本是不是3.5,如果不是的话要做修改
sed -i s#k8s.gcr.io/pause:3.5#registry.aliyuncs.com/google_containers/pause:3.5#g /etc/containerd/config.toml
sed -i s#'SystemdCgroup = false'#'SystemdCgroup = true'#g /etc/containerd/config.toml
修改kubelet配置
指定运行时为remote即containerd,pause镜像版本。
vim /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5"
重启服务
systemctl daemon-reload
systemctl restart containerd
systemctl restart kubelet
查看服务状态
查看pod状态
迁移成功