K8s 终将废弃 docker,TKE 早已支持 containerd

网友投稿 327 2022-10-26

K8s 终将废弃 docker,TKE 早已支持 containerd

近日 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]

“寄生”在 kubelet 中的 dockershim

弃用 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

在 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 的问题并且及时进行了修复,如:

注意: 后两种方式会造成同一集群中 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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:光纤接口转为以太网接口数据传输系统的实现方法
下一篇:GitOps之Argo CD实践
相关文章

 发表评论

暂时没有评论,来抢沙发吧~