关于腾讯云:K8s-终将废弃-dockerTKE-早已支持-containerd

3次阅读

共计 7107 个字符,预计需要花费 18 分钟才能阅读完成。

近日 K8s 官网称最早将在 1.23 版本弃用 docker 作为容器运行时,并在博客中强调能够应用如 containerd 等 CRI 运行时来代替 docker。本文会做具体解读,并介绍 docker 与 containerd 的关系,以及为什么 containerd 是更好的抉择。这里先答复下 TKE 用户关怀的问题:咱们的集群该怎么办?

TKE 集群该怎么办

  • TKE 早在 2019 年 5 月就曾经反对抉择 containerd 作为容器运行时。如果新建集群,举荐抉择 containerd 作为容器运行时
  • 已有集群在降级到 K8s 1.23(假设 TKE 第一个不反对 dockershim 的 K8s 版本,也可能是 1.24)之前,依然能够持续应用 docker 作为容器运行时
  • 已有集群通过 TKE 集群降级性能降级到 1.23 时,TKE 会提供切换运行时为 containerd 的选项。当然,这种状况下没方法做到 Pod 不受影响,只能采纳重装节点的形式来降级
  • 已有集群也能够将运行时切换为 containerd,新增节点会应用 containerd,存量节点不受影响依然应用 docker(留神:这会造成同一集群中 docker 节点与 containerd 节点共存,如果有应用 Docker in Docker,或者其余依赖节点上 docker daemon 与 docker.sock 的业务,须要提前采取措施来防止产生问题,例如通过按节点标签调度,保障这类业务调度到 docker 节点;或者采纳如前文所述在 containerd 集群运行 Docker in Docker 的计划)
  • 当然,在将来 docker 也有可能在外部实现 CRI 或者增加一个 dockershim 过程,如果 docker 做了相应适配,TKE 这边在将来也会进行反对。

解读 K8s 弃用 dockershim

