「【只做懂你de云原生干货知识共享】」

为什么Kubernetes放弃了Docker?
近日,很多公众号发布了相关kubernetes对放弃使用docker的文章并阐述了官方的做法,也并做了很多的解释,但是今天咱说说k8s为什么要放弃docker?真的都放弃了吗?目前,kubernetes不推荐使用kubelet当中的Docker所支持功能了,并将在以后的版本中将其删除。Kubelet以前使用了一个名为dockershim的模块来实现对Docker的CRI支持。但是,Kubernetes社区发现了与此相关的维护问题,因此建议你考虑使用包含完整CRI实现的可用容器运行时。
简而言之,Docker不支持Kubernetes运行时API CRI(容器运行时接口),并且Kubernetes用户一直在使用名为“ dockershim”的桥接服务。Dockershim可以转换Docker API和CRI,但在后续版本中,Kubernetes将不再提供此桥接服务
上面说的可能不是特别让你理解,所以接着上面的问题,我们继续探讨这个问题~ 当然,Docker本身也是一个非常强大的工具,可用于创建开发环境。但是为了了解当前情况的原因,我们需要充分分析Docker在现有Kubernetes架构中的作用。
Kubernetes是一种基础架构工具,可以将各种不同的计算资源(例如虚拟/物理机器)组合在一起,使它们看起来像是一个统一的巨大计算资源,可以由应用程序使用或与他人共享。在这种架构中,Docker(或容器运行时)仅用于通过Kubernetes控制平面进行调度,以在实际主机中运行应用程序。

通过上面的架构图,我们可以看到每个Kubernetes节点都与控制平面通信。每个节点上的kubelet获取元数据并执行CRI以在该节点上运行容器创建/删除。
但是为什么不赞成使用Docker?
如前所述,Kubernetes只能与CRI通信,因此要与Docker通信,必须使用网桥服务。这是第一个原因。为了解释下一个原因,我们必须对Docker架构进行一些解释。首先请参考下图。

是的,Kubernetes实际上需要留在红色框中。排除Docker网络和存储卷。这些未使用的功能本身可能会带来安全风险。实际上,你拥有的功能越少,攻击面就越小。因此,我们需要考虑使用替代方法,即CRI运行时。
CRI运行时 CRI运行时有两种主要的实现方案。
containerd
如果你只想从Docker迁移,那么容器化是最佳选择。因为它实际上在Docker中生效,所以它可以完成所有“运行时”工作,如上图所示。更重要的是,它提供的CRI实际上是Docker提供的100%。
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的一部分容器化不同,CRI-O本质上是纯CRI运行时,因此除CRI之外不包含任何其他内容。
从Docker迁移到CRI-O通常更困难,但是无论如何,CRI-O至少可以支持Docker容器在Kubernetes上的正常运行。还有一件事……
当我们谈论容器运行时时,请注意我们在谈论哪种类型的运行时。有两种类型的运行时:CRI运行时和OCI运行时。
CRI运行时
如前所述,CRI是Kubernetes提供的API,用于与容器运行时进行通信以创建/删除容器化的应用程序。
每个作为kubelet的容器化应用程序都通过IPC在gRPC中进行通信,并且运行时也在同一主机上运行;CRI运行时负责从kubelet获取请求,并执行OCI容器运行时以运行容器。这有点复杂,接下来我们将通过图表进行说明。

因此,CRI在运行时将执行以下操作:从kubelet获取gRPC请求。根据规范创建OCI json配置
OCI运行时
OCI运行时负责使用Linux内核系统调用(例如cgroups和名称空间)生成容器。你可能听说过runC或gVisor。

CRI将通过Linux系统调用执行二进制文件,然后runC将生成容器。这表明runC取决于Linux计算机上运行的内核。这也意味着,如果在runC中发现一个漏洞,该漏洞使你可以在主机上获得root特权,那么容器化的应用程序也会导致root特权泄漏。显然,恶意黑客将抓住机会入侵主机并造成灾难性后果。因此,每个人都需要不断更新Docker(或其他容器运行时),而不仅仅是容器化应用程序本身。

gVisor
gVisor是最初由Google员工创建的OCI运行时。它实际上在托管各种Google云服务(包括Google Cloud Run,Google App Engine和Google Cloud Functions)的相同基础架构上运行。
有趣的是,gVisor包含“guest kernel”层,这意味着容器化的应用程序无法直接访问主机内核层。即使应用程序“认为”它已经触摸过它,但实际上它只是gVisor的guest kernel。
gVisor的安全模式非常有趣。我建议你参考官方文档 gVisor和runC之间的显着差异如下:
例如:Linux内核层不是100%兼容的,如果想了解更多请参考官方文档中的“兼容性”部分
总结一下
Docker确实是不赞成使用的,你应该开始考虑使用CRI运行时,比如contrainerd和CRI-O。
Containerd与Docker兼容,并且都共享相同的核心组件。
如果你主要使用Kubernetes的最低功能选项,则CRI-O可能更适合。
清楚了解CRI运行时和OCI运行时在功能和范围上的区别。
根据你的实际工作量和业务需求,runC不一定总是最佳选择,请酌情考虑!
参考:[https : github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation]
[https://medium.com/cloud-belivers/kubernetes-has-abandoned-docker-d88fc1340afa]
穷则思变,差则思勤!没有比人更高的山没有。
【一个懂你的云原生知识共享平台】
「欢迎扫描下方二维码关注】
如果喜欢文章的话,点点关注,就差你的关注了,更多好玩有趣的云原生前沿技术尽在云原生CTO,如果对你有帮助,欢迎分享给更多人
工作中你如果对kubernetes遇到的困难的问题不知道如何解决,希望你也可以加入我们专属的知识星球,这里是一个答疑技术社群,只为云原生技术而生,另外还有更多的技术干货等你来探索!






