2.4 容器镜像库:Docker Hub
我们的CircleCI配置中包含了一些命令,它们调用Docker来构建应用的容器镜像,例如docker build和docker push。本节,我们将首先介绍为什么Docker是DevOps的重要组成部分,然后将仔细研究容器镜像是如何创建的。
容器,特别是Docker容器,之所以流行,是因为它有助于解决代码依赖管理的复杂问题。应用一般都要依赖外部的库和包,以避免重新“造轮子”。为了方便维护,运维人员需要在系统上共享这些库和包。如果十个应用都用到了同一个包,而在这个包中发现了问题,则只需要更新这一个包,所有应用就都能从更新中受益。
当各式各样的应用需要使用同一个库的不同版本时,问题就出现了。例如,一个系统默认使用了OpenSSL 0.9,如果一个包需要在这个系统上使用OpenSSL 1.2,那么它就无法工作。基础系统难道需要安装所有版本的OpenSSL吗?这些版本会不会发生冲突?答案没有那么简单,这些问题让开发人员和运维人员头痛不已。这个问题有一些解决方案,它们的基本思路都一样,就是应用应该分开管理它们各自的依赖。容器提供的包管理机制实现了这种隔离。
你还是Docker新手?
在本章中,我们只是重点使用了Docker容器有限的几个功能来打包发票应用。要想全面了解Docker,可参考Jeff Nickoloff所著的Docker in Action(Manning出版社于2016年出版)。
正如我们之前讨论的CircleCI配置文件展现的那样,Docker容器是根据一个名为Dockerfile的配置文件来构建的。Docker对冗长的容器构建、发布和运行任务进行了不错的抽象。代码清单2.3就是构建发票应用容器镜像的Dockerfile。麻雀虽小,五脏俱全,文件虽短,却隐藏着惊人的复杂性。我们来研究一下它做了些什么。
我们来研究一下代码清单 2.3:
•FROM指令表明了用来构建容器镜像的基础容器镜像。Docker容器有层的概念,允许在一个容器基础之上再增加信息。这里,我们使用基于BusyBox的容器,这个容器是最小的通用Linux工具集合。
•RUN指令创建了一个名为“app”的用户,下面的USER指令在运行应用时会用到这个用户。
•COPY指令会在容器中加载发票应用的可执行文件。这条指令将本地文件bin/invoicer(相对于构建操作运行的路径)放到容器中的/bin/invoicer这个位置。
•EXPOSE和ENTRYPOINT指令在容器启动时运行发票应用,让外来者可以访问它的 8080 端口。
要用这份配置构建容器,先要将发票应用的源代码编译成静态二进制文件,并拷贝到bin/invoicer,然后使用docker build命令创建容器。
接下来通过build命令将发票应用二进制文件打包进Docker容器。
这就是你所要了解的关于Docker构建应用容器的全部。CircleCI会执行一模一样的命令,然后将容器镜像推送到Docker Hub。
如果要推送到Docker Hub,就需要一个在Docker Hub官网(链接2.5)上的账户和一个名为“securingdevops/invoicer”(或是和你的GitHub用户名及仓库名相匹配的其他名字)的仓库。CircleCI需要这个账户的凭证来登录Docker Hub,因此,在创建好账户之后,转到CircleCI中仓库的设置部分,将环境变量DOCKER_USER和DOCKER_PASS设置为Docker Hub的用户名和密码。
安全提示
你不应该在CircleCI中共享自己的Docker Hub凭证。在第6章中,我们将讨论如何使用拥有最低权限的服务专用账户来达到这个目的。
大多数CI平台都支持在不泄露隐私的情况下使用敏感信息的机制。CircleCI和Travis CI都不允许将包含隐私的环境变量暴露给来自代码仓库之外(复刻的代码仓库而非特性分支)的拉取请求,以此来保护这些环境变量。
我们来总结一下截至目前实现的内容。你有了一个在变更提出时通过webhook调用CI平台的代码仓库。测试会自动执行,帮助评审人员验证这些变更不会破坏功能。如果变更被批准了,它就会被合并到master分支中。然后CI平台会被第二次调用来构建应用的容器。容器被上传到远程容器仓库,任何人都可以获取它。
内部CI
即使是闭门造车,完全在内部运营流水线,也能达到同样的效果。用私有的GitLab实例代替GitHub,用Jenkins代替CircleCI,运行自己的Docker Registry服务器来保存容器,就可以在私有的基础设施上实现同样的工作流了(但搭建这条流水线需要花费更多的时间)。
无论你用哪种方式实现流水线,其核心思路都是一样的。那就是将应用在每次变更时都要执行的测试和构建步骤自动化,在保障稳定性的同时加速变更集成。
CI流水线实现了发票应用测试和打包的完全自动化。在必要时,流水线每天可以运行数百次,它能可靠地将代码变成可以发布到生产环境中的应用容器。接下来就要搭建托管和运行容器的基础设施了。