左耳朵耗子说过一段话,让人深以为然:
我清楚地看到了 Go 和 Docker 这两种技术的生态圈发展过程。让我收获最大的并不是这些技术本身,而是技术的变迁和行业的发展。从中,我看到了非常具体的各种思潮和思路,这些更有价值......这些关键新技术,可以让你拿到技术的先机。这些对一个需要技术领导力的个人或公司来说都是非常重要的。
12 月 2 日,Kubernetes 发布了一则消息,表示将在即将发布的 Kubernetes 1.20 版本中弃用 Docker 支持。CNCF 大使 Ian Coldwater 特地发了一条Twitter消息,呼吁大家对此进行关注:“ Kubernetes 中已弃用了 Docker 支持。你需要注意这一点并做一些计划。这将破坏你的集群。”
这些举动,在技术圈子里引起的震荡就好比又宣布了一次 Docker 的死亡(第一次是“Swarm 的没落”)。虽然这只是一盘大棋中最无关紧要的最后一小步,目的就是让 Kubernetes“不再依赖”Docker。
容器技术圈子在短短几年发生了一些重大的变数。
Docker 以提供镜像打包的创新技术实现了“一次构建、处处运行”的软件交付方式,开启了一个全新的容器时代。面对平台化的竞争,Docker 推出了调度引擎 Swarm,但 Swarm 从未真正流行起来,因为整个行业更倾向于采用 Kubernetes,这是 Docker 第一次死亡:它失去了平台之战。2016 年 9 月,Google 和 RedHat联合宣布了“fork Docker”,也就是后来的 CRI-O 项目,这就是这次弃用事件的起始,同时也宣告了竞争的结束。
Docker 源于 Linux Container,可以将一台机器的资源分成 N 份容器,做到资源的隔离,并将可运行的程序定义为标准的 docker image。相对来说,Kubernetes 属于 Docker 容器引擎的上层:编排调度层,它可以把不同机器的每份容器进行编排、调度,组成分布式系统。
近几年,Kubernetes 已经成为自有机房、云上广泛使用的容器编排方案,最广泛的使用方式是 Kubernetes+Docker。运维工程师一方面用 Kubernetes 中的 kubctl 命令、k8s API 来操作集群,一方面在单机用 docker 命令来管理镜像、运行镜像。技术专家杨明越给 InfoQ 总结道:“单独用 Kubernetes,下层不是 Docker 的情况,并不算很多”。
“弃用 Docker”,具体来说,是 Kubernetes 将在 1.20 版本中弃用 dockershim。它是一个桥接服务,帮助 Kubernetes 与 Docker 通信时屏蔽下层容器运行时之间的差异。
这种桥接服务带来便利性的同时也带来了复杂性。留着时间的流逝,这种复杂性不断“膨胀”,维护 Dockershim 已成为运维/开发人员的沉重负担。在下一版中,去掉 Dockershim 将是一个极大的简化,并且恢复了调用的一致性。
尽管 Kubernetes 在发布消息的时候,表示开发人员对这种转变“不必恐慌”,“Docker 还没有死,它仍然有其用途”。但显然 Kubernetes 的解释并不能令人满意:“是否有人质疑为什么不选择一种更顺畅的迁移方式,而不是像谷歌那样抨击 Docker,劝人们赶紧迁移,越快越好”。也有更多开发人员表达了他们并不明白接下来他们需要做些什么。
在生产环境中,企业大量的使用的是经典 Kubernetes+ Docker 方案,同时在一些公司的场景中也有单独使用 Docker 的情况。
如果用户的业务部署比较简单,规模也较小,仅仅是为了使用容器做应用交付的便利,也没有其他的功能需求的话,仅仅通过 docker run/docker-compose 这种方式也能管得好的话,实际上是没必要非得引入 Kubernetes 这样非常重的编排组件的。反而直接仅仅使用 Docker 会更轻量,也更好运维。比如 toB 的软件交付的情况,如果要部署的软件的部署架构比较简单的话,仅仅涉及少量几台机器,服务进程也不多的情况下,也有不少是直接使用 Docker,而不引入 Kubernetes 的,比较轻量、简单。
还有一个就是,使用 kubernetes 做编排引擎的情况下,实际开发者在日常的开发中,也会比较多地使用 Docker。
“对于一般的应用开发者来说,他们一般不会直接去面对 Kubernetes 的,因此,对于他们来说,可能压根就是无感知的,应用开发者甚至都不用知道他们的业务是用容器运行的。对于整个基于 Kubernetes 生态的各个解决方案提供商来说,由于当前基于 Kubernetes 的编排是事实标准,容器的镜像格式又是都遵守 OCI 的,因此可以说所有的之前的交付的构件,无论容器运行时怎样变化,实际上都不会有啥影响。”网易轻舟容器平台 NCS 负责人王新勇在接受 InfoQ 的采访中表示,“但对于容器平台提供商来说,可能需要一些适配和准备动作。”
根据 Sysdig 发布的 2019 年容器使用报告显示,Docker 占据了容器平台市场的大部分份额,占比为 79%,而排在第二位的是 containerd,占比为 18%,排在第三位的 CRI-O 项目,占比为 4%。
CRI-O 是 Kubernetes 的轻量级运行时,希望绕过现有 Docker 容器的大部分机制直接操作 Linux 容器,由 RedHat 主导,并且也是目前 Kubernetes 推崇的方式。
“网易已经有比较好的准备,实际上 Kubernetes 弃用 Docker 从很早就开始讨论了。很早我们就开始关注和使用 Containerd 作为我们的容器运行时的一个选项了。后续我们会提供相关的运行时多个选项 ,并逐步过渡到使用 Containerd 作为运行时。”王新勇表示。
“我们还可以通过将 Dockershim 从 Kubernetes 中抠出来,独立运行,作为 Kubernetes 的 cri 到 Docker API 的适配器,实现 Kubernetes 继续支持 Docker,从而保持之前的使用习惯。”
杨明越也认为由于老技术实现的惯性,在生产环境大量使用的经典 Kubernetes+ Docker 方案依然运行,且运维已经成熟,不会很快升级。对于开发人员、企业,对于 K8S API 的使用频率、变数,远远大于 Docker API,至于 Kubernetes 和 Docker 的桥接,更不用关心。因此,即便“彻底弃用 Docker”,对开发者与企业的影响也非常有限。
Docker 和 Kubernetes 的往事已经非常久远,从亲密伙伴到反目成仇,令人不胜唏嘘。
2013 年,当时名叫 dotCloud 的 Docker 公司,开源出来了自己的容器项目 Docker。Docker 通过镜像打包的方式保持了本地环境和云端环境的高度一致,解决了运维人员的一大心病,将运维人员从一遍遍的重复劳动中解放了出来。同时友好简洁的封装,对开发人员十分具有亲和力,这让 Docker 一举走红。很多后端和云计算领域的优秀的开发力量都汇集在了 Docker 的周围,生态一时间变得异常繁荣。
但此时的这个开源创业公司还必须考虑盈利压力,于是 dotCloud 公司决定将公司名称改为“Docker”。将这个开源项目的名称变成了 Docker 公司的注册商标,这意味着,任何人在商业活动中使用这个单词,以及鲸鱼的 Logo,都会立刻受到法律警告。
2014 年到 2015 年期间,是容器技术的鼎盛时期,Docker 公司一家独大,具有十足的话语权,主导着整个社区的发展。Google 公司曾向 Docker 公司表达了合作的愿望,希望共同推进一个中立的容器运行时(container runtime)库作为 Docker 项目的核心依赖。不过,Docker 公司并没有认同这个明显会削弱自己地位的提议,不久后 Docker 自己还发布了一个容器运行时库 Libcontainer。
作为开源生态的一部分,Docker 还缺少有效的商业模式,他们将眼光放到了容器编排领域,推出了 Swarm。作为 Docker 项目早期的重要贡献者,RedHat 对 Docker 公司的这个平台化战略表示很不满并愤愤退出该项目。
面对 Docker 的强硬态度,Google 联合 RedHat,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的中立基金会,来推动 Kubernetes 的发展。
从此之后,面对 Kubernetes 社区的崛起和壮大,Docker 公司不得不面对失败的现实。2017 年 Docker 公司宣布将 Docker 项目改名为 Moby,交给社区自行维护,而 Docker 公司的商业产品将占有 Docker 这个注册商标,希望以此将原本属于 Docker 社区的用户转化成了自己的客户。
杨明越认为现在的 Kubernetes,从技术上可以说是非常开放的产物,但 Docker 已经不是。开源社区的 Moby 项目,图标由一条鲸鱼变成了一条鲸鱼的尾巴,也可以看出 Docker 对开源版本的态度。原本是开源的项目,是开源生态的一部分,盈利的目标对于 Docker 来说,属于“强扭的瓜”。正如人际关系,从风雨同舟到分道扬镳,甚至到反目成仇,这其中的转折点,并非一两次冲突,而是价值取向的背离。
他强调说:“总体来说,Docker 的弱势来自于公司的盈利、技术应用面两方面,但如果谈 Docker 的消亡,还为时过早。因为 Docker 本身也是一系列技术模块的组合体系,而非一个东西。”
王新勇也认为 Docker 技术(或者说 Moby 项目)和 Docker 公司得分开看待。短时间内,Moby 项目不会消亡,会使用 Docker 命令可能会成为一个开发人员的必备技能,毕竟技术的惯性是很强大的。至于 Docker 公司,就算处境不乐观,应该也是不影响 Docker 技术本身的,毕竟其背后还有强大的开源社区。
近几年,云原生技术发展速度很快,“Kubernetes 1.20 版本中弃用 Docker 支持”可能只是其中很小的一段插曲,毕竟在云原生的全局图中,运行时只占很小的一部分,而且又是比较标准化的部分。
“从云原生的角度来看 Kubernetes 弃用 Docker,其实是件好事,”杨明越表示:“Docker 已经是个商业化产品了,如果能找到一个开源替代品,对整个技术的发展会更有益处。”那么,谁将会代替 Docker 成为云原生技术的“新势力”呢?在我们的采访中,多位老师表示很看好 Podman。
Podman(Pod Manager)是一个由 RedHat 公司推出的容器管理工具,其定位就是 Docker 的替代品,在使用上与 Docker 的体验类似。Podman 源于 CRI-O 项目,可以直接访问 OCI 的实现(如 runC),流程比 Docker 要短。
为什么说 Podman 是比 Docker 更先进的存在呢?晓川表示:“首先,Docker 已经是商业化的产品,而 podman 是个开源产品,在以开源为主的云原生技术体系中更容易得到推广和应用;其次,Docker 在实现 CRI 时,需要一个守护进程,并且以 root 来运行,这就带来了安全隐患,而 podman 不需要,可以直接通过 OCI runtime(默认也是 runc)来启动容器。”
Docker 与 Podman 的区别
由于 podman 的定位是 Docker 的替代品,因此在使用习惯方面也与 Docker 十分类似。
从系统构建者角度看,podman 默认软件与 Docker 的区别不大,只是在进程模型、进程关系方面有所区别,例如关联进程的调试方面、进程的树状结构查看等等,而且总体来看,podman 要比 Docker 简单;从使用者角度看,podman 与 Docker 的命令基本兼容,包括容器运行时、本地镜像、镜像仓库等。因此,podman 命令行工具与 docker 类似,比如构建镜像、启停容器等,甚至可以通过 alias docker=podman 可以进行替换,即便使用了 podman,仍然可以使用 docker.io 作为镜像仓库。
除了 Kubernetes,RHEL 7 同样官方也不支持 Docker,只为容器环境提供 Podman、Buildah 以及 CRI-O。
采访嘉宾:
杨明越,现从事分布式系统、云架构方面工作,具有全方位的技术,曾任新兴互联网公司(BAT)的主任架构师,世界顶级芯片公司的 OS 技术专家,前 Top2 通讯公司高级工程师。
王新勇,网易数帆资深架构师,网易轻舟容器平台 NCS 负责人。
晓川,曾在 RedHat 任产品测试开发工程师,具有多年 Docker 容器、K8s、Linux 和 Python 方面的经验,在 OpenShift 从事 PaaS 平台比较前沿的技术项目。
领取专属 10元无门槛券
私享最新 技术干货