什么?Kubernetes已然弃用Docker?


先问是不是,再问为什么。

没错,这是真的。Kubernetes现已弃用Docker。

参考链接:https://github.com/kubernetes/ ... ation


目前,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控制平面进行调度,从而在实际主机内运行应用程序。

1.png


通过以上架构图,可以看到每个Kubernetes节点都与控制平面彼此通信。各个节点上的kubelet获取元数据,并执行CRI以在该节点上运行容器的创建/删除。

但Docker为什么会被弃用?

如前所述,Kubernetes只能与CRI通信,因此要与Docker通信,就必须使用桥接服务。这就是第一点原因。

要解释下一个原因,我们必须稍微解释一下Docker架构。首先参考以下示意图。
2.png

没错,Kubernetes实际上需要保持在红框之内。Docker网络与存储卷都被排除在外。

而这些用不到的功能本身就可能带来安全隐患。事实上,你拥有的功能越少,攻击面也就越小。

因此,我们需要考虑使用替代方案,即CRI运行时。

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上的正常运行。

还有一点……

当我们谈论容器运行时时,请注意我们到底是在谈论哪种类型的运行时。运行时分为两种:CRI运行时与OCI运行时。

CRI运行时

正如之前所提到,CRI是Kubernetes提供的API,用于同容器运行时进行通信以创建/删除容器化应用程序。

各容器化应用程序作为kubelet通过IPC在gRPC内通信,而且运行时也运行在同一主机之上;CRI运行时负责从kubelet获取请求并执行OCI容器运行时以运行容器。稍微有点复杂,接下来我们会用图表来解释。
3.png

因此,CRI运行时将执行以下操作:
  1. 从kubelet获取gRPC请求。
  2. 根据规范创建OCI json配置


OCI运行时

OCI运行时负责使用Linux内核系统调用(例如cgroups与命名空间)生成容器。你可能听说过runC或者gVisor,这就是了。
4.png

CRI会通过Linux系统调用以执行二进制文件,而后runC生成容器。这表明runC依赖于Linux计算机上运行的内核。

这也意味着,如果你发现runC中的漏洞会使你获得主机root权限,那么容器化应用程序同样会造成root权限外泄。很明显,恶意黑客会抓住机会入侵主机,引发灾难性的后果。正因为如此,大家才需要不断更新Docker(或者其他容器运行时),而不仅仅是更新容器化应用程序本身。
5.png

gVisor是最初由谷歌员工创建的OCI运行时。它实际上运行在承载各类谷歌云服务(包括Google Cloud Run、Google App Engine以及Google Cloud Functions)的同一套基础设施之上。

有趣的是,gVisor中包含一个“访客内核”层,意味着容器化应用程序无法直接接触到主机内核层。即使是应用程序“认为”自己接触到了,实际接触到的也只是gVisor的访客内核。

gVisor的安全模式非常有趣,这里建议大家参阅官方说明文档

gVisor与runC的显著差别如下:


总结


  • Docker确被弃用,大家应该开始考虑使用CRI运行时,例如containerd与CRI-O。
    • containerd与Docker相兼容,二者共享相同的核心组件。

    • 如果你主要使用Kubernetes的最低功能选项,CRI-O可能更为适合。

  • 明确理解CRI运行时与OCI运行时之间的功能与作用范围差异。


根据你的实际工作负载与业务需求,runC可能并不总是最好的选择,请酌情做出考量!

原文链接:Wait, Docker is deprecated in Kubernetes now? What do I do?

0 个评论

要回复文章请先登录注册