容器的崛起——Docker与K8s的相爱相杀

news2024/11/25 5:50:09

容器的崛起

对于K8s启用docker,作为普通开发者的体感是,k8s不就是docker的集群操作吗?k8s弃用docker就像鱼反对水一样不可思议,那么这两个技术究竟是什么关系,Kubernetes 是如何一步步与 Docker 解耦的,请看下文。

模块导学:从微服务到云原生

什么是不可变基础设施

向应用代码隐藏分布式架构复杂度、让分布式架构得以成为一种能够普遍推广的普适架构风格的必要前提。

云原生的定义

官方定义太抽象了,我就不复制粘贴了,我选择从我们都比较熟悉的,至少是能看得见、摸得着的容器化技术开始讲起。

虚拟化的目标与类型

容器是云计算、微服务等诸多软件业界核心技术的共同基石。容器的首要目标是让软件分发部署的过程,从传统的发布安装包、靠人工部署,转变为直接发布已经部署好的、包含整套运行环境的虚拟化镜像。

操作系统层虚拟化

操作系统层虚拟化也就是容器化,仅仅是虚拟化的一个子集,它只能提供操作系统内核以上的部分 ABI 兼容性与完整的环境兼容性。

引言

作为整个模块的开篇,我们这节课的学习目的是要明确软件运行的“兼容性”指的是什么,以及要能理解我们经常能听到的“虚拟化”概念指的是什么。只有理清了这些概念、统一了语境,在后续的课程学习中,我们关于容器、编排、云原生等的讨论,才不会产生太多的歧义。

Docker与K8s的相爱相杀

云原生进化历程

接下来的两节课,我会以容器化技术的发展为线索,带你从隔离与封装两个角度,去学习和了解容器技术。

今天,我们就先来学习下 Linux 系统中隔离技术前提准备,以此为下节课理解“以容器封装应用”的思想打好前置基础。

封装系统:LXC

当文件系统、访问、资源都可以被隔离后,容器就已经具备它降生所需要的全部前置支撑条件了,并且 Linux 的开发者们也已经明确地看到了这一点。

2008 年 Linux Kernel 2.6.24 内核在刚刚开始提供 cgroups 的同一时间,就马上发布了名为Linux 容器(LinuX Containers,LXC)的系统级虚拟化功能。

如此一来,LXC 就带着令人瞩目的光环登场,它的出现促使“容器”从一个阳春白雪的、只流传于开发人员口中的技术词汇,逐渐向整个软件业的公共概念、共同语言发展,就如同今天的“服务器”“客户端”和“互联网”一样。

LXC 眼中的容器的定义与 OpenVZ 和 Linux-VServer 并没有什么差别,它们都是一种封装系统的轻量级虚拟机,而 Docker 眼中的容器的定义则是一种封装应用的技术手段。这两种封装理念在技术层面并没有什么本质区别,但在应用效果上差异可就相当大了。

封装应用:Docker

在 2013 年宣布开源的 Docker,毫无疑问是容器发展历史上里程碑式的发明,然而 Docker 的成功似乎没有太多技术驱动的成分。至少对于开源早期的 Docker 而言,确实没有什么能构成壁垒的技术。

事实上,它的容器化能力直接来源于 LXC,它的镜像分层组合的文件系统直接来源于AUFS,在 Docker 开源后不久,就有人仅用了一百多行的 Shell 脚本,便实现了 Docker 的核心功能(名为Bocker,提供了 docker bulid/pull/images/ps/run/exec/logs/commit/rm/rmi 等功能)。

