00 前情提要

作为后端研发工程师,之前的工作中还是涉及到一部分K8S的工作。在当时的工作场景下,我们通过使用Kubernetes(简称k8s)+docker编排部署的架构方案来提供云原生的在线服务。工作内容包括:编写k8s的yaml文件,通过maven和gradle将工程项目打包成docker镜像,使用kuberctl命令进行运维部署等。在工作过程中学习到了很多Docker和K8s相关的知识,比如写时复制、共享内存、etcd、kube proxy、负载均衡等等,后来还接触了一些K9S。当时在我的心中,Kubernetes+Docker的方案已然是一个很成熟的解决方案。

当本人看到下述标题(参考链接2):

心里难免咯噔一下。

我才刚刚接触这技术不久啊……

“开始了吗(指基于K8S编排Docker的分布式服务架构)”。

“已经结束了(K8S弃用Docker)”

在这篇文章中分享一下关于“k8s弃用docker”的相关学习笔记。

另外:后文提到的"美国小百度"指代google,请不要太在意这个名称。

01 弃用Docker?

相比于网络上的众说纷纭,首先我们应该先查找的还是官方的blog、CHANGELOG或者release note等权威信息。在官方的GitHub CHANGELOG中,我们可以看到官方的声明:

"Changes by kind"一章的"Deprecation"这一小节开篇直接表示kubelet废弃了对Docker的支持。kubelet使用了"dockershim"模块,该模块实现了CRI(容器运行时接口)接口,以支持Docker。官方同时表示:Docker容器的用户最好评估一下容器迁移的成本,将原先的Docker容器迁移为一个更成熟的实现CRI接口的容器。

注:kubelet是在每个 Node 节点上运行的主要 “节点代理”。基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。kubelet 不管理不是由 Kubernetes 创建的容器(参考链接4)。

同样官方在官方的CHANGELOG当中我们可以看到,Docker编译的镜像依然可以在Kubernetes集群环境下运行:

在Kubernetes停止支持Dockershim之后,在Kubernetes新版本中运行Docker镜像依然是没有问题的,那么停止支持Dockershim 到底意味着什么呢?

k8s官方CHANGELOG1.20.md链接

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation

第一步,我们需要明白,原生的Docker并不支持CRI(容器运行时接口)这一Kubernetes运行时API,而Kubernetes用户一直以来所使用的其实是名为“dockershim”的桥接服务。Dockershim能够转换Docker API与CRI,但在后续版本当中,Kubernetes将不再提供这项桥接服务。

另一方面Docker的强大无需赘述。作为地球上第一个实用化的虚拟化容器技术,Docker可用于创建开发环境、中间件部署、进程隔离等方方面面的应用。曾经的萌新安装一个MySQL或者Mongo需要找到官方教程一步步走,如今只要docker pull一下,docker run一下即可,极大减少了研发的工作量和运维成本。

所以又回到那个问题,既然Docker这么强大,那么K8s到底为什么要弃用Docker呢?

02 为什么弃用Docker?

关于“k8s弃用docker”这一现状,我们首先分析Docker在现有的kubernetes架构中的作用

前文所述,K8s底层需要与CRI通信,而Docker又不支持CRI,为了使用Docker,就必须使用桥接模式对Docker进行兼容。

此处贴一下Docker的架构图。

由于k8s本身提供了网络、proxy、volume、namespace等功能,docker中对应的这些功能对于k8s而言就是累赘。Kubernetes对docker的功能需求,实际上只有红框之内的那部分。Docker网络与存储卷都被排除在外。而这些用不到的功能本身就可能带来安全隐患(注:虽然的确功能越多安全隐患越大,但走到这一步难免不让人觉得是各大厂围剿Docker的阴谋,理论上可以完全基于Docker本身的网络、挂载、代理等原生机制进行二次开发)。

解决方案就是基于k8s的CRI(容器运行时接口)。

目前有两种CRI解决方案:containerd和CRI-O。由于containerd是从Docker项目中衍生出来的解决方案,本文只介绍一下containerd,对于CRI-O不做过多介绍。

有读者可能会问,既然兼容Docker这么麻烦,为什么不在一开始Kubernetes就设计好相应规范,直接在更底层支持Docker呢?

背后故事就是一个可可爱爱没有脑袋的商业战争故事啦。

