容器基础
容器镜像
镜像是容器运行的基础,容器引擎服务可使用不同的镜像启动相应的容器。在容器出现错误后,能迅速通过 删除容器、启动新的容器来恢复服务,这都需要以容器镜像作为支撑技术 [15]。
镜像简介
镜像是由按层封装好的文件系统和描述镜像的元数据构成的文件系统包,包含应用所需要的系统、环境、配 置和应用本身等。镜像由开发者
构建好之后上传至镜像仓库,使用者获取镜像之后就可以使用镜像直接构建自己 的应用。由 Linux基金会主导开发的开放容器标准规范
(Open Container Initiative,OCI)于 2017 年发布 v1.0 版本 [16], 该标准将致力于统一容器运行时和镜像格式的规范。Docker 积极为 OCI做出重要贡献,开发并捐赠了大部分的 OCI代码,并作为项目维护者在定义运行时和镜像规范时做了建设性工作。与虚拟机
所用的系统镜像不同,容器镜像不仅没有 Linux系统内核,同时在格式上也有很大的区别。虚拟机 镜像是将一个完整系统封装成一个镜像文件,而容器镜像不是一个文件,而是分层存储的文件系统。#### 镜像特点
(1)分层存储
分层存储是容器镜像的主要特点之一,从图 2.1 可以看出,每个镜像都是由一系列的“镜像层”组成。当需 要修改镜像内的某个文件时,只会对最上方的读写层进行改动,不会覆盖下层已有文件系统的内容。当提交这个 修改生成新的镜像时,保存的内容仅为最上层可读写文件系统中被更新过的文件,这样就实现了在不同的容器镜 像间共享镜像层的效果。下图是一个简单的容器镜像示例,最上层是容器的读写层,剩余的是只读层。
(2)写时复制
容器镜像使用了写时复制 (Copy-on-Write) 的策略,在多个容器之间共享镜像,每个容器在启动的时候并不 需要单独复制一份镜像文件,而是将所有镜像层以只读的方式挂载到一个挂载点,再在上面覆盖一个可读写的容 器层。在未更改文件内容时,所有容器共享同一份数据,只有在容器运行过程中文件系统发生变化时,才会把变 化的文件内容写到可读写层,并隐藏只读层中的老版本文件。写时复制配合分层机制减少了镜像对磁盘空间的占 用和容器启动时间。
(3)内容寻址
在 Docker 1.10 版本后,引入了内容寻址存储的机制,根据文件的内容来索引镜像和镜像层。对镜像层的内 容计算校验和,生成一个内容哈希值,并以此哈希值作为镜像层的唯一标识。该机制提高了镜像的安全性
,并在 pull、push、load 和 save 操作后检测数据的完整性。(4)联合挂载
联合挂载技术可以在一个挂载点上同时挂载多个文件系统,将挂载点的原目录与被挂载内容进行整合,使得 最终可见的文件系统包含整合之后各层的文件和目录。实现这种联合挂载技术的文件系统通常被称为联合文件系 统 (Union Filesystem)。
联合挂载是用于将多个镜像层的文件系统挂载到一个挂载点来实现一个统一文件系统图的途径,是下层存 储驱动实现分层合并的方式。
镜像的构建
镜像作为容器运行的基础,有多种获取途径。其中一种是在镜像仓库中获取现成的镜像,包括公共仓库和私 有仓库;另一种是开发人员自己打包制作镜像。本节主要介绍两种如何制作并生成镜像的方法。
(1)docker build
这种构建方法基于 Dockerfile 来自动构建镜像,Dockerfile 的可读性和可理解性都较高。其机制为:每一行 都会基于上一层的中间容器来执行对应的修改命令,然后通过 docker build 提交,经过一次次循环,最终提交成 为目标镜像。构建镜像的 Dockerfile 示例如下:
FROM ubuntu:15.04 COPY . /ap
RUN make /[app](http://github5.com/search?f=p&wd=app)
CMD python /app/app.py
Dockerfile 中的每一行指令(COPY、RUN、CMD)都会生成新的一层,叠加在上一个指令生成的文件系统之上, 最后所有镜像层叠加就构成了镜像的文件系统。
(2)docker commit
这种构建镜像的方式,首先使用某一镜像启动容器,进入容器中完成需要的操作,最后在宿主机上执行 docker commit 命令,该命令会将此时的容器打包成一个新的镜像。这种制作新镜像的优点是修改便捷、构建的 镜像出现问题时容易排查解决。缺点在于不够透明、可维护性差。
镜像仓库
镜像仓库是镜像存储的位置,也是用来获得镜像的重要渠道之一。镜像仓库根据用途不同分为公共仓库和私 有仓库。
(1)公共仓库
公共仓库是面向整个互联网用户的仓库,典型的代表为 Docker Hub[17],目前已经包括了超过 15,000 的镜像。 大部分常用应用的镜像,都可以通过在 Docker Hub 中直接下载使用。
另外,用户也可以将自己创建好的镜像上传至公共仓库供其它的用户使用,软件厂商也可以以镜像形式发布 自己的软件。
(2)私有仓库 不是所有的镜像都适合在互联网进行发布共享,有时候有些含有敏感信息的镜像只能在团队内部共享使用。
因此,考虑到镜像的敏感性与网络的可用性和稳定性等因素,出现了私有仓库的使用场景,或者可以称之为 本地仓库。私有仓库是在一定范围内可访问的镜像仓库,典型的私有仓库实现代表为 Harbor[18]。
Harbor
Harbor 由 VMware 中国研发团队负责开发,旨在帮助用户迅速搭建一个企业级的 Registry 服务。它以 Docker Registry 为基础,提供了管理 UI、基于角色的访问控制、AD/LDAP集成、审计日志以及镜像漏洞扫描等功能。
Registry | 负责储存 Docker 镜像,并处理 docker push/pull 命令 |
---|---|
UI | 提供图形化界面,帮助用户管理 Registry 上的镜像,并对用户进行授权 |
Job Service | Harbor 的任务管理服务 |
DB | 提供数据库服务。负责储存用户权限、审计日志、镜像分组信息等数据 |
AD/LDAP | 提供统一的用户身份认证和权限控制 |
Log Collector | 负责收集其它组件的日志,供日后进行分析 |
Notary | 镜像内容审计,确保镜像真实性,可以选择是否集成 |
Clair | 负责进行镜像的脆弱性扫描,可以选择是否集成 |