为什么要用 Docker 而不是 LXC?(Why would I use Docker over plain LXC?)

  • 跨机器的绿色部署
  • 以应用为中心的封装
  • 自动构建:Docker 提供了开发人员从在容器中构建产品的全部支持,开发人员无需关注目标机器的具体配置,就可以使用任意的构建工具链,在容器中自动构建出最终产品。
  • 多版本支持:Docker 支持像 Git 一样管理容器的连续版本,进行检查版本间差异、提交或者回滚等操作。从历史记录中,你可以查看到该容器是如何一步一步构建成的,并且只增量上传或下载新版本中变更的部分。
  • 组件重用:Docker 允许将任何现有容器作为基础镜像来使用,以此构建出更加专业的镜像。
  • 共享:Docker 拥有公共的镜像仓库,成千上万的 Docker 用户在上面上传了自己的镜像,同时也使用他人上传的镜像。
  • 工具生态:Docker 开放了一套可自动化和自行扩展的接口,在此之上用户可以实现很多工具来扩展其功能,比如容器编排、管理界面、持续集成,等等。

其实,促使 Docker 一问世就惊艳世间的,并不是什么黑科技式的秘密武器,而是它符合历史潮流的创意与设计理念,还有充分开放的生态运营。由此可见,在正确的时候,正确的人手上有一个优秀的点子,确实有机会引爆一个时代。

== 和chatgpt套壳一样,巨大的需求,最低的门槛,资源丰富的公共仓库 ==

2014 年,Docker 开源了自己用 Golang 开发的libcontainer,这是一个越过 LXC 直接操作 namespaces 和 cgroups 的核心模块,有了 libcontainer 以后,Docker 就能直接与系统内核打交道,不必依赖 LXC 来提供容器化隔离能力了。(runC的前身,后期会讲到这个)(docker开始构建自己的技术壁垒)

到了 2015 年,在 Docker 的主导和倡议下,多家公司联合制定了“开放容器交互标准”(Open Container Initiative,OCI),这是一个关于容器格式和运行时的规范文件,其中包含了运行时标准(runtime-spec )、容器镜像标准(image-spec)和镜像分发标准(distribution-spec,分发标准还未正式发布)。

  • 运行时标准定义了应该如何运行一个容器、如何管理容器的状态和生命周期、如何使用操作系统的底层特性(namespaces、cgroup、pivot_root 等);
  • 容器镜像标准规定了容器镜像的格式、配置、元数据的格式,你可以理解为对镜像的静态描述;
  • 镜像分发标准则规定了镜像推送和拉取的网络交互过程。

由此,为了符合 OCI 标准,Docker 推动自身的架构继续向前演进。

**首先,它是将 libcontainer 独立出来,封装重构成runC 项目,并捐献给了 Linux 基金会管理。**runC 是 OCI Runtime 的首个参考实现,它提出了“让标准容器无所不在”(Make Standard Containers Available Everywhere)的口号。

为了能够兼容所有符合标准的 OCI Runtime 实现,Docker 进一步重构了 Docker Daemon 子系统,把其中与运行时交互的部分抽象为了containerd 项目

**这是一个负责管理容器执行、分发、监控、网络、构建、日志等功能的核心模块,其内部会为每个容器运行时创建一个 containerd-shim 适配进程,**默认与 runC 搭配工作,但也可以切换到其他 OCI Runtime 实现上(然而实际并没做到,最后 containerd 仍是紧密绑定于 runC)。

后来到了 2016 年,Docker 把 containerd 捐献给了 CNCF 管理。

可以说,runC 与 containerd 两个项目的捐赠托管,既带有 Docker 对开源信念的追求,也带有 Docker 在众多云计算大厂夹击下自救的无奈,这两个项目也将会成为未来 Docker 消亡和存续的伏笔(到这节课的末尾你就能理解这句矛盾的话了)。

2

封装集群:

Kubernetes如果说以 Docker 为代表的容器引擎,是把软件的发布流程从分发二进制安装包,转变为了直接分发虚拟化后的整个运行环境,让应用得以实现跨机器的绿色部署;那以 Kubernetes 为代表的容器编排框架,就是把大型软件系统运行所依赖的集群环境也进行了虚拟化,让集群得以实现跨数据中心的绿色部署,并能够根据实际情况自动扩缩。

