专一于大数据及容器云核心技术解密,可提供全栈的大数据+云原平生台咨询方案,请持续关注本套博客。若有任何学术交流,可随时联系。更多内容请关注《数据云技术社区》公众号。 linux
1 Docker已不是Docker
1.1 核心大事件
- 2013年:Docker公司在2013年推出Docker后,极大的颠覆了这个行业,也推动了业务容器化过程。
- 2015年:Docker公司主导之下社区推出了容器的第一个行业标准OCI标准(开放容器协议),彼时Docker公司推出了第一个OCI标准的容器运行时runc。
- 2016年,Docker 分拆了 containerd,并将其捐赠给了社区。将这个组件分解为一个单独的项目,使得 docker 将容器的管理功能移出 docker 的核心引擎并移入一个单独的守护进程(即 containerd)。
- 在2017年发布的Containerd1.0
1.2 Docker发展演变
- Docker 1.9 推出swarm,做为独立工具,用于集群管理和服务编排
- Docker 1.11 推出containerd和runc。(2016)
- Docker 1.12 swarm进入引擎
- Docker 17.06 引擎社区改名为moby,docker社区版本改名为docker-ce(相似于红帽的fedora和rhel)
- Docker 17.12 Docker正式引入containerd 1.0(2017)
- Docker 18.06 正式在engine里加入了buildkit,在设置一个环境变量后可使用buildkit完成docker build过程。
- Docker 18.06.1正式将containerd 1.1引入docker。
1.3 Docker总体架构技术图
1.4 最新演变架构整体图
2 containerd项目-CNCF正式宣布毕业
- (美国时间2019年2月28日,CNCF正式宣布containerd毕业了!)
- 2014年,containerd诞生于Docker,最初它是Docker引擎的底层运行时管理器。
- 继2017年3月被CNCF接受以后,containerd已经成为一个行业标准的容器运行时,它简单、稳定、有良好的可移植性,最普遍的使用方式是做为Docker引擎和OCI runc执行器之间的层。
- containerd是继Kubernetes、Prometheus、Envoy和CoreDNS以后,第五个从CNCF毕业的项目。从孵化成熟阶段开始,要想最终毕业,项目必须表现出高度的多样性,被大量用户普遍使用,拥有正式的治理过程,而且面向整个开源社区坚持其可持续性及包容性。
- containerd独立负责容器运行时和生命周期(如建立、启动、中止、停止、信号处理、删除等),其余一些如镜像构建、卷管理、日志等由Docker Daemon的其余模块处理。
2.1 子系统
- distribute子系统 ->该服务实现取去镜像功能
- bundle子系统 ->该服务容许用户从磁盘映像中提取镜像和打包成bundle
- runtime子系统->该服务实现bundles的执行, 包括运行时容器的建立。
2.2 组件
- Executor组件->实际容器运行时的执行器
- Supervisor组件->监视和报告容器状态
- Metadata组件->将元数据存储在图形数据库中。用于存储对镜像和bundle的任何持久性引用。输入到数据库的数据将具备在组件之间协调的模式,以提供对任意数据的访问。其余功能包括定义了用于磁盘资源的垃圾回收的钩子。
- Content组件->提供对content addressable storage (镜像的层文件)的访问,全部不可变的内容将存储在这里,经过内容的hash索引。
- Snapshot组件->管理容器映像的文件系统快照。这相似于Docker中的graphdriver。图层被解包到快照中
- Events组件->支持事件的收集和使用,以提供一致的,事件驱动的行为和审计。
- Metrics组件->每一个组件将导出几个指标,可经过指标API访问。
2.3 bundle数据流
- 指示Distribution组件拉取一个指定的镜像;
- Distribution组件将镜像的content放入content组件中存储;
- 将镜像名字和根清单指针向metadata组件存储注册;
- bundle组件解压镜像为一个bundle;
- 根据上面content组件中存储,将镜像的层文件解压到snapshot 组件中;
- 当一个容器的rootfs的snapshot准备好时,bundle组件使用镜像清单指针和配置来准备执行全部的配置;
- 将准备好的bundle传递给runtime子系统执行;
- runtime子系统读取bundle配置,建立一个运行容器。
2.4 K3s诞生
- 史上最轻量的、开源Kubernetes发行版,正是使用containerd代替Docker做为运行时的容器引擎。K3s只有40M大小,经过用containderd替换Docker,K3s显著减小了运行时占用空间,删除libnetwork、swarm、Docker存储驱动程序和其余插件等功能。
3 runC项目-OCI标准的参考实现
- OCI定义了容器运行时标准,runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。
- Open Container Initiative,也就是常说的OCI,是由多家公司共同成立的项目,并由linux基金会进行管理,致力于container runtime的标准的制定和runc的开发等工做。
- OCI的runtime spec标准中对于容器的状态描述,以及对于容器的建立、删除、查看等操做进行了定义。
- runc,是对于OCI标准的一个参考实现,是一个能够用于建立和运行容器的CLI(command-line interface)工具。runc直接与容器所依赖的cgroup/linux kernel等进行交互,负责为容器配置cgroup/namespace等启动容器所需的环境,建立启动容器的相关进程。
4 kubernetes与容器的演变
4.1 核心大事件
4.2 CRI演变阶段划分
- 阶段一
- kubernetes在初期版本里,就对多个容器引擎作了兼容,所以可使用docker、rkt对容器进行管理。以docker为例,kubelet中会启动一个docker manager,经过直接调用docker的api进行容器的建立等操做。
- 阶段二
- 在k8s 1.5版本以后,kubernetes推出了本身的运行时接口api--CRI(container runtime interface)。cri接口的推出,隔离了各个容器引擎之间的差别,而经过统一的接口与各个容器引擎之间进行互动。
- 阶段三
- docker独立出来了containerd。kubernetes也顺应潮流,孵化了cri-containerd项目,用以将containerd接入到cri的标准中。
- 阶段四(持续关注)
- 为了进一步与oci进行兼容,kubernetes还孵化了cri-o,成为了架设在cri和oci之间的一座桥梁。经过这种方式,能够方便更多符合oci标准的容器运行时,接入kubernetes进行集成使用。能够预见到,经过cri-o,kubernetes在使用的兼容性和普遍性上将会获得进一步增强。
4.3 containerd轻量化的优点
- Containerd的范围比Docker小得多,它提供golang的客户端API,更加关注于可嵌入化。更小的范围意味着更小的代码基,更易于维护和支持,和Kubernetes的需求匹配见下表:
4.4 Cri-containerd项目发布及做用
- Cri-containerd v1.0.0-alpha.0在2017年9月25号发布。
- Cri-containerd使用containerd来管理完整的容器生命周期和全部容器镜像。正以下图所示,Cri-containerd经过CNI(另外一个CNCF的项目)管理pod网络。
- Kubelet调用Cri-containerd,经过CRI运行时服务API,来建立pod;
- Cri-containerd使用containerd建立而且启动一个特定的pause容器(沙箱容器),而且将该容器放到pod的cgroup和命名空间里(简化起见跳过这里的详细步骤);
- Cri-containerd使用CNI配置pod的网络命名空间;
- Kubelet接下来经过CRI镜像服务API调用Cri-containerd,来拉取应用程序容器镜像;
- 若是该镜像不在这个节点上,Cri-containerd就会使用containerd来拉取镜像;
- Kubelet随后经过CRI运行时服务API来调用Cri-containerd,在pod内部,使用拉取下来的容器镜像,建立而且启动应用程序容器;
- Cri-containerd最终调用containerd建立出应用程序容器,将其放入pod的cgroup和命名空间里,而且启动pod的全新的应用程序容器。
总结
专一于大数据及容器云核心技术解密,可提供全栈的大数据+云原平生台咨询方案,请持续关注本套博客。若有任何学术交流,可随时联系。更多内容请关注《数据云技术社区》公众号。 golang