Docker作为最早的容器化技术,于2013年推出并大杀特杀。众多大厂(比如美国小百度)对Docker公司提出了收购意愿,然而倔强的Docker公司并不愿意委身于大厂,于是以美国小百度为首的一系列大公司祭出了K8s对Docker展开了胡萝卜加大棒的策略。

最开始的阶段,由于Docker实在是太火,K8s只能被动兼容Docker,采用的技术包括硬编码和shim。与此同时,随着云原生技术的发展,越来越多更轻量级更定制化的容器技术出现了,为了兼容这些容器,同时也为了围剿Docker,以美国小百度为首的一系列公司在背地里偷偷地提出并完善CRI接口,为杀死Docker慢慢磨刀。

这一操作实质上麻痹了Docker公司,导致Docker公司在kubernetes面前逐渐变得被动。

另一方面,当Docker刚刚推出的时候,没有人预想到容器还需要编排。为了和kubernetes竞争,Docker公司推出了Docker Swarm技术,并推出了containerd技术。然而,正如大家今天所看到的的,Docker Swarm在Kubernets面前不能说是没有赢,只能说是体无完肤并且轰轰烈烈地失败了。

于是Docker公司只能后退一步,将containerd技术捐献给CNCF基金会(Cloud Native Computing Foundation,云原生计算基金会)。而Kubernetes也算见好就收,既然Docker已先退了一步,那就优先支持脱胎于原生Docker容器技术的containerd容器吧。

这背后的故事本文不做过多赘述,有兴趣的读者请自行阅读参考链接6(https://www.qikqiak.com/post/containerd-usage/)。

03 containerd简介

containerd是什么

首先查看Docker的官方博客,原文如下(引用字数有限制,不全部引用):

Containerd was designed to be used by Docker and Kubernetes as well as any other container platform that wants to abstract away syscalls or OS specific functionality to run containers on linux, windows, solaris, or other OSes.

https://www.docker.com/blog/what-is-containerd-runtime/

containerd被设计于能够被Docker、Kubernetes或其他容器平台使用,并在linux、Windows、solaris等操作系统使用的容器。containerd的设计者希望能将containerd设计成一个没有冗余功能的容器。这里面的冗余功能包括网络、volume挂载等。以容器的网络功能为例,在如今的分布式服务环境下,相比于早期的基于linux的抽象netlinking技术,基于SDN技术和服务发现技术的新兴网络技术更具有平台稳定性。因此,在containerd中,设计者所做的只是选择了一个健壮的event系统,以便多个消费者可以订阅他们关心的event。设计者还公开了一个任务API,它允许用户创建一个正在运行的任务,能够向容器的网络名称空间添加接口,然后启动容器的进程,而无需在容器生命周期的各个点上使用复杂的hook技术。

此外,containerd设计了一个支持OCI(Open Container Initiative)和Docker镜像格式的存储分发系统。通过ContainerDAPI,用户有一个完整的内容寻址存储系统,它不仅适用于图像,还适用于元数据、检查点和附加到容器的任意数据。

(调皮一下,OCI的官网页面,看到某菊花厂。)

引用参考链接6,containerd 是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性,containerd 可以负责干下面这些事情:

  • 管理容器的生命周期(从创建容器到销毁容器)

  • 拉取/推送容器镜像

  • 存储管理(管理镜像及容器数据的存储)

  • 调用 runc 运行容器(与 runc 等容器运行时交互)

  • 管理容器网络接口及网络

下图是K8s在Docker和containerd环境下的调用链路图,可见通过使用containerd替代Docker,移除了调用链路中的dockershim与docker两个节点,使K8s的底层调用链路得到了优化。

使用containerd替换Docker之后,此时不能再使用 docker ps 或 docker inspect 命令来获取容器信息。由于不能列出容器,因此也不能获取日志、停止容器,甚至不能通过 docker exec 在容器中执行命令(注:全部使用kubectl命令来完成就可以啦)。

当然使用者仍然可以下载镜像,或者用 docker build 命令构建镜像,但用 Docker 构建、下载的镜像,对于容器运行时和 Kubernetes,均不可见。为了在 Kubernetes 中使用,需要把镜像推送到镜像仓库中去。

到了 containerd 1.1 版本后,containerd进一步去掉了 CRI-Contained 这个 shim,直接把适配逻辑作为插件的方式集成到了 containerd 主进程中,现在这样的调用就更加简洁了。

04 containerd+K8s使用教程

将K8s中的Docker容器替换为containerd容器并不困难。此处请读者自行阅读参考链接7-11进行containerd+k8s的安装和使用,本文对于k8s结合containerd不做过多的阐述。

此处只贴一下安装完containerd之后的ctr命令的结果(直接输入ctr命令,输出containerd支持的操作)。可见ctr关于容器的操作比docker少了很多,主要是容器的创建、删除、运行,没有log、执行(exe)、进程打印(ps)等操作。


ctr
NAME:ctr -_______/ /______/ ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/containerd CLIUSAGE:ctr [global options] command [command options] [arguments...]VERSION:v1.5.5DESCRIPTION:ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.COMMANDS:plugins, plugin            provides information about containerd pluginsversion                    print the client and server versionscontainers, c, container   manage containerscontent                    manage contentevents, event              display containerd eventsimages, image, i           manage imagesleases                     manage leasesnamespaces, namespace, ns  manage namespacespprof                      provide golang pprof outputs for containerdrun                        run a containersnapshots, snapshot        manage snapshotstasks, t, task             manage tasksinstall                    install a new packageoci                        OCI toolsshim                       interact with a shim directlyhelp, h                    Shows a list of commands or help for one commandGLOBAL OPTIONS:--debug                      enable debug output in logs--address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]--timeout value              total timeout for ctr commands (default: 0s)--connect-timeout value      timeout for connecting to containerd (default: 0s)--namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]--help, -h                   show help--version, -v                print the version