尽管早在 2013 年,Pivotal(持有着 Spring Framework 和 Cloud Foundry 的公司)就提出了“云原生”的概念,但是要实现服务化、具备韧性(Resilience)、弹性(Elasticity)、可观测性(Observability)的软件系统依旧十分困难,在当时基本只能依靠架构师和程序员高超的个人能力,云计算本身还帮不上什么忙。

而在云的时代,不能充分利用云的强大能力,这让云计算厂商无比遗憾,也无比焦虑。

所以可以说,直到 Kubernetes 横空出世,大家才终于等到了破局的希望,认准了这就是云原生时代的操作系统,是让复杂软件在云计算下获得韧性、弹性、可观测性的最佳路径,也是为厂商们推动云计算时代加速到来的关键引擎之一。

Docker 靠的是优秀的理念,它是以一个“好点子”引爆了一个时代。我相信就算没有 Docker,也会有 Cocker 或者 Eocker 的出现,但由成立仅三年的 DotCloud 公司(三年后又倒闭)做成了这样的产品,确实有一定的偶然性。

而 Kubernetes 的成功,不仅有 Google 深厚的技术功底作支撑、有领先时代的设计理念,更加关键的是 Kubernetes 的出现,符合所有云计算大厂的切身利益,有着业界巨头不遗余力地广泛支持,所以它的成功便是一种必然。

3

Kubernetes 与 Docker 两者的关系十分微妙,因此我们把握住两者关系的变化过程,是理解 Kubernetes 架构演变与 CRI、OCI 规范的良好线索。

Kubernetes 是如何一步步与 Docker 解耦的?

在一般使用者的体感中,k8s,就是作为管理和编排众多docker容器的工具,后来听说k8s要弃用docker,感觉就像鱼反对水一样不可思议,但是k8s随着版本更迭慢慢解耦docker,可以看做是云原生发展的历史,对理解现在k8s架构有重大意义。于我而言,在这里多费笔墨的原因是,这个过程和企业级架构中用于替换或者升级某一个应用或者组件也如出一辙,在替换过程中的抽象和重构,亦是大型应用的常态。

在 Kubernetes 开源的早期,它是完全依赖且绑定 Docker 的,并没有过多地考虑日后有使用其他容器引擎的可能性。直到 Kubernetes 1.5 之前,Kubernetes 管理容器的方式都是通过内部的 DockerManager,向 Docker Engine 以 HTTP 方式发送指令,通过 Docker 来操作镜像的增删改查的,如上图最右边线路的箭头所示(图中的 kubelet 是集群节点中的代理程序,负责与管理集群的 Master 通信,其他节点的含义在下面介绍时都会有解释)。

现在,我们可以把这个阶段的 Kubernetes 与容器引擎的调用关系捋直,并结合前面提到的 Docker 捐献 containerd 与 runC 后重构的调用,一起来梳理下这个完整的调用链条:

  • Kubernetes Master → kubelet → DockerManager → Docker Engine → containerd → runC

然后到了 2016 年,Kubernetes 1.5 版本开始引入“容器运行时接口”(Container Runtime Interface,CRI),这是一个定义容器运行时应该如何接入到 kubelet 的规范标准,从此 Kubernetes 内部的 DockerManager,就被更为通用的 KubeGenericRuntimeManager 所替代了(实际上在 1.6.6 之前都仍然可以看到 DockerManager),kubelet 与 KubeGenericRuntimeManager 之间通过 gRPC 协议通信。

不过,由于 CRI 是在 Docker 之后才发布的规范,Docker 是肯定不支持 CRI 的,所以 Kubernetes 又提供了 DockerShim 服务作为 Docker 与 CRI 的适配层,由它与 Docker Engine 以 HTTP 形式通信,从而实现了原来 DockerManager 的全部功能。

