目录
- 一、Docker 介绍
- 1.1 容器历史
- 1.2 Docker 是什么
- 1.3 Docker 和虚拟机,物理主机
- 1.4 Docker 的组成
- 1.5 Namespace
- 1.6 Control groups
- 1.7 容器管理工具
- 1.8 Docker 的优势
- 1.9 Docker 的缺点
- 1.10 容器的相关技术
- 1.10.1 容器规范
- 1.10.2 容器 runtime
- 1.10.3 容器管理工具
- 1.10.4 镜像仓库 Registry
- 1.10.5 容器编排工具
一、Docker 介绍
Container 即容器,平时生活中指的是可以装下其它物品的工具, 以方便人类归纳放置物品 、存储和异地运输 ,比如人类使用的衣柜 、行李箱、 背包等可以成为容器,Container 除了容器以外,另一个意思是集装箱, 很多码头工人将很多装有不同物品但却整齐划一的箱子装载到停靠在岸边大船,然后方便的运来运去,如下图所示:
为什么这些集装箱可以很方便的运来运去呢?因为它们大小一致标准化尺寸的箱子,并且可以安全的隔离开,所以当我们使用 Container 来形容容器的时候,就是我们想要让容器达到一个可以打包,符合标准的状态。
但今天我们所说的容器是一种 IT 技术。容器其实是一种 沙盒技术。 顾名思义,沙盒就是能够像一个集装箱一样,把你的应用装起来。这样,应用与应用之间就有了边界而不会相互干扰;同时装在沙盒里面的应用,也可以很方便的被搬来搬去,这也是 PaaS 想要的最理想的状态(可移植性、标准化、隔离性)。
容器是软件工业上的集装箱的技术,集装箱的标准化,减少了包装成本,大大提高货物运输和装卸效率,是传统运输行业的重大变革。早期的软件项目中软件更新,发布低效,开发测试发布周期很长,很难敏捷。有了容器技术,就可以利用其标准化的特点,大幅提高生产效率。
容器技术是虚拟化、云计算、大数据之后的一门新兴的并且是炙手可热的新技术, 容器技术提高了硬件资源利用率、 方便了企业的业务快速横向扩容(可以达到秒级快速扩容)、 实现了业务宕机自愈功能 (配合 K8S 可以实现,但 OpenStack 无此功能),因此未来数年会是一个容器愈发流行的时代 ,这是一个对于 IT 行业来说非常有影响和价值的技术,而对于IT行业的从业者来说, 熟练掌握容器技术无疑是一个很有前景的行业工作机会。
1.1 容器历史
虽然 docker 把容器技术推向了巅峰,但容器技术却不是从 docker 诞生的。实际上,容器技术连新技术都算不上,因为它的诞生和使用确实有些年头了。下面的一串名称可能有的你都没有听说过,但它们的确都是容器技术的应用:
- Chroot Jail。就是我们常见的 chroot 命令的用法。它在 1979 年的时候就出现了,被认为是最早的容器化技术之一。它可以把一个进程的文件系统隔离起来。
- The FreeBSD Jail。Freebsd Jail (监狱)实现了操作系统级别的虚拟化,它是操作系统级别虚拟化技术的先驱之一。2000年,伴随 FreeBSD4.0 版的发布
- Linux VServer。使用添加到 Linux 内核的系统级别的虚拟化功能实现的专用虚拟服务器。允许创建许多独立的虚拟专用服务器(VPS),这些虚拟专用服务器在单个物理服务器上全速同时运行,从而有效地共享硬件资源。 VPS 提供与传统 Linux 服务器几乎相同的操作环境。可以在这样的 VPS 上启动所有服务(例如 ssh,邮件, Web 和数据库服务器),而无需(或者在特殊情况下只需进行很少的修改),就像在任何真实服务器上一样。每个 VPS 都有自己的用户帐户数据库和 root 密码,并且与其他虚拟服务器隔离,但它们共享相同的硬件资源 2003年11月1日 VServer 1.0 发布。官网:http://linux-vserver.org/
- Solaris Containers。它也是操作系统级别的虚拟化技术,专为 X86 和 SPARC 系统设计。Solaris 容器是系统资源控制和通过
区域
提供边界隔离的组合。 - OpenVZ。OpenVZ 是一种 Linux 中操作系统级别的虚拟化技术。 它允许创建多个安全隔离的 Linux 容器,即 VPS。
- Process Containers。Process 容器由 Google 的工程师开发,一般被称为 cgroups。
- LXC。LXC 为 Linux Container 的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。Linux Container 提供了在单一可控主机节点上支持多个相互隔离的 server container 同时执行的机制。 Linux Container 有点像 chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为 lxc 是一种操作系统层次上的资源的虚拟化。
- Warden。在最初阶段,Warden 使用 LXC 作为容器运行时。 如今已被 CloudFoundy 取代。
- LMCTFY。LMCTY 是 Let me contain that for you 的缩写。它是 Google 的容器技术栈的开源版本。Google 的工程师一直在与 docker 的 libertainer 团队合作,并将 libertainer 的核心概念进行抽象并移植到此项目中。该项目的进展不明,估计会被 libcontainer 取代。
- Docker。Docker 是一个可以将应用程序及其依赖打包到几乎可以在任何服务器上运行的容器的工具。
- RKT。RKT 是 Rocket 的缩写,它是一个专注于安全和开放标准的应用程序容器引擎。
综上所述正如我们所看到的,docker 并不是第一个容器化技术,但它的确是最知名的一个。
1.2 Docker 是什么
Docker (码头工人)是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司(后由于 Docker 开源后大受欢迎就将公司改名为 Docker Inc ,总部位于美国加州的旧金山)内部的一个开源的 PAAS 服务 (Platform as a ServiceService ) 的业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 是基于 Linux 内核实现,Docker 最早采用 LXC 技术 ,LXC 是 Linux 原生支持的容器技术 ,可以提供轻量级的虚拟化 ,可以说 docker 就是基于 LXC 发展起来 的,提供 LXC 的高级封装,标准的配置方法,在 LXC 的基础之上,docker 提供了一系列更强大的功能。而虚拟化技术KVM(KernelKernel-based Virtual Machine Machine) 基于模块实现, 后来 Docker 改为自己研发并开源的 runc 技术运行容器,彻底抛弃了 LXC。
Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程 API 来管理和创建容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是 build(构建)、ship(运输)、 run(运行),Docker 遵从 apache 2.0 协议,并通过(namespace 及 cgroup 等)来提供容器的资源隔离与安全保障等,所以 Docker 容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机 6-8% 性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机。类似于 VM 但是在原理和应用上和 VM 的差别还是很大的,并且 docker 的专业叫法是 应用容器(Application Container)。
Docker 的主要目标:
Build,Ship and Run Any App,Anywhere,即通过对应用组件的封装(Packaging)、分发
(Distribution)、部署(Deployment)、运行(Runtime)等生命周期的管理,达到应用组件级别的 一次封装,到处运行。
这里的应用组件,既可以是一个 Web 应用,也可以是一套数据库服务,甚至是一个操作系统。将应用运行在 Docker 容器上,可以实现跨平台,跨服务器,只需一次配置准备好相关的应用环境,即可实现到处运行,保证研发和生产环境的一致性,解决了应用和运行环境的兼容性问题,从而极大提升了部署效率,减少故障的可能性。使用 Docker 容器化封装应用程序的意义:
统一基础设施环境------ docker 环境:
硬件的组成配置
操作系统的版本
运行时环境的异构
统一程序打包(装箱)方式------ docker 镜像:
java程序
python程序
nodejs程序
统一程序部署(运行)方式------ docker 容器:
java-jar...→ docker run...
python manage.py runserver... → docker run...
npm run dev ... → docker run...
1.3 Docker 和虚拟机,物理主机
容器和虚拟机技术比较:
传统虚拟机是虚拟出一个主机硬件,并且运行一个完整的操作系统,然后在这个系统上安装和运行软件。容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化。每个容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统,独立的进程空间,网络空间,用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响。
容器和虚拟机表现比较:
- 资源利用率更高: 开销更小,不需要启动单独的虚拟机 OS 内核占用硬件资源,可以将服务器性能压榨至极致。虚拟机一般会有 5-20% 的损耗,容器运行基本无损耗,所以生产中一台物理机只能运行数十个虚拟机,但是一般可以运行数百个容器。
- 启动速度更快: 可以在数秒内完成启动。
- 占用空间更小:容器一般占用的磁盘空间以 MB 为单位,而虚拟机以 GB。
- 集成性更好:和 CI/CD(持续集成/持续部署)相关技术结合性更好,实现打包镜像发布测试可以一键运行,做到自动化并快速的部署管理,实现高效的开发生命周期。
使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如 Nginx、PHP、Tomcat 等 web 程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来较大的性能提升。
根据实验,一个运行着 CentOS 的 KVM 虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用 100~200 MB 内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘I/O的损耗非常大。比如:一台 96G 内存的物理服务器,为了运行 java 程序的虚拟机一般需要分配 8G 内存/4核 的资源,只能运行 13台 左右虚拟机,但是改为在 docker 容器上运行 Java 程序,每个容器只需要分配 4G 内存 即可,同样的物理服务器就可以运行 25个 左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可节约一半以上的物理设备。
1.4 Docker 的组成
docker 官网:http://www.docker.com
帮助文档链接:https://docs.docker.com/
docker 镜像:https://hub.docker.com/
docker 中文网站: http://www.docker.org.cn/
Docker 主机(Host):一个物理机或虚拟机,用于运行 Docker 服务进程和容器,也称为宿主机, node节点
Docker 服务端(Server):Docker 守护进程,运行 docker 容器
Docker 客户端(Client):客户端使用 docker 命令或其他工具调用 docker API
Docker 镜像(Images):镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合
Docker 仓库(Registry):保存镜像的仓库,官方仓库:https://hub.docker.com/,可以搭建私有仓库 harbor
Docker 容器(Container):容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程
1.5 Namespace
一个宿主机运行了N个容器,多个容器共用一个 OS,必然带来的以下问题:
- 怎么样保证每个容器都有不同的文件系统并且能互不影响?
- 一个 docker 主进程内的各个容器都是其子进程,那么如果实现同一个主进程下不同类型的子进程?
- 各个容器子进程间能相互通信(内存数据)吗?
- 每个容器怎么解决IP及端口分配的问题?
- 多个容器的主机名能一样吗?
- 每个容器都要不要有root用户?怎么解决账户重名问题?
namespace 是 Linux 系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在内核,各个 docker 容器运行在同一个 docker 主进程并且共用同一个宿主机系统内核,各 docker 容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离:
1.6 Control groups
Linux Cgroups 的全称是 Linux Control Groups,是 Linux 内核的一个功能。最早是由 Google 的工程师(主要是 Paul Menage 和 Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。在2007年时,因为在 Linux 内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为 cgroup,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。
如果不对一个容器做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU、内存等。Cgroups 最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如:将进程挂起和恢复等操作)。Cgroups 在内核层默认已经开启,从 CentOS 和 Ubuntu 不同版本对比,显然内核较新的支持的功能更多。
Rocky Linux 8.7:
[root@rocky8 ~]# cat /etc/redhat-release
Rocky Linux release 8.7 (Green Obsidian)
[root@rocky8 ~]# grep CGROUP /boot/config-4.18.0-425.3.1.el8.x86_64
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_MISC is not set
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_FC_APPID=y
# CONFIG_BLK_CGROUP_IOCOST is not set
# CONFIG_BLK_CGROUP_IOPRIO is not set
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
Centos7 cgroups:
[root@centos7 ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
[root@centos7 ~]# grep CGROUP /boot/config-3.10.0-1062.el7.x86_64
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y
Ubuntu cgroups:
amoxiang@amoxiang:~$ grep CGROUP /boot/config-5.15.0-60-generic
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_RWSTAT=y
# CONFIG_BLK_CGROUP_IOLATENCY is not set
CONFIG_BLK_CGROUP_FC_APPID=y
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
cgroups 中内存模块:
amoxiang@amoxiang:~$ grep MEMCG /boot/config-5.15.0-60-generic
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
1.7 容器管理工具
有了以上的 chroot、namespace、cgroups 就具备了基础的容器运行环境,但是还需要有相应的容器创建与删除的管理工具、以及怎么样把容器运行起来、容器数据怎么处理、怎么进行启动与关闭等问题需要解决,于是容器管理技术出现了。目前主要是使用 docker,早期使用 LXC。
- LXC:Linux Container。可以提供轻量级的虚拟化功能,以便隔离进程和资源,包括一系列容器的管理工具软件,如,lxc-create,lxc-start,lxc-attach 等,但这技术功能不完善,目前较少使用。官方网站: https://linuxcontainers.org/
- docker。Docker 相当于增强版的LXC,功能更为强大和易用,也是当前最主流的容器前端管理工具。Docker 先启动一个容器也需要一个外部模板,也称为镜像,docker 的镜像可以保存在一个公共的地方共享使用,只要把镜像下载下来就可以使用,最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像,一个镜像可以被启动为多个容器。
Docker 的镜像是分层的,镜像底层为库文件且只读层即不能写入也不能删除数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到宿主机上对应容器的目录,但是容器内的数据在删除容器后也会被随之删除。 - 项目网点: https://github.com/alibaba/pouch。Pouch (小袋子)起源于 2011 年,并于2017年11月19日上午,在中国开源年会现场,阿里巴巴正式开源了基于 Apache 2.0 协议的容器技术 Pouch。Pouch 是一款轻量级的容器技术,拥有快速高效、可移植性高、资源占用少等特性,主要帮助阿里更快的做到内部业务的交付,同时提高超大规模下数据中心的物理资源利用率。目前的容器方案大多基于 Linux 内核提供的 cgroup 和 namespace 来实现隔离,然后这样轻量级方案存在弊端: 容器间,容器与宿主间,共享同一个内核。内核实现的隔离资源,维度不足。面对如此的内核现状,阿里巴巴采取了三个方面的工作,来解决容器的安全问题:
用户态增强容器的隔离维度,比如网络带宽、磁盘使用量等 给内核提交 patch,修复容器的资源可见性问题,cgroup 方面的 bug 实现基于 Hypervisor 的容器,通过创建新内核来实现容器隔离
- Podman。虽然目前 Docker 是管理 Linux 容器最好的工具,注意没有之一,但是 podman 的横空出现即将改变这一点。Podman 即 Pod Manager tool,从名称上可以看出和 kubernets 的 pod 的密切联系,不过就其功能来说,简而言之:alias docker = podman,是 CentOS8 新集成的功能,或许不久的未来会代替 docker。Podman 是一个 为 Kubernetes 而生的开源的容器管理工具,原来是 CRI-O(即容器运行时接口CRI 和开放容器计划OCI) 项目的一部分,后来被分离成一个单独的项目叫libpod。其可在大多数 Linux 平台上使用,它是一种无守护程序的容器引擎,用于在 Linux 系统上开发,管理和运行任何符合 Open Container Initiative(OCI)标准的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端,Podman 里面 87%的指令 都和 Docker CLI 相同,因此可以简单地为 Docker CLI 别名,即
alias docker = podman
,事实上,podman 使用的一些库也是 docker 的一部分。
官网地址:https://podman.io/
项目地址:https://github.com/containers/libpod
Podman 和 docker 不同之处:
1.docker 需要在系统上运行一个守护进程(docker daemon),这会产生一定的开销,而 podman 不需要
2.启动容器的方式不同:
docker cli 命令通过API跟 Docker Engine(引擎)交互告诉它我想创建一个container,然后docker Engine才会调用 OCI container
runtime(runc)来启动一个container。
这代表container的process(进程)不会是 Docker CLI的 child process(子进程),而是 Docker Engine的 child process。
Podman是直接给 OCI containner runtime(runc)进行交互来创建container的,所以container process直接是 podman的 child process。
3.因为docke有docker daemon,所以docker启动的容器支持 --restart策略,但是podman不支持docker需要使用root用户来创建容器。
这可能会产生安全风险,尤其是当用户知道docker run命令的--privileged选项时。
podman既可以由root用户运行,也可以由非特权用户运行
4.docker在Linux上作为守护进程运行扼杀了容器社区的创新。 如果要更改容器的工作方式,则需要更改docker守护程序并将这些更改推送到
上游。 没有守护进程,容器基础结构更加模块化,更容易进行更改。 podman的无守护进程架构更加灵活和安全。
1.8 Docker 的优势
- 快速部署:短时间内可以部署成百上千个应用,更快速交付到线上
- 高效虚拟化:不需要额外 hypervisor 支持,基于linux内核实现应用虚拟化,相比虚拟机大幅提高性能和效率
- 节省开支:提高服务器利用率,降低IT支出
- 简化配置:将运行环境打包保存至容器,使用时直接启动即可
- 环境统一:将开发,测试,生产的应用运行环境进行标准化和统一,减少环境不一样带来的各种问题
- 快速迁移和扩展:可实现跨平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从A宿主机迁移到B宿主机,甚至是A平台迁移到B平台
- 更好的实现面向服务的架构,推荐一个容器只运行一个应用,实现分布的应用模型,可以方便的进行横向扩展,符合开发中高内聚,低耦合的要求,减少不同服务之间的相互影响
1.9 Docker 的缺点
- 多个容器共用宿主机的内核,各应用之间的隔离不如虚拟机彻底
- 由于和宿主机之间的进程也是隔离的,需要进入容器查看和调试容器内进程等资源,变得比较困难和繁琐
- 如果容器内进程需要查看和调试,需要在每个容器内都需要安装相应的工具,这也造成存储空间的重复浪费
1.10 容器的相关技术
1.10.1 容器规范
OCI 官网:https://opencontainers.org/
容器技术除了的 docker 之外,还有 coreOS 的 rkt,还有阿里的 Pouch,为了保证容器生态的标准性和健康可持续发展,包括 Linux 基金会、Docker、微软、红帽谷歌和 IBM 等公司在2015年6月共同成立了一个叫 Open Container Initiative(OCI) 的组织,其目的就是制定开放的标准的容器规范,目前 OCI 一共发布了两个规范,分别是 runtime spec 和 image format spec,有了这两个规范,不同的容器公司开发的容器只要兼容这两个规范,就可以保证容器的可移植性和相互可操作性。
1.10.2 容器 runtime
runtime 是真正运行容器的地方,因此为了运行不同的容器 runtime 需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境。runtime 类型:
- Lxc:linux 上早期的runtime,在 2013 年 Docker 刚发布的时候,就是采用 lxc 作为 runtime,Docker 把 LXC 复杂的容器创建与使用方式简化为 Docker 自己的一套命令体系。随着 Docker 的发展,原有的 LXC 不能满足 Docker 的需求,比如跨平台功能。
- Libcontainer:随着 Docker 的不断发展,重新定义容器的实现标准,将底层实现都抽象化到 Libcontainer 的接口。这就意味着,底层容器的实现方式变成了一种可变的方案,无论是使用 namespace、cgroups 技术抑或是使用 systemd 等其他方案,只要实现了 Libcontainer 定义的一组接口,Docker 都可以运行。这也为 Docker 实现全面的跨平台带来了可能。
- runc:早期 libcontainer 是 Docker 公司控制的一个开源项目,OCI 的成立后,Docker 把 libcontainer 项目移交给了 OCI 组织,runC 就是在 libcontainer 的基础上进化而来,目前 Docker 默认的 runtime, runc 遵守 OCI 规范。
- rkt:是 CoreOS 开发的容器 runtime,也符合 OCI 规范,所以使用 rktruntime 也可以运行 Docker 容器。
1.10.3 容器管理工具
管理工具连接 runtime 与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给 runtime 执行。lxc 是 lxd 的管理工具。Runc 的管理工具是 docker engine,docker engine 包含后台 deamon 和 cli 两部分,大家经常提到的 Docker 就是指的 docker engine。Rkt 的管理工具是 rkt cli。
1.10.4 镜像仓库 Registry
统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库。
- Docker hub:docker官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用
- 阿里云,网易等第三方镜像的公共仓库
- Image registry:docker 官方提供的私有仓库部署工具,无 web 管理界面,目前使用较少。
- Harbor:vmware 提供的自带web界面自带认证功能的镜像私有仓库,目前有很多公司使用
1.10.5 容器编排工具
当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎。容器编排通常包括容器管理、调度、集群定义和服务发现等功能:
- Docker compose:docker 官方实现单机的容器的编排工具。
- Docker swarm:docker 官方开发的容器编排引擎,支持 overlay network。
- Mesos+Marathon:Mesos 是 Apache 下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos 最初是由加州大学伯克利分校的 AMPLab 开发的,后在 Twitter 得到广泛使用。通用的集群组员调度平台,mesos(资源分配) 与 marathon(容器编排平台) 一起提供容器编排引擎功能。
- Kubernetes:google 领导开发的容器编排引擎,内部项目为 Borg,且其同时支持 docker 和 CoreOS,当前已成为容器编排工具事实上的标准。