点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
关注公众号后台回复pay或mall获取实战项目资料+视频作者 | Kohei Ota 译者 | 核子可乐
策划 | 万佳 来源:架构头条
什么?Kubernetes 决定弃用 Docker?
这是真的。Kubernetes 现已弃用 Docker。
“https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md
”
目前,kubelet 中的 Docker 支持功能现已弃用,并将在之后的版本中被删除。Kubelet 之前使用的是一个名为 dockershim 的模块,用以实现对 Docker 的 CRI 支持。但 Kubernetes 社区发现了与之相关的维护问题,因此建议大家考虑使用包含 CRI 完整实现(兼容 v1alpha1 或 v1)的可用容器运行时。
简而言之,Docker 并不支持 CRI(容器运行时接口)这一 Kubernetes 运行时 API,而 Kubernetes 用户一直以来所使用的其实是名为“dockershim”的桥接服务。Dockershim 能够转换 Docker API 与 CRI,但在后续版本当中,Kubernetes 将不再提供这项桥接服务。
当然,Docker 本身也是一款非常强大的工具,可用于创建开发环境。但为了了解造成当前状况的原因,我们需要全面分析 Docker 在现有 Kubernetes 架构中的作用。
Kubernetes 是一款基础设施工具,可对多种不同计算资源(例如虚拟 / 物理机)进行分组,使其呈现为统一的巨量计算资源,从而供应用程序使用或与其他人共享。在这样的架构中,Docker(或者容器运行时)仅用于通过 Kubernetes 控制平面进行调度,从而在实际主机内运行应用程序。
![](https://i-blog.csdnimg.cn/blog_migrate/650e47f5a3ec932ca991775ee646fa19.png)
通过以上架构图,可以看到每个 Kubernetes 节点都与控制平面彼此通信。各个节点上的 kubelet 获取元数据,并执行 CRI 以在该节点上创建 / 删除容器。
1、但 Docker 为什么会被弃用?
如前所述,Kubernetes 只能与 CRI 通信,因此要与 Docker 通信,就必须使用桥接服务。这就是弃用 Docker 的第一点原因。
要解释下一个原因,我们必须稍微聊聊 Docker 架构。首先参考以下示意图。
![](https://i-blog.csdnimg.cn/blog_migrate/f9c34f0be4c00857fcd7abf71820ee54.png)
没错,Kubernetes 实际上需要保持在红框之内。Docker 网络与存储卷都被排除在外。
而这些用不到的功能本身就可能带来安全隐患。事实上,您拥有的功能越少,攻击面也就越小。
因此,我们需要考虑使用替代方案,即 CRI 运行时。
2、CRI 运行时
CRI 运行时的实现方案主要有两种。
containerd
如果大家只是想从 Docker 迁移出来,那么 containerd 就是最好的选择。因为它实际上就是在 Docker 之内起效,可以完成所有“运行时”工作,如上图所示。更重要的是,它提供的 CRI 其实 100% 就是由 Docker 所提供。
containerd 还属于全开源软件,因此您可以在 GitHub 上查看说明文档甚至参与项目贡献。
“https://github.com/containerd/containerd/
”
CRI-O
CRI-O 是主要由 Red Hat 员工开发的 CRI 运行时。它的最大区别在于并不依赖于 Docker,而且目前已经在 Red Hat OpenShift 中得到使用。
有趣的是,RHEL 7 同样不官方支持 Docker。相反,其只为容器环境提供 Podman、Buildah 以及 CRI-O。
“https://github.com/cri-o/cri-o
”
CRI-O 的优势在于其采用极简风格,或者说它的设计本身就是作为“纯 CRI”运行时存在。不同于作为 Docker 组成部分的 containerd,CRI-O 在本质上属于纯 CRI 运行时、因此不包含除 CRI 之外的任何其他内容。
从 Docker 迁移至 CRI-O 往往更为困难,但无论如何,CRI-O 至少可以支持 Docker 容器在 Kubernetes 上的正常运行。
3、还有一点……
当我们谈论容器运行时时,请注意我们到底是在谈论哪种类型的运行时。运行时分为两种:CRI 运行时与 OCI 运行时。
CRI 运行时
正如之前所提到,CRI 是 Kubernetes 提供的 API,用于同容器运行时进行通信以创建 / 删除容器化应用程序。
各容器化应用程序作为 kubelet 通过 IPC 在 gRPC 内通信,而且运行时也运行在同一主机之上;CRI 运行时负责从 kubelet 获取请求并执行 OCI 容器运行时以运行容器。稍微有点复杂,接下来我们会用图表来解释。
![](https://i-blog.csdnimg.cn/blog_migrate/2ef2a30f50e122513e94d4ffcc29477a.png)
因此,CRI 运行时将执行以下操作:
从 kubelet 获取 gRPC 请求。
根据规范创建 OCIjson 配置。
OCI 运行时
OCI 运行时负责使用 Linux 内核系统调用(例如 cgroups 与命名空间)生成容器。您可能听说过 runc 或者 gVisor,这就是了。
附录 1:runC 的工作原理
![](https://i-blog.csdnimg.cn/blog_migrate/9dbf526b1c99e170210ceb3a87a8a2d6.png)
CRI 会通过 Linux 系统调用以执行二进制文件,而后 runC 生成容器。这表明 runC 依赖于 Linux 计算机上运行的内核。
这也意味着,如果您发现 runC 中的漏洞会使您获得主机 root 权限,那么容器化应用程序同样会造成 root 权限外泄。很明显,恶意黑客会抓住机会入侵主机,引发灾难性的后果。正因为如此,大家才需要不断更新 Docker(或者其他容器运行时),而不仅仅是更新容器化应用程序本身。
附录 2:gVisor 工作原理
![](https://i-blog.csdnimg.cn/blog_migrate/21fabfdd34043c70d3da9c315c66cf7a.png)
gVisor 是最初由谷歌员工创建的 OCI 运行时。它实际上运行在承载各类谷歌云服务(包括 Google Cloud Run、Google App Engine 以及 Google Cloud Functions)的同一套基础设施之上。
有趣的是,gVisor 中包含一个“访客内核”层,意味着容器化应用程序无法直接接触到主机内核层。即使是应用程序“认为”自己接触到了,实际接触到的也只是 gVisor 的访客内核。
gVisor 的安全模式非常有趣,这里建议大家参阅官方说明文档。
“https://gvisor.dev/docs/
”
gVisor 与 runC 的显著差别如下:
性能更差
Linux 内核层并非 100% 兼容:参见官方文档中的兼容性部分
不受默认支持
“https://gvisor.dev/docs/user_guide/compatibility/
”
4、总结
1.Docker 确被弃用,大家应该开始考虑使用 CRI 运行时,例如 containerd 与 CRI-O。
a.containerd 与 Docker 相兼容,二者共享相同的核心组件。
b. 如果您主要使用 Kubernetes 的最低功能选项,CRI-O 可能更为适合。
2.明确理解 CRI 运行时与 OCI 运行时之间的功能与作用范围差异。
根据您的实际工作负载与业务需求,runC 可能并不总是最好的选择,请酌情做出考量!
译文原文链接:
“https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m
”
有热门推荐????
10w行级别数据的Excel导入,4版完整优化记录,效果太明显了!
推荐一个基于SpringBoot + Mybatis + Vue的代码生成器
这些SQL错误用法,如果经常犯,说明你的水平还很low...
数据库界的Swagger,一键生成数据库文档!牛逼哄哄...
我终于决定要放弃okhttp、httpClient,选择了这个牛逼的神仙工具!贼爽
点击阅读原文,前往学习SpringCloud实战项目