Docker support in the kubelet is now deprecated and will be removed in a future release. The kubelet uses a module called “dockershim” which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community. We encourage you to evaluate moving to a container runtime that is a full-fledged implementation of CRI (v1alpha1 or v1 compliant) as they become available. (#94624, @dims) [SIG Node]

K8s 在 1.20 的 change log 中提到 K8s 将于 1.20 版本开始逐渐放弃对 Docker 的反对。在 K8s 的官网博客中也提到具体的申明和一些 FAQ。

  • Don’t Panic: Kubernetes and Docker
  • Dockershim FAQ

    在博客中提到 K8s 将在 1.20版本中增加不举荐应用 docker 的信息,且最早将于 1.23版本中把 dockershim 从 kubelet 中移除,届时用户将无奈应用 docker 作为 K8s 集群的运行时,不过通过 docker 构建的镜像在没有 docker 的 K8s 集群中仍然能够应用。

“寄生”在 kubelet 中的 dockershim

本次改变次要内容是筹备删除 kubelet 中的 dockershim,当然这种做法也是合乎预期的。在晚期 rkt 和 docker 争霸时,kubelet 中须要保护两坨代码别离来适配 docker 和 rkt,这使得 kubelet 每次公布新性能都须要思考对运行时组件的适配问题,重大拖慢了新版本公布速度。另外虚拟化曾经是一个广泛的需要,如果呈现了类型的运行时,SIG-Node 小组可能还须要把和新运行时适配的代码增加到 kubelet 中。这种做法并不是长久之计,于是在 2016 年,SIG-Node 提出了容器操作接口 CRI(Container Runtime Interface)。CRI 是对容器操作的一组形象,只有每种容器运行时都实现这组接口,kubelet 就能通过这组接口来适配所有的运行时。但 Docker 过后并没有(也不打算)实现这组接口,kubelet 只能在外部保护一个称之为“dockershim”组件,这个组件充当了 docker 的 CRI 转接器,kubelet 在创立容器时通过 CRI 接口调用 dockershim,而 dockershim 在通过 http 申请把申请交给 docker。于是 kubelet 的架构变成下图这样:

在应用实现了 CRI 接口的组件作为容器运行时的状况下,kubelet 创立容器的调用链如图中红色箭头所示,kubelet 中的 ContainerManager 能够间接通过 CRI 调用到容器运行时,这过程中只须要一次 grpc 申请;而在应用 docker 时,ContainerManager 会走图中蓝色的调用链,CRI 的申请通过 unix:///var/run/dockershim.sock 流向 dockershim,dockershim 做转换后把申请转发给 docker,至于为什么 docker 前面还有个 containerd 稍后会讲到。在 kubelet 中实现 docker 的转接器原本就是一种不优雅的实现,这种做法让调用链变长且不稳定性,还给 kubelet 的保护增加了额定工作,把这部分内容从 kubelet 删掉就是工夫问题了。

弃用 Docker 后会有什么不同?

If you’re an end-user of Kubernetes, not a whole lot will be changing for you. This doesn’t mean the death of Docker, and it doesn’t mean you can’t, or shouldn’t, use Docker as a development tool anymore. Docker is still a useful tool for building containers, and the images that result from running docker build can still run in your Kubernetes cluster.

音讯一出,大家最关怀的事件应该就是弃用 docker 后到底会产生什么影响?

官网的回答是:Don’t Panic!随后又重点解释了几个大家最关怀的问题,咱们来剖析下官网提到的这些方面:

  • 失常的 K8s 用户不会有任何影响

    是的,生产环境中高版本的集群只须要把运行时从 docker 切换到其余的 runtime(如 containerd)即可。containerd 是 docker 中的一个底层组件,次要负责保护容器的生命周期,追随 docker 经验了长期考验。同时 2019 年初就从 CNCF 毕业,能够独自作为容器运行时用在集群中。TKE 也早在 2019 年就曾经提供了 containerd 作为运行时选项,因而把 runtime 从 docker 转换到 containerd 是一个根本无痛的过程。CRI-O 是另一个常被提及的运行时组件,由 redhat 提供,比 containerd 更加轻量级,不过和 docker 的区别较大,可能转换时会有一些不同之处。

  • 开发环境中通过 docker build 构建进去的镜像仍然能够在集群中应用

    镜像始终是容器生态的一大劣势,尽管人们总是把镜像称之为“docker 镜像”,但镜像早就成为了一种标准了。具体标准能够参考 image-spec。在任何中央只有构建出合乎 Image Spec 的镜像,就能够拿到其余合乎 Image Spec 的容器运行时上运行。

  • 在 Pod 中应用 DinD(Docker in Docker)的用户会受到影响

    有些使用者会把 docker 的 socket (/run/docker.sock)挂载到 Pod 中,并在 Pod 中调用 docker 的 api 构建镜像或创立编译容器等,官网在这里的倡议是应用 Kaniko、Img 或 Buildah。咱们能够通过把 docker daemon 作为 DaemonSet 或者给想要应用 docker 的 Pod 增加一个 docker daemon 的 sidecar 的形式在任意运行时中应用 DinD 的计划。TKE 也专门为在 containerd 集群中应用 DinD 提供了计划,详见 在 containerd 中应用 DinD。

containerd 的今生前世

所以 containerd 到底是个啥?和 docker 又是什么关系?可能有些同学看到博客后会收回这样的疑难,接下来就给同学们解说下 containerd 和 docker 的渊源。

docker 与 containerd

2016 年,docker 把负责容器生命周期的模块拆分进去,并将其捐献给了社区,也就是当初的 containerd。docker 拆分后构造如下图所示(当然 docker 公司还在 docker 中增加了局部编排的代码)。

在咱们调用 docker 命令创立容器后,docker daemon 会通过 Image 模块下载镜像并保留到 Graph Driver 模块中,之后通过 client 调用 containerd 创立并运行容器。咱们在应用 docker 创立容器时可能须要应用 --volume 给容器增加长久化存储;还有可能通过 --network 连贯咱们用 docker 命令创立的几个容器,当然,这些性能是 docker 中的 Storage 模块和 Networking 模块提供给咱们的。但 K8s 提供了更强的卷挂载能力和集群级别的网络能力,在集群中 kubelet 只会应用到 docker 提供的镜像下载和容器治理性能,而编排、网络、存储等性能都不会用到。下图中能够看出以后的模式下各模块的调用链,同时图中被红框标注出的几个模块就是 kubelet 创立 Pod 时所依赖的几个运行时的模块。

containerd 被捐献给 CNCF 社区后,社区给其增加了镜像治理模块和 CRI 模块,这样 containerd 不只能够治理容器的生命周期,还能够间接作为 K8s 的运行时应用。于是 containerd 在 2019 年 2 月从 CNCF 社区毕业,正式进入生产环境。下图中能看出以 containerd 作为容器运行时,能够给 kubelet 带来创立 Pod 所需的全副性能,同时还失去了更纯正的功能模块以及更短的调用链。

从下面的比照能够看出从 containerd 被捐献给社区开始,就始终以成为简略、稳固且牢靠的容器运行时为指标;而 docker 则是心愿能成为一个残缺的产品。官网文档中也提到了这一点,docker 为了给用户更好的交互和应用体验以及更多的性能,提供了很多开发人员所须要的个性,同时为了给 swarm 做根底,提供了网络和卷的性能。而这些性能其实都是是 K8s 用不上的;containerd 则相同,仅提供了 kubelet 创立 Pod 所须要的根底性能,当然这换来的就是更高的鲁棒性以及更好的性能。在肯定水平上讲,即便在 kubelet 1.23 版本之后 docker 提供了 CRI 接口,containerd 依然是更好的抉择。

在 Kubernetes 集群中应用 containerd

当然当初有诸多的 CRI 实现者,比拟次要的除了 containerd 还有 CRI-O。CRI-O 是次要由 Red Hat 员工开发的 CRI 运行时,齐全和 docker 没有关系,因而从 docker 迁徙过去可能会比拟艰难。无疑 containerd 才是 docker 被摈弃后的 CRI 运行时的最佳人选,对于开发同学来说整个迁徙过程应该是无感知的,不过对于局部运维同学可能会比拟在意部署和运行中细节上的差别。接下来咱们重点介绍下在 K8s 中应用 containerd 和 docker 的几处区别。

  • 容器日志比照项
比照项 Docker Containerd
存储门路 如果 docker 作为 K8s 容器运行时,容器日志的落盘将由 docker 来实现,保留在相似 /var/lib/docker/containers/$CONTAINERID 目录下。kubelet 会在 /var/log/pods 和 /var/log/containers 上面建设软链接,指向 /var/lib/docker/containers/$CONTAINERID 该目录下的容器日志文件。 如果 Containerd 作为 K8s 容器运行时,容器日志的落盘由 kubelet 来实现,保留至 /var/log/pods/$CONTAINER_NAME 目录下,同时在 /var/log/containers 目录下创立软链接,指向日志文件。
配置参数 在 docker 配置文件中指定:”log-driver”: “json-file”,”log-opts”: {“max-size”: “100m”,”max-file”: “5”} 办法一:在 kubelet 参数中指定:–container-log-max-files=5 –container-log-max-size=”100Mi” 办法二:在 KubeletConfiguration 中指定:“containerLogMaxSize”: “100Mi”, “containerLogMaxFiles”: 5,
把容器日志保留到数据盘 把数据盘挂载到“data-root”(缺省是 /var/lib/docker)即可。 创立一个软链接 /var/log/pods 指向数据盘挂载点下的某个目录。在 TKE 中抉择“将容器和镜像存储在数据盘”,会主动创立软链接 /var/log/pods。
  • cni 配置形式的区别
    在应用 docker 时,kubelet 中的 dockershim 负责调用 cni 插件,而 containerd 的场景中 containerd 中内置的 containerd-cri 插件负责调用 cni,因而对于 cni 的配置文件须要放在 containerd 的配置文件中(/etc/containerd/containerd.toml):

     [plugins.cri.cni]
          bin_dir = "/opt/cni/bin"
          conf_dir = "/etc/cni/net.d"
  • stream 服务的区别

    阐明:

    Kubectl exec/logs 等命令须要在 apiserver 跟容器运行时之间建设流转发通道。

    如何在 containerd 中应用并配置 Stream 服务?

    Docker API 自身提供 stream 服务,kubelet 外部的 docker-shim 会通过 docker API 做流转发。而 containerd 的 stream 服务须要独自配置:

      [plugins.cri]
      stream_server_address = "127.0.0.1"
      stream_server_port = "0"
      enable_tls_streaming = false  [plugins.cri]  stream_server_address = "127.0.0.1"  stream_server_port = "0"  enable_tls_streaming = false

K8s 1.11 前后版本配置区别是什么?

containerd 的 stream 服务在 K8s 不同版本运行时场景下配置不同。

  • 在 K8s 1.11 之前:
    kubelet 不会做 stream proxy,只会做重定向。即 kubelet 会将 containerd 裸露的 stream server 地址发送给 apiserver,并让 apiserver 间接拜访 containerd 的 stream 服务。此时,您须要给 stream 服务转发器认证,用于平安防护。
  • 在 K8s 1.11 之后:
    K8s1.11 引入了 kubelet stream proxy,使 containerd stream 服务只须要监听本地地址即可。

在 TKE 集群中应用 containerd

从 2019 年 5 月份开始,TKE 就开始反对把 containerd 作为容器运行时选项之一。随着 TKE 逐渐在 containerd 集群中反对日志收集服务和 GPU 能力,2020 年 9 月份 containerd 在 TKE 也摘掉了 Beta 版本的标签,能够正式用于生产环境中了。在长期应用中,咱们也发现了一些 containerd 的问题并且及时进行了修复,如:

  • 因为错误处理问题导致的 Pod Terminating
  • 因为内核版本问题导致镜像文件失落

    想要在 TKE 集群中应用 containerd 作为运行时有三种形式:

  1. 在创立集群时,抉择 1.12.4 及以上版本的 K8s 后,抉择 containerd 为运行时组件即可

  2. 在已有 docker 集群中,通过创立运行时为 containerd 的节点池来创立一部分 containerd 节点(新建节点池 > 更多设置 > 运行时组件)

  3. 在已有 docker 集群中,批改集群或者节点池的 ” 运行时组件 ” 属性为 ”containerd”

留神: 后两种形式会造成同一集群中 docker 节点与 containerd 节点共存,如果有应用 Docker in Docker,或者其余依赖节点上 docker daemon 与 docker.sock 的业务,须要提前采取措施来防止产生问题,例如通过按节点标签调度,保障这类业务调度到 docker 节点;或者采纳如前文所述在 containerd 集群运行 Docker in Docker 的计划。

现阶段对于 containerd 和 docker 抉择问题能够查看这里。

参考

[1] Don’t Panic: Kubernetes and Docker

[2] Dockershim FAQ

[3] Dockershim Removal Kubernetes Enhancement Proposal

[4] kubernetes CHANGELOG-1.20

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

正文完
 0