此时,Docker 对 Kubernetes 来说就只是一项默认依赖,而非之前的不可或缺了,现在它们的调用链为:

  • Kubernetes Master → kubelet → KubeGenericRuntimeManager → DockerShim → Docker Engine → containerd → runC

接着再到 2017 年,由 Google、RedHat、Intel、SUSE、IBM 联合发起的CRI-O(Container Runtime Interface Orchestrator)项目发布了首个正式版本。

一方面,我们从名字上就可以看出来,它肯定是完全遵循 CRI 规范来实现的;另一方面,它可以支持所有符合 OCI 运行时标准的容器引擎,默认仍然是与 runC 搭配工作的,如果要换成Clear Containers、Kata Containers等其他 OCI 运行时,也完全没有问题。(前面提过的运行时交互的部分抽象为了containerd 项目,负责管理容器执行、分发、监控、网络、构建、日志等功能的核心模块,其内部会为每个容器运行时创建一个 containerd-shim 适配进程

不过到这里,开源版的 Kubernetes 虽然完全支持用户去自由选择(根据用户宿主机的环境选择)是使用 CRI-O、cri-containerd,还是 DockerShim 来作为 CRI 实现,但在 RedHat 自己扩展定制的 Kubernetes 企业版,即OpenShift 4中,调用链已经没有了 Docker Engine 的身影:

  • Kubernetes Master → kubelet → KubeGenericRuntimeManager → CRI-O→ runC

当然,因为此时 Docker 在容器引擎中的市场份额仍然占有绝对优势,对于普通用户来说,如果没有明确的收益,也并没有什么动力要把 Docker 换成别的引擎。所以 CRI-O 即使摆出了直接挖掉 Docker 根基的凶悍姿势,实际上也并没有给 Docker 带来太多即时可见的影响。不过,我们能够想像此时 Docker 心中肯定充斥了难以言喻的危机感。

时间继续来到了 2018 年,由 Docker 捐献给 CNCF 的 containerd,在 CNCF 的精心孵化下发布了 1.1 版,1.1 版与 1.0 版的最大区别是此时它已经完美地支持了 CRI 标准,这意味着原本用作 CRI 适配器的 cri-containerd 从此不再被需要。

此时,我们再观察 Kubernetes 到容器运行时的调用链,就会发现调用步骤会比通过 DockerShim、Docker Engine 与 containerd 交互的步骤要减少两步,这又意味着用户只要愿意抛弃掉 Docker 情怀的话,在容器编排上就可以至少省略一次 HTTP 调用,获得性能上的收益。而且根据 Kubernetes 官方给出的测试数据,这些免费的收益还相当地可观。

如此,Kubernetes 从 1.10 版本宣布开始支持 containerd 1.1,在调用链中就已经能够完全抹去 Docker Engine 的存在了:

Kubernetes Master → kubelet → KubeGenericRuntimeManager → containerd → runC

而到了今天,要使用哪一种容器运行时,就取决于你安装 Kubernetes 时宿主机上的容器运行时环境,但对于云计算厂商来说,比如国内的阿里云 ACK、腾讯云 TKE等直接提供的 Kubernetes 容器环境,采用的容器运行时普遍都已经是 containerd 了,毕竟运行性能对它们来说就是核心生产力和竞争力。

画时间线图描述,结合调用图就清楚了。

小结

学完这节课,我们可以试着来做一个判断:在未来,随着 Kubernetes 的持续发展壮大,Docker Engine 经历从不可或缺、默认依赖、可选择、直到淘汰,会是大概率的事件。从表面上看,这件事情是 Google、RedHat 等云计算大厂联手所为,可实际淘汰它的还是技术发展的潮流趋势。这就如同 Docker 诞生时依赖 LXC,到最后用 libcontainer 取代掉 LXC 一样。

同时,我们也该看到事情的另一面:现在连 LXC 都还没有挂掉,反倒还发展出了更加专注于跟 OpenVZ 等系统级虚拟化竞争的LXD,就可以相信 Docker 本身也是很难彻底消亡的,已经养成习惯的 CLI 界面,已经形成成熟生态的镜像仓库等,都应该会长期存在,只是在容器编排领域,未来的 Docker 很可能只会以 runC 和 containerd 的形式存续下去,毕竟它们最初都源于 Docker 的血脉。

一课一思

在 2021 年 1 月初,Kubernetes 宣布将会在 v1.23 版本中,把 Dockershim 从 Kubelet 中移除,那么你会如何看待容器化日后的发展呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s学习-CKS真题-Runtime设置gVisor

目录题目环境搭建解题参考题目 该 cluster 使用 containerd 作为 CRI 运行时。containerd 的默认运行时处理程序是 runc。 containerd 已准备好支持额外的运行时处理程序 runsc (gVisor)。 Task 使用名为 runsc 的现有运行时处理程序,创建一个名为 untrusted 的 Ru…

MIPI D-PHYv2.5笔记(20) -- High-Speed Data-Clock Timing

PHY是在Forward Direction中的源同步接口(source synchronous interface)。无论是处于Forward还是Reverse信号模式,只能有一个时钟源。在Reverve Direction中,时钟是在Forward Direction中被发送的。 图1 Conceptual D-PHY Data a…

本地目录映射到公网访问

1 环境搭建 1.1 nodejs安装 首先是安装nodejs,下载地址:https://nodejs.org/zh-cn/download 选择windows exe版本直接下载。 解压可以得到如下文件: 然后添加环境变量保证在任意终端可以直接使用命令。 当然也可以直接下载msi文件进行安装…

AD8226ARZ-R7-ASEMI代理亚德诺AD8226ARZ-R7车规级芯片

编辑-Z AD8226ARZ-R7芯片参数: 型号:AD8226ARZ-R7 输入电压噪声:22 nV/√Hz 输出电压噪声:120 nV/√Hz 电流噪声:100 fA/√Hz 输入偏移:200μV 输出偏移:1000μV 输入偏置电流&#xff…

得物 API一站式协作平台的一些思考

1.背景 Mooncake是得物API一站式协作平台。从2022年3月份开始负责Mooncake,到现在已经一年了,回顾这一年,Mooncake大的阶段上,总共经历过两个版本: 1、Mooncake 1.0: 面向前端和客户端的mock平台,主要解决接口调用者…

PHP实现以函数的方式计算阶乘,使用函数输入数值逆序输出的两个代码程序

目录 前言 一、实现以函数的方式计算阶乘 1.1运行流程(思想) 1.2代码段 1.3运行截图 二、使用函数输入3个数求和,并以表单形式输出 2.1运行流程(思想) 2.2代码段 2.3运行截图 前言 1.因多重原因,…

项目沟通管理流程的6大规范步骤

1、建立沟通计划 需要对整个项目的沟通对象、沟通内容、沟通频率、沟通方法等各方面,进行计划和安排。尤其需明确沟通机制,建立完整的沟通计划。并根据项目沟通的具体情况,实时添加和修订计划,以保证沟通管理计划的持续适用性。 项…

电脑重装了系统开不了机怎么办?

我们的电脑办公用久后也会出现故障问题,例如卡顿反应慢等等,这时候就要进行重装系统了,但是很多小伙伴重装系统后会出现开不了机的问题,其实我们比较常见的也就是电脑重装系统开不了机的情况。有很多小伙伴反映自己不知道应该怎么…

阿里架构师惨遭“人员优化”,离职只留下一份Java面试进阶手册!!

前几天,一个认识了好几年在大厂工作的程序员朋友,年近30了,却被大厂以“人员优化”的名义无情被辞,据他说,有一个月散伙饭都吃了好几顿…… 在很多企业,都有KPI考核,然后在此基础上还会弄个“末…

【java】深入分析try with resouce的原理 java如何通过方法句柄的方式进行方法调用

这个代码如果是复制用去,非常简单,但是推导过程真的特别艰辛,十几二十行的代码 博主和某T吵了一下午,到最后某T给的写法还是错误的,总之博主能写出这个demo实属不易。推荐看到本博客的同学自己再去深入学习相关的内容&…

用SQL语句操作Oracle数据库--数据查询详解(下篇)

数据查询是数据库的核心操作。上一篇文章我们介绍了单表查询操作,本文将继续介绍另一种重要的查询类型—[ 多表查询 ](涉及多个表的数据查询)。 本文我们将使用以下三个表来进行查询操作: TABLE1: S(学生基本信息表) TABLE2: C(…

Maven环境搭建及配置

文章目录一、系统要求二、安装步骤1.JDK检查2.下载Maven3.配置Maven环境变量4.检查配置一、系统要求 项目要求JDKMaven 3.3 要求 JDK 1.7或以上Maven 3.2 要求 JDK 1.6 或以上 Maven 3.0/3.1 要求 JDK 1.5 或以上磁盘Maven 自身安装需要大约 10 MB 空间。除此之外,…

​破除“内卷”,什么才是高阶智能座舱更优方案?

下一代智能座舱雏形已现。 从多屏互动到舱内全场景交互,从中控娱乐快速延伸到更多元化的车内娱乐平台;越来越多元化功能集中上车,座舱空间的营造(包括氛围灯、香氛等)以及AR技术的应用等等,开始深刻影响着…

活动目录密码策略管理

员工使用的密码可以决定或破坏组织中的数据安全性。但是,知道员工通常不遵循良好的密码卫生习惯也就不足为奇了。从在本机工具(如 Windows Active Directory 组策略)中设置弱密码和通用密码到宽松的密码策略规则,有几个因素对密码…

基于DSP+FPGA的机载雷达伺服控制系统的硬件设计与开发(一)总体设计

2.1 功能要求及性能指标 2.1.1 功能要求 (1)具备方位和俯仰两轴运动的能力; (2)方位轴可实现预置、周扫和扇扫功能; (3)俯仰轴可实现预置功能。 2.1.2 性能指标 (1&#…

【英语】大学英语CET考试,听力题答题技巧笔记(3-4)与技巧总结

文章目录听力技巧课3(长选项关键词)听力技巧课4(所有划关键词的方法,真题带练)听力技巧总结(1-4)听力技巧课1&2:地址 听力技巧课3(长选项关键词) 上课老…

JWT 认证机制

Session 认证机制需要配合 Cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端按口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。 JWT (英文全称: JSON Web Token)是目前最流行的跨域认…

LeetCode算法小抄--二叉搜索树

LeetCode算法小抄--二叉搜索树二叉搜索树(BST)寻找第 K 小的元素[230. 二叉搜索树中第K小的元素](https://leetcode.cn/problems/kth-smallest-element-in-a-bst/)二叉搜索树的转化[538. 把二叉搜索树转换为累加树](https://leetcode.cn/problems/convert-bst-to-greater-tree/…

AI提效工具|借助chatgpt快速读论文,快速总结、归纳、索引相似文章

目前新论文层出不穷,“快速阅读论文”成为研究者们一个必备能力。本文简单记录了近期出现的两个借助chatgpt来帮助我们快速读论文的“神器”,帮助大家快速上手应用,迅速提升论文阅读速度。 此外,本人也会定期更新记录一些类似的“…

酷开科技携手蓝凌数字化OA,释放数字生产力

疫情虽已落幕,但协同办公理念却逐步升级,伴随企业进入到以数字办公为基础的新周期。以提升管理效率为目的的协同办公在人工智能、大数据等技术的加持下,快速步入赋能办公、提升办公效率的自律型协作模式。 数字化时代,时间、空间…