另外关于弃用Dockershim带来的影响和FAQ,请详细阅读Kubernetes的官方链接(参考链接13和参考链接14)。

官方给出的Docker迁移CRI容器注意事项如下(参考链接13):

根据Kubernetes提供的官方数据(参考链接15),可以看出,使用containerd容器替代Docker容器之后,系统的启动时间、CPU使用、内存使用均得到了一定程度的优化。

05 总结

Kubernetes弃用Docker,实际上是Kubernetes弃用了Dockershim这一模块,减少了对Docker容器的完整的支持,Docker编译出的镜像依然是可以在Kubernetes中编排使用的。弃用Dockershim的背后的技术原因,主要是因为Docker不支持Kubernetes底层的CRI接口。

与此同时,为了和Kubernetes对接,Docker公司开源并捐献了containerd。Kubernetes官方也推荐使用containerd容器替换现有的Docker容器。containerd其实算是一个精简版本的Docker,通过将网络、volume挂载、代理(proxy)等功能剥离,提供了k8s运行环境下的最小的容器单元。

梳理k8s启用Docker的完整流程,包括containerd从提出到演化的流程,我们可以看出,导致Docker被弃用的主要原因并不是技术问题,更多的还是商业竞争。长期来看,随着Docker Swarm的溃败,K8s已经逐渐占领了云原生的垄断地位,containerd大规模取代Docker只是时间问题。

此外,我们需要持续关注其他的容器解决方案,比如Podman、Buildah等。但是从目前Kubernetes官方对containerd的推荐,以及containerd脱胎于Docker的"高贵血统"观察,其他的容器技术想要在k8s容器市场分一杯羹并不容易。包括Podman和Buildah在内的其他容器技术,具体请参考链接12。

下图左为Podman的标识(是你,三地鼠!),下图右为Buildah的标识(所以鬼佬就这么喜欢小动物吗)。

ps:未来一段时间内可能都不会涉及到K8s的部署、安装和运维等工作,短期内可能不会再更新k8s、云原生、容器等相关的文章了。

06 参考链接

  1. http://dockone.io/article/450984

  2. https://mp.weixin.qq.com/s/J21CLwgF1xLy-6fo1f6Lgw

  3. https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation

  4. https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/

  5. https://www.docker.com/blog/what-is-containerd-runtime/

  6. https://www.qikqiak.com/post/containerd-usage/

  7. https://www.modb.pro/db/100271

  8. https://segmentfault.com/a/1190000039692099

  9. https://zhuanlan.zhihu.com/p/359719736

  10. https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/#containerd

  11. https://cloud.tencent.com/developer/article/1810553

  12. https://www.infoq.cn/article/ggimepmcvdqw4eos2cig

  13. https://kubernetes.io/zh/blog/2020/12/02/dockershim-faq/

  14. https://kubernetes.io/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/

  15. https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/

