重新审视 Kubernetes 容器运行时

首先

NRI OpenStandia Advent Calendar 2020的第六天,将以Kubernetes和容器运行时为题材。

以下是对上述句子的汉语本地化改写:

12月1-3日左右,有消息称,从Kubernetes v1.20版本开始,不再推荐选择Docker作为容器运行时,这一新闻引起了热议。
讨论达到了如此之高,以至于Kubernetes发布了官方声明,要求大家保持冷静。

尽管“非推奨”这个词让人感到震惊,但实际上对于大多数开发者来说并没有太大影响。
只是作为容器运行时,使用Docker本身被认为是不推荐的,但继续推荐使用containerd(Docker的一部分功能)。

然而,许多人可能会怀疑为什么尽管被不推荐使用,却几乎没有对大多数开发者产生影响?因此,在本文中,我们重新审视了容器运行时的定义。

顺便提一下,关于这条新闻,Kubernetes文档翻译项目的所有者inductor详细地写了一篇文章。请一并确认!

    • https://blog.inductor.me/entry/2020/12/03/061329

 

    https://blog.inductor.me/entry/2020/12/03/144834

jacopenさん的文章也很易懂啊!非常值得一看。

    https://jaco.udcp.info/entry/2020/12/03/172843

容器运行时是什么?(入门篇)

容器运行时是指用于操作容器的功能。
容器运行时分为”高级运行时”和”低级运行时”,借助这两者,我们可以创建容器。

image.png

(※请参考Kubernetes官方文档以获取其他组件的解释)

高レベルランタイム低レベルランタイム役割Kubernetes(kubelet)からの指示に対応する「高レベルランタイム」の指示に従ってコンテナ操作を実行主なランタイムcontainerd,cri-orunC,gVisor

再谈容器运行时,会出现OCI和CRI这样的词语。它们指的是高级运行时和低级运行时在进行指令交流时遵循的规范(规则)。

高级运行时和低级运行时之间的通信使用了被称为开放容器倡议(OCI)的世界标准规范。

而且,Kubernetes与高级运行时的交互是通过Kubernetes提出的容器运行时接口(CRI)规范来实现的。

Docker是一种高级运行环境。

在使用Kubernetes时,Docker被用作高级容器运行时。
然而,它不符合Kubernetes设计的容器运行时接口(CRI)。

因此,Kubernetes和Docker通过称为dockershim的桥接器进行通信。

image.png

Kubernetes~Docker之间的智能交互是containerd。

尽管Docker作为容器运行环境非常优秀,但Kubernetes面临一个问题,就是无法进行与其本来目标相符的交互(即不通过dockershim,直接使用CRI)。

因此,containerd应运而生。
containerd是从Docker中提取出来的高级容器运行时功能。

containerd最初是由Docker公司捐赠给云原生计算基金会(CNCF)的,并经过版本升级后成为符合容器运行时接口(CRI)标准的高级运行时。

image.png

换句话说,如果将containerd作为高层次运行时来使用,就可以使用与将Docker作为高层次运行时时完全相同的功能。

如果可以直接使用containerd实现Docker的功能,为什么要特意使用dockershim呢?

您不认同这样的想法吗?Kubernetes的开发团队也得出了这个结论。

    https://github.com/kubernetes/kubernetes/pull/94624
image.png

根据Git上「Deprecate Dockershim(dockershim 非推荐)」的问题说明,Kubernetes希望利用符合CRI标准的机制,如containerd和cri-o。
尽管containerd可以实现完全相同的功能,但为了那些选择使用Docker的人,继续维护dockershim是低效的。因此,决定删除dockershim。

即使将高级运行时从Docker更改为其他,容器本身不受影响。

在过去一直使用Docker作为高级运行时的人中间,可能会出现这样的疑问:“如果在中途更换容器运行时,会对现有的Docker镜像产生影响吗?”

image.png

如图所示,Kubernetes和高级运行时之间的交互必须使用CRI作为规范,
而高级运行时和低级运行时之间的交互必须使用OCI作为规范。

总之,即使高级运行时从Docker改变为其他的解决方案,输入(来自kubelet的指令)仍然保持相同的格式,而输出(指向低级运行时的指令)也将完全保持与Docker相同的格式。

因此,您可以使用containerd或cri-o操作以前在Docker中创建的容器。

在什么情况下会有影响?

如果您之前使用Docker CLI或Docker API,那么在更改Docker的高级运行时时,将需要进行相应的适配工作。

特别值得一提的是,有一种情况是实施了 Docker in Docker。

在容器中的容器是什么?顾名思义,它是一种将Docker容器放置在另一个Docker容器中的方法。这种方法常用于使用CI工具时。

请参阅inductor先生的文章以获取更多详细案例。

    https://blog.inductor.me/entry/2020/12/03/144834

containerd 还是 cri-o ?

当从Docker迁移高层次运行时,主要的选择就是containerd和cri-o。

根据容器运行时containerd与Docker分离的背景,可以看出该运行时具备丰富的功能。
而cri-o因追求最小化的功能,因此非常轻量。

概述

在Kubernetes中,建议使用符合CRI规范的容器运行时,如containerd或cri-o。这是因为它是在Kubernetes和Docker技术结合时的最佳选择。

我期待着Kubernetes和Docker这两种技术今后能够共同发展。

附录:什么是高级运行时

就像前文所述的那样,高级运行时会从Kubernetes(kubelet)接收到CRI规范的指令。
CRI规范的指令会通过Unix套接字发送过来。

附录:低级运行时是什么

低级运行时根据高级运行时的指示来实际操作容器,因此安全性非常重要。

作为低级别运行时的主要选择,有runC和gVisor。

runC是一个在2020年已经成为事实上标准的低级运行时。通过共享内核,它将最大限度地减少容器中应用程序的性能影响。

gVisor是Google开发的低级别运行时。
尽管操作受到限制,但由于应用程序与主机内核分离,它比runC更安全。

如果是关于可执行应用的话,是否考虑一下使用gVisor呢?

广告
将在 10 秒后关闭
bannerAds