重新审视 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
容器运行时是什么?(入门篇)
容器运行时是指用于操作容器的功能。
容器运行时分为”高级运行时”和”低级运行时”,借助这两者,我们可以创建容器。
(※请参考Kubernetes官方文档以获取其他组件的解释)
再谈容器运行时,会出现OCI和CRI这样的词语。它们指的是高级运行时和低级运行时在进行指令交流时遵循的规范(规则)。
高级运行时和低级运行时之间的通信使用了被称为开放容器倡议(OCI)的世界标准规范。
而且,Kubernetes与高级运行时的交互是通过Kubernetes提出的容器运行时接口(CRI)规范来实现的。
Docker是一种高级运行环境。
在使用Kubernetes时,Docker被用作高级容器运行时。
然而,它不符合Kubernetes设计的容器运行时接口(CRI)。
因此,Kubernetes和Docker通过称为dockershim的桥接器进行通信。
Kubernetes~Docker之间的智能交互是containerd。
尽管Docker作为容器运行环境非常优秀,但Kubernetes面临一个问题,就是无法进行与其本来目标相符的交互(即不通过dockershim,直接使用CRI)。
因此,containerd应运而生。
containerd是从Docker中提取出来的高级容器运行时功能。
containerd最初是由Docker公司捐赠给云原生计算基金会(CNCF)的,并经过版本升级后成为符合容器运行时接口(CRI)标准的高级运行时。
换句话说,如果将containerd作为高层次运行时来使用,就可以使用与将Docker作为高层次运行时时完全相同的功能。
如果可以直接使用containerd实现Docker的功能,为什么要特意使用dockershim呢?
您不认同这样的想法吗?Kubernetes的开发团队也得出了这个结论。
- https://github.com/kubernetes/kubernetes/pull/94624
根据Git上「Deprecate Dockershim(dockershim 非推荐)」的问题说明,Kubernetes希望利用符合CRI标准的机制,如containerd和cri-o。
尽管containerd可以实现完全相同的功能,但为了那些选择使用Docker的人,继续维护dockershim是低效的。因此,决定删除dockershim。
即使将高级运行时从Docker更改为其他,容器本身不受影响。
在过去一直使用Docker作为高级运行时的人中间,可能会出现这样的疑问:“如果在中途更换容器运行时,会对现有的Docker镜像产生影响吗?”
如图所示,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呢?