Kubernetes弃用Docker?关于Kubernetes、Docker和containerd的那些事相关推荐

  1. Kubernetes 弃用 Docker !

    多年间,Docker.Kubernetes 被视为云计算时代下开发者的左膀右臂. Docker 作为一种开源的应用容器引擎,开发者可以打包他们的应用及依赖到一个可移植的容器中,发布到流行的 Linux ...

  2. 不讲武德,Kubernetes 弃用 Docker刷爆了网络,我们公司也慌了!

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 8:55 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | J ...

  3. Kubernetes弃用Docker后怎么办?

    本文转自Rancher Labs 近期,Kubernetes在其最新的Changelog中宣布,自Kubernetes 1.20之后将弃用Docker作为容器运行时.这一消息在云原生领域激起了不小的水 ...

  4. Kubernetes学习笔记三:Docker安装,Docker使用,编写Dockerfile,制作容器镜像,上传docker镜像

    文章目录 Docker的安装 Docker的使用:docker run命令 查看本地存在的镜像:docker images命令 编写Dockerfile,制作容器镜像 docker build制作镜像 ...

  5. Docker 和 Kubernetes 从听过到略懂:给程序员的旋风教程

    早在 Docker 正式发布几个月的时候,LeanCloud 就开始在生产环境大规模使用 Docker,在过去几年里 Docker 的技术栈支撑了我们主要的后端架构.这是一篇写给程序员的 Docker ...

  6. 黑客使用合法工具接管 Docker 和 Kubernetes 平台

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:云头条 在最近一次攻击中,网络犯罪团伙TeamTN ...

  7. Docker、Kubernetes、Apache Mesos 之争 | 一个与传说不同的故事

    本文讲的是Docker.Kubernetes.Apache Mesos 之争 | 一个与传说不同的故事[编者的话]有无数的文章.讨论和社交网络上的交流在比较 Docker.Kubernetes 和 M ...

  8. Docker与Kubernetes,是敌是友?

    本文讲的是Docker与Kubernetes,是敌是友?[编者的话]本文为读者提供了容器技术平台的组成说明,介绍了Docker公司的历史,编排框架Kubernetes推动Docker容器的使用,容器技 ...

  9. 带你快速了解 Docker 和 Kubernetes

    作者:honghaohu,腾讯 PCG 后台开发工程师 从单机容器化技术 Docker 到分布式容器化架构方案 Kubernetes,当今容器化技术发展盛行.本文面向小白读者,旨在快速带领读者了解 D ...

最新文章

  1. Mybatis 获取当前序列和下一个序列值 以及在一个方法中写多条SQL 语句
  2. Kettle连接HiveServer2配置和常见问题解决
  3. mongodb c++ driver安装踩坑记
  4. 融合CDN,纾解数据拥塞之困
  5. Struts2国际化
  6. XML简介和使用AFNetworking解析XML案例
  7. BGP路径属性分类与实验(华为设备)
  8. react native 使用TabNavigator编写APP底部导航
  9. 【EF】Entity Framework Core 2.0 特性介绍和使用指南
  10. uniapp:APP跳转小程序
  11. 女人一生要读的30本书
  12. iov_iter结构体
  13. 包装exp是什么意思_药瓶说明中EXP是什么意思?
  14. 原创,PHP简单的查询火车时刻表程序
  15. 未找到setenv命令 WRF
  16. 多个视频文件合成画中画效果(Python版)
  17. GraphX与GraphLab、Pregel的对比
  18. 微信小程序生成详情页面二维码
  19. CSS基础-02-基础选择器
  20. Windows编译x264

热门文章

  1. c语言库函数大全文库,c语言常用的库函数_相关文章专题_写写帮文库
  2. Python基础经典问题-求sin正弦值
  3. 技术人员需要了解的手机验证码登录风险
  4. 2022 开启新的篇章,越努力越幸运
  5. Codeforces Contest 1110 problem E Magic Stones —— 更改算式
  6. 辛巴学院-Unity-剑英陪你零基础学c#系列(二)顺序
  7. 兵士不克不及怂就是干!美服龙战上传说--新浪炉石传说专区
  8. html5怎么插入psv,请问psv要怎么才能连接电脑进行文件传输?
  9. Unity中实现声音的近大远小
  10. ready 和 onload 的区别