实操|如何将 Containerd 用作 Kubernetes runtime
日前专为开发者提供技术分享的又拍云 OpenTalk 公开课邀请了网易有道资深运维开发工程师张晋涛,直播分享《Containerd 上手实践 》,详细介绍 Containerd 的发展历程、主要特性,以及如何将其作为 Kubernetes runtime 的上手实践。以下是直播内容整理
关于作者:张晋涛,现就职于网易有道, 对 Docker、Kubernetes 及相关生态有大量实践及深入源码的研究,《Docker 核心知识必知必会》专栏作者。PS 讲师长期坚持更新 K8S 生态周报,如有兴趣可订阅其公众号【MoeLove】。
大家好,今天分享的内容将会从 Kubernetes 宣布弃用 dockershim 说起,介绍 Containerd 相关特性,分享如何将 Containerd 用作 Kubernetes 的 runtime。
Kubernetes 宣布弃用 dockershim
很多媒体将该事件宣称为 Kubernetes 宣布弃用 Docker,其实这是一种误导。那么应该如何正确的去看待呢?首先是了解整个事情的前因后果,得需要知道 dockershim 是什么。
dockershim
dockershim 是 Kubernetes 的一个组件,主要目的是为了通过 CRI 操作 Docker。Docker在 2013 年就出现了,2014 年 Kubernetes 发布并默认使用 Docker 作为容器运行时,而 dockershim首次正式出现是在 2016 年。Docker 在创建之初并没有考虑到容器编排或者是考虑 Kubernetes,但 Kubernetes 在创建之初便采用Docker 作为它的默认容器进行时,后续代码当中包含了很多对 Docker 相关的操作逻辑。后期 Kubernetes 为了能够做解耦,兼容更多的容器进行时,将操作 Docker 相关逻辑整体独立起来组成了 dockershim。
Container Runtime Interface
再说 CRI(Container Runtime Interface)即容器运行时接口,该概念是由Kubernetes 提出并在 2016 年底开始应用,其主要目标是增强 Kubernetes 的可扩展性,可以不固定、不捆绑某一个容器运行时,实现可插拔式的容器进行时。比如可以使用 Docker 为容器运行时也可以使用其他的例如 rkt,并且希望通过开放 CRI 这个统一的接口来提高代码的可维护性,而不是需要支持 Docker 时就对 Docker 进行适配,需要支持另一个运行时就得对其做相关的适配。它希望是任何一个成为 Kubernetes 的容器运行时都遵守 CRI 统一的接口与规范,实现了 CRI 就可以作为 Kubernetes 的运行时,并不需要关注具体是什么。
为什么要弃用 dockershim
dockershim 的目的是为了 Kubernetes 通过 CRI 操作 Docker,所以Kubernetes 任何的功能变动或 Docker 有任何的功能特性变更,dockershim 代码必须加以改动保证能够支持变更。另外一个原因是随着容器技术的推进,容器运行时已经多种多样了,比如本次分享的主角 Containerd,还有 cri-o 以及 rkt 的容器运行时,不过这个 rkt 容器运行时的项目已经不维护了。
此外,原先 Kubernetes 需要去调用 dockershim 跟 Docker 做沟通,Docker 的底层运行时是 containerd,可以发现最终都是要调用 containerd,并且 containerd 自身也是可以支持 CRI 的。那为什么要先绕过一层 Docker 呢?是不是可以直接通过 CRI 跟 Containerd 进行交互呢?这也就造成了现在 Kubernetes 社区希望弃用 dockershim。
弃用 dockershim 的影响
终端⽤⼾⽆任何影响。这里指的是使用来自云厂商/使用别人提供的Kubernetes 集群的终端用户,他们不需要关注集群本身的容器运行时到底是什么,因为和你交互的都是 Kubernetes 自身的 CRI,而任何一个可以作为 Kubernetes 底层容器运行时的东西都必须是兼容 CRI 接口的,上层就已经屏蔽掉这个细节了。
对负责维护 Kubernetes 集群的工作人员有一定影响。当升级 Kubernetes 集群版本时,需要考虑是否切换容器进行时。如果目前在用最新版本 Kubernetes V1.20,并且使用 Docker 作为容器运行时,要考虑它能否正常工作。其实是可以正常工作的,只是在启动 Kubernetes 的时候会发现一条日志,提醒你当前使用的容器运行时 Docker 已经不再被 Kubernetes 支持,因为已经准备弃用dockershim,因此会有这个提醒。
Kubernetes 社区计划在 2021 年将dockershim 正式移除。换个角度考虑,既然社区不想在 Kubernetes 源代码当中维护 dockershim 了,那是不是可以把 dockershim 组件给单独的拿出来呢?答案是可以的,现在 Mirantis 和 Docker 已经决定之后共同合作维护 dockershim 组件。此外,还可以通过树外的 dockershim 独立组件,继续使用 Docker 作为容器运行时,并且使用这种方式只需要做一些简单的配置,把原先使用内置的Kubernetes 自身携带的 dockershim 组件,改成使用一个独立的 dockershim 组件,本身变动很小。
那么 Docker 到底还能否使用呢?在我看来,毋庸置疑,Docker 仍然是现阶段容器构建和运行的最佳选择。
快速了解 Containerd
Containerd 是中间层的容器运行时。它构建在平台之下,作为平台下层的一个容器运行时,但又比最底层的容器运行时像 runc、gVisor 要高一点,所以被称为中间层的容器运行时。除此之外也可称作为资源管理器,可以用来管理容器的进程、镜像以及管理文件系统的快照,还有元数据和依赖的管理。既然它可以作为一个资源管理器来使用,如果想要在此之上构建一个属于自己的容器平台就会很方便。
Containerd 是由 Docker 公司创建,并且在 2017年捐赠给了 CNCF,2019 年 Containerd 从 CNCF 正式毕业。Containerd 项目一开始的目标是用来管理容器的进程,之后逐步变更成为一个完整的容器运行时,是 Docker 的底层容器运行时。需要说明的是,containerd 是可以抛开 Docker 与 Kubernetes 自身独立工作的。
Containerd 与 CRI
Containerd 在之前的版本中考虑到了 CRI,但它是将CRI 作为独立的进程存在的。在上图中看到,CRI-Containerd 其实是一个独立组件,Kubernetes 通过 CRI 接口调用 CRI-Containerd,再由这个组件去调用 containerd。在 Containerd1.1 版本之后对该特性做了重新的设计,它将 CRI 的支持通过插件化的方式来实现,Kubernetes 通过 CRI 接口调用的其实是 Containerd 当中 CNI 的插件,以此来达到通信的目的,调用链更少更短了。
Containerd 的特性
支持 OCI 镜像规范,即前文所提到的 runc
支持 OCI 运行时规范。Docker 引导了 OCI 组织的成立,该组织主要有两个规范:镜像规范与运行时规范。这两个规范在 Docker 成立时把 Docker 镜像规范与底层容器运行时规范都给捐赠出来作为它的初始工作
支持镜像的 push/pull 作用
支持容器网络管理。因为可以启动和运行容器,容器启动后支持相互之间的访问,或彼此之间网络的隔离,所以需要支持容器网络的管理
存储支持多租户。Containerd 的相关操作有通过 namespace 来做隔离的,可以指定不同的 namespace 来实现,它默认的 namespace 叫 default,在 default 的 namespace下面下载多个镜像。但是在其他的 namespace 下看不到这些镜像,也用不到,以此来达到多租户的隔离
支持容器运行时和容器的生命周期管理
支持管理网络名称空间容器以加入现有名称空间,可以让某一个容器加入到现有的 namespace 当中
Containerd 的整体架构
上图是 Containerd 整体的架构。由下往上,Containerd支持的操作系统和架构有 Linux、Windows 以及像 ARM 的一些平台。在这些底层的操作系统之上运行的就是底层容器运行时,其中有上文提到的runc、gVisor 等。在底层容器运行时之上的是Containerd 相关的组件,比如 Containerd 的 runtime、core、API、backend、store 还有metadata 等等。构筑在 Containerd 组件之上以及跟这些组件做交互的都是 Containerd 的 client,Kubernetes 跟 Containerd 通过 CRI 做交互时,本身也作为 Containerd 的一个 client。Containerd 本身有提供了一个 CRI,叫 ctr,不过这个命令行工具并不是很好用。
在这些组件之上就是真正的平台,Google Cloud、Docker、IBM、阿里云、微软云还有RANCHER等等都是,这些平台目前都已经支持 containerd, 并且有些已经作为自己的默认容器运行时了。
Containerd 主要功能与上手实践
镜像管理
首先是上文中频繁提到的镜像管理。具体操作是需要通过一个 client 去跟 Containerd 做交互。如图中所示,这里选择了ctr 的命令行工具。ctr指定一个address 参数跟 Containerd交互,它是在后台持续运行的一个服务,需要指定它的地址。图中是通过 pull 一个 redis alpine linux 的镜像,接下来通过 image ls就可以看到已经成功 pull 下来的镜像。
容器管理
作为一个容器运行时对容器进行管理是必不可少的功能。同样的通过 -a 参数来指定 address 与Containerd 进行通信,通过 container create+镜像名称+容器名称来创建一个容器,通过 container ls 可以看到刚才创建的容器。需要注意的是,最后一列叫做 runtime,它的 runtime 叫做 io.containerd.runc.v2,表明是 v2 版本的 Containerd API。
在 Containerd 中通过 container create 创建出来的容器其实并不管用,还需要让其运行起来。这时通常会把它当作一个 task,对它执行 task start,就可以把刚才创建的镜像跑起来了。通过 task ls 就可以看到名叫 redis 的 Containerd,其中有一个正在运行的进程,并且展现出了进程号。
命名空间
需要说明的是,可以通过 -n 来指定一个默认的叫做 default 的命名空间,而后通过 task ls 就看到刚才启动容器的进程,它其实是在运行中的。如果把 namespace 换一个,比如图中的 moby 就是 Docker 项目当前使用的 namespace 名称,Docker 在使用 Containerd 作为容器运行时的时候,会默认使用它。
继续往下看,通过 ctr -n 指定使用 moby 命名空间,-a 参数指定containerd 的地址,然后 task ls 来看看moby 项目当中到底运行着什么。可以看到有一条记录是正在运行当中的。这条记录如何和 Docker 当中的容器或任务做匹配比较呢?一个简单的办法就是通过 docker ps --no-trunc-- format 跟容器完整的 ID,然后 grep 就可以看到刚才通过 ctr 命令得到的ID 了。
需要注意的是,如果使用 Containerd 作为 Kubernetes 的容器运行时,那么它的 namespace 叫 k8s.io。到这里可能有些人已经发现,Containerd 作为 Docker 的运行时可以使用不同的命名空间,比如 moby。用作 Kubernetes 容器运行时也可以使用不同的命名空间,比如 k8s.io。那是否存在一种办法可以让平台当中既有 Kubernetes 又有 Docker,还有 Containerd 呢?答案是肯定的,直接将其全部装到一起,但不配置 Docker 作为容器运行时,先观察一段时间看看,这也是一种办法。
Containerd 用作 Kubernetes 的 runtime
上图是 Containerd 用作 Kubernetes 的 runtime 整个流程图。Kubernetes 通过 CRI 接口,调用到 CRI plugin,plugin 是Containerd 一个内置的插件,其中包含了最主要的两部分:一是 image service,包含了镜像服务相关的;二是 runtime service,即运行时的服务。如果在 containerd 当中部署了一个项目或服务,它首先会调度到某一台机器,这台机器上的 Kubernetes 就会开始工作,它会查询服务、需要哪些镜像,而后把相关的镜像让运行时给拉下来,再去启动对应的 pod 或者相关的容器。
其次它还会跟 CNI 做交互。CNI 即 Container Network Interface,是Kubernetes 提供的一个容器网络接口)。主要注意的是,交互过程中可能会提前创建出来 pause的 container,是一个占位的过程,这里先不对此做更深入的介绍。
当 Containerd 作为 Kubernetes 的容器运行时,配置相对很简单:通过 containerd config default命令可以直接查询到 Containerd 完整的默认配置,下图中可以看到主要是配置 CRI。所以在这里的配置文件当中,通过 plugins.io.containerd.grpc.vi.cri 对其进行配置,首先是 default-runtime,其次配置一个 runtime.runc。
这里简单介绍配置 runc 需要注意的参数。比如 io.containerd.runc.v2 需要配置runtime.type;涉及配置与 runc 相关的一些配置会包含一些 CNI 的配置、目录之类的,具体的配置上图中已经展示了。总而言之如果想要提起来一个服务、一个 pod 或是 container,要注意都是需要配置的。它都会有一个 pause的镜像,即 sandbox_image,可以从中指定一个默认的镜像。当然也可以通过此处换源,加快国内环境下的拉取速度。
最后还有些其他的资源,如本人长期参与的一个项目 KIND( Kubernetes in docker)。这个项目相当于是使用docker 容器作为不同的 node,可以把这些 node 组成一个集群网络,搭建一套 Kubernetes。而这个集群使用的容器运行时就是 containerd,虽然一开始使用的是 Docker,但后期逐步都将其替换成了 containerd,类似的还有包括 K3C、K3S,效果都是差不多的。
推荐阅读
实操|如何将 Containerd 用作 Kubernetes runtime的更多相关文章
- HDFS集群PB级数据迁移方案-DistCp生产环境实操篇
HDFS集群PB级数据迁移方案-DistCp生产环境实操篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 用了接近2个星期的时间,终于把公司的需要的大数据组建部署完毕了,当然,在部 ...
- containerd与kubernetes集成
kubernetes集群三步安装 概念介绍 cri (Container runtime interface) cri is a containerd plugin implementation of ...
- Istio的流量管理(实操一)(istio 系列三)
Istio的流量管理(实操一)(istio 系列三) 使用官方的Bookinfo应用进行测试.涵盖官方文档Traffic Management章节中的请求路由,故障注入,流量迁移,TCP流量迁移,请求 ...
- Istio的流量管理(实操二)(istio 系列四)
Istio的流量管理(实操二)(istio 系列四) 涵盖官方文档Traffic Management章节中的inrgess部分. 目录 Istio的流量管理(实操二)(istio 系列四) Ingr ...
- Istio的流量管理(实操三)
Istio的流量管理(实操三) 涵盖官方文档Traffic Management章节中的egress部分.其中有一小部分问题(已在下文标注)待官方解决. 目录 Istio的流量管理(实操三) 访问外部 ...
- 72 个网络应用安全实操要点,全方位保护 Web 应用的安全
原文地址:Web Application Security Checklist 原文作者:Teo Selenius(已授权) 译者 & 校正:HelloGitHub-小熊熊 & 卤蛋 ...
- 基于IPv6的RIPng路由协议测试——信而泰网络测试仪实操
关键词 IPv6; RIPng; 协议测试; 内部网关协议; 外部网关协议 前言:在国际性网络中,如因特网,拥有很多应用于整个网络的路由选择协议.形成网络的每一个自治系统(AS),都有属于自己的路由选 ...
- containerd与kubernetes集成部署
概念介绍 cri (Container runtime interface) cri is a containerd plugin implementation of Kubernetes conta ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
随机推荐
- 事件修饰符 阻止冒泡 .stop 阻止默认事件 .prevent
stop修饰符 阻止冒泡行为 可以在函数中利用$event传参通过stopPropagation()阻止冒泡 通过直接在元素中的指令中添加 .stop prevent修饰符 阻止默认行为 可以在函数中 ...
- Kafka消费者手动提交消息偏移
生产者每次调用poll()方法时,它总是返回由生产者写入Kafka但还没有消费的消息,如果消费者一致处于运行状态,那么分区消息偏移量就没什么用处,但是如果消费者发生崩溃或者有新的消费者加入群组,就会触 ...
- python k-means聚类实例
port sys reload(sys) sys.setdefaultencoding('utf-8') import matplotlib.pyplot as plt import numpy as ...
- GeoServer安装部署流程
1.双击geoserver-2.13.0.exe进行安装,点击Next进行下一步 2.GeoServer遵循GPL许可,点击I agree继续 3.选择要安装的程序文件目录,点击Next继续 4.点击 ...
- SecureCRT的下载、安装和Putty 的使用 SSH连接工具
SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件.SecureCRT支持SSH,同时支持Telnet和rlog ...
- Autofac的基本使用---4、使用Config配置
Autofac的基本使用---目录 准备 使用的表是Student,创建相关的IDAL.DAL.IBLL.BLL层. 使用EF,创建一个Model层,存放edmx文件. 创建一个Infrastruct ...
- 爱普生 L4160 Serveies 网络打印机配置(问题解决)
一.爱普生网络打印机固定IP地址 用网络打印机过程中,偶尔会出现打印机脱机的状况,大多数原因是打印机的IP地址在路由器重启过后重新分配了IP地址导致的.此时,为了减少不必要的麻烦就需要固定打印机的IP ...
- 前端技术VUE 的前世今生从PC 走向移动
一.Vue的前世 Vue 框架诞生于2014年,他的作者为中国人–尤雨溪(江苏无锡人).Vue用于构建交互式的Web界面的库,是一个构建数据驱动的Web界面渐进式框架,该框架遵循CMD规范,并且提供的 ...
- Unity UI适配 之 GridLayoutGroup组件下的内容适配(进度条适配)
好久没有更新博客了,蓝廋啊. 今天写一写关于GripLayoutGroup组件的屏幕适配问题,以在ARPG游戏中常用的经验条适配来举例子,以此来加深自己的记忆,以便在下次需要制作该功能时能够快速完成. ...
- Demo分享丨看ModelArts与HiLens是如何让车自己跑起来的
摘要:基于HiLens Kit已经基本开发完成,可部署到HiLens Kit,模型的选择为基于DarkNet53的YOLOv3模型,权重为基于COCO2014训练的数据集,而车道线的检测是基于Open ...