k8s containerd
ddatsh
“寄生”在 kubelet 中的 dockershim
rkt 和 docker 争霸时,kubelet 需维护两坨代码分别适配运行时组件,严重拖慢新版本发布速度
SIG-Node 提出 CRI(Container Runtime Interface)让kubelet可以适配所有的运行时
Docker 当时并没有(也不打算)实现这组接口, kubelet 只能在内部维护 “dockershim”组件充当 docker 的 CRI 转接器,kubelet 创建容器时通过 CRI 接口调用 dockershim ,而 dockershim 再通过 http 请求把请求交给 docker 。 kubelet 架构变成下图
kubelet 创建容器调用链
- 实现了 CRI 接口的组件作为容器运行时,红色箭头,ContainerManager 直接通过 CRI 调用到容器运行时,一次 grpc 请求
- 使用 docker 时,ContainerManager 走蓝色调用链, CRI 请求通过 unix:///var/run/dockershim.sock 流向 dockershim,dockershim 做转换后把请求转发给 docker
kubelet 中实现 docker 转接器本来就是一种不优雅的实现,让调用链变长且不稳定性,还给 kubelet 的维护添加了额外工作
在 Pod 中使用 DinD(Docker in Docker)
docker 的 socket (/run/docker.sock) 挂载到 Pod 中,并在 Pod 中调用 docker 的 api 构建镜像或创建编译容器等
Kaniko、Img 或 Buildah。把 docker daemon 作为 DaemonSet 或者给想要使用 docker 的 Pod 添加一个 docker daemon 的 sidecar 的方式在任意运行时中使用 DinD 方案
containerd
2016 年docker 把负责容器生命周期的模块拆分出containerd捐给社区
docker 拆分后结构(docker 公司添加了部分编排代码)
调用 docker 命令创建容器后
-
docker daemon 通过 Image 模块下载镜像并保存到 Graph Driver 模块中
-
之后通过 client 调用 containerd 创建并运行容器
-
可能
--volume
给容器添加持久化存储(Storage 模块) -
可能
--network
连接用 docker 命令创建的几个容器(Networking 模块)
K8s 提供了更强的卷挂载和集群级别的网络能力,在集群中 kubelet 只会用到 docker 提供的镜像下载和容器管理功能,而编排、网络、存储等功能都不会用到
kubelet 创建 Pod 时赖的几个运行时模块
containerd 捐赠给 CNCF 社区后,社区添加了镜像管理模块和 CRI 模块后,除管理容器的生命周期,还可直接作为 K8s 的运行时使用,2019 年 2 月从 CNCF 社区毕业,正式进入生产环境
containerd 作为容器运行时,给 kubelet 带来创建 Pod 所需的全部功能,同时得到更纯粹的功能模块以及更短的调用链
containerd 以成为简单、稳定且可靠的容器运行时为目标
docker 希望能成为一个完整的产品(交互,使用体验及更多的功能),同时为了给 swarm 做基础,提供了网络和卷的功能,K8s 用不上
一定程度上讲,即使在 kubelet 1.23 版本之后 docker 提供了 CRI 接口,containerd 仍然是更好的选择
https://www.cnblogs.com/tencent-cloud-native/p/14134164.html