从 chroot,control groups,lxc,warden, 一路走到如今的 dockerrocketwindows containerhyper, 容器技术才算是真正的走向了大规模应用详细的容器技术发展历史可以参考下面这篇文章
容器技术发展历史
本文主要从宏观的角度, 梳理 Docker 与 hyper 这两种 container runtime 及其相关生态的一个关系, 帮助感兴趣的人建立一个整体的印象
Docker
Docker 一路走来, 从独立发展到参与开放容器规范的建设, 自身架构也在不断调整与完善, 逐渐走向了更加规范和生态化的道路宏观上看, Docker Engine 是一种 client/server 架构, server 端, 也即是 daemon, 由一个后台常驻进程 dockerd 构成对外提供 REST API, 整体架构如下图所示
自 1.11 版本起, Docker 全面调整模块架构, 成为了第一个符合 OCI 规范的容器运行时具体来说, Docker Engine 目前是基于 containerd 和 runc 构建的下面详细介绍相关 OCI 规范 runCcontainerd
什么是 OCI 规范
OCI(Open Container Initiative) 致力于建立一个容器运行时和镜像格式的规范, 其核心目的在于避免容器生态的分化, 确保在不同容器引擎上构建的容器可以相互兼容这是容器可移植性的根本保证虽然 Docker 目前是容器的事实规范, 但随着时间的推移, 会不断涌现一些其他的容器引擎, 这个时候就很有必要来定义一下什么是一个容器, 保证不同的实现遵循一些共同的东西这既是 OCI 期望做的事情
runtime spec
OCI Runtime Specification, 主要定义如何 container 配置执行环境以及 container 生命周期
image spec
OCI Image Format Specification, 主要定义一个 OCI image 由一个 manifest, 一个 image index (optional), 一组 filesystem layers, 以及一个 configuration 组成该规范的目的在于确保能构建一套不同容器引擎间可互操作的工具, 用于镜像的构建传输, 以及镜像运行准备工作
有关 OCI 详细资料, 可参考其官方网站
什么是 runC
在早期的 Docker Engine 中, 主要用 LXC 工具来运行和管理容器; 后来采用自研的 libcontainer 来做这类事情, libcontainer 直接使用 Linux 内核提供的相关隔离技术, 比如 cgroupsnamespace 等等
runC 是一个轻量级的工具, 做且只做一件事情, 那就是运行一个容器由 libcontainer 演变而来, 并且由 Docker 捐献给 Linux 基金会, 作为 OCI 的参考实现
有关 runC 详细资料, 可参考其 github repo
什么是 containerd
2016 年 12 月 14 日, Docker 公司宣布将 containerd 从 Docker Engine 中分离, 并捐赠到一个新的开源社区独立发展和运营,"一个工业标准的容器运行时, 注重简单 健壮性可移植性"containerd 可以作为 daemon 程序运行在 Linux 和 Windows 上, 管理机器上所有容器的生命周期
Docker 1.11 的 Docker Engine 里就包含了 containerd, 而现在则是把 containerd 从 Docker Engine 里彻底剥离出来, 作为一个独立的开源项目独立发展, 目标是提供一个更加开放稳定的容器运行基础设施和原先包含在 Docker Engine 里 containerd 相比, 独立的 containerd 将具有更多的功能, 可以涵盖整个容器运行时管理的所有需求
containerd 并不是直接面向最终用户的, 而是主要用于集成到更上层的系统里, 比如 Swarm, Kubernetes, Mesos 等容器编排系统 containerd 以 Daemon 的形式运行在系统上, 通过 unix domain docket 暴露很低层的 gRPC API, 上层系统可以通过这些 API 管理机器上的容器每个 containerd 只负责一台机器, Pull 镜像, 对容器的操作 (启动停止等), 网络, 存储都是由 containerd 完成具体运行容器由 runC 负责, 实际上只要是符合 OCI 规范的容器都可以支持
整体架构
模块分层
有关详细信息可参考官网和 github 项目主页
Docker 如何组合上述组件
先看上面这张图, docker 目前被分成了 4 个独立部分, engine 管理镜像, 通过 containerd,containerd 调用 containerd-shim,containerd-shim 调用 runc 启动容器 containerd 只与容器打交道图中列出的每个组件, 都有一个独立的二进制可执行文件与之对应, 如下所示
Kubernetes on Docker
基本的容器 runtime 还远远不能满足大规模应用的需求, 典型的诉求就是容器的编排管理系统, Docker 公司自身的 swarm,google 的 kubernetes, 以及 mesos marathon 就是这类编排系统经过这几年的发展, kubernetes 大有一统江湖的趋势, kubernetes 本身与 docker 的结合方式也在不断的变化, 自身的定位也逐渐在往通用性容器编排调度系统发展, 所以 k8s 一直在探索如何兼容更多的 container runtime,CRI 就是在这种背景下诞生的
CRI
从 1.5 版本开始, kubernetes 引入了 CRI(Container Runtime Interface), 可参考 Introducing Container Runtime Interface (CRI) in Kubernetes, 其核心目的在于通过一种标准的方式来集成各种不同容器 runtime 并且是一种可插拔的架构, 可以在不改变 kubernetes 的前提下, 使用不同的 container runtime 在 CRI 之前, 不同的 container runtime(docker/rkt 等) 集成到 kubelet 是通过在 kubelet 中实现一个高层接口来完成的, 之前叫做 OCID,CRI-O 则是完全聚焦与 OCI 兼容的 container runtime 和 container images
CRI-containerd
CRI-containerd 则是基于 containerd 的 CRI 实现, 目前是 kubernetes 的一个孵化项目, kubernetes 1.8 中已进入 beta 版本主要用于替代前期基于 dockerd 的 CRI 实现
kubelet 从 dockershim 向 cri-containerd 迁移
CRI-containerd 架构
[图片上传失败...(image-c3ebe5-1517490845623)]
所以在这种新型架构下, kubelet 直接通过基于 containerd 的 CRI 实现 (CRI-containerd) 与 docker-containerd 交互, 以实现 container 的管理
hyper container
鉴于 docker 是共享宿主机的内核, 所以在安全性方面有天然的弱势传统的虚拟机则属于内核相互隔离的那么能否结合二者的优点呢, 答案就是 hyper container
hyper container 主要有 4 部分构成, hyperctl 客户端, hyperd,hyperkernel,hyperStart 整体架构如下图所示
hyper container 直接使用 OCI 镜像规范, hyper 的 runtime 是基于 hypervisor 的 runV, 兼容 OCI runtime 规范, 但是由于 hypervisor 和 container 的天然区别, OCI 中有部分规范在 hyper 里是没有的, 详情可参见 github 项目主页
类似 hyper 的还有 intel 开源的 clearcontainers
小结
容器生态正在走向规范化, 结和虚拟机和 container 二者优势的 hyper 正在快速发展, 编排系统 kubernetes 正在稳步成熟, 周边生态也在不断完善, CNCF 家庭成员也在不断壮大, 微服务理念也逐步深入人心, service mesh 技术正在高速发展... 一切值得期待
来源: http://www.jianshu.com/p/453021b7c1ff