容器在“基础设施即代码(Infrastructure as Code)”中有什么意义?
一句话概括的话,容器意味着一切。
为什么这么说呢?当你在比较单体应用和微服务时,一定会有一些权衡和取舍。一方面,从单体模型转移到微服务模型,能够将进程分离成独立的工作单元。这使得开发者们可以将注意力放在单一功能上,并且有助于测试和扩展。另一方面,由于将所有的东西都分成了单独的服务,过去你只需管理一个单一部署单元的基础设施,现在你却必须管理每一个服务的基础设施。正是为了应对这一挑战,“基础设施即代码”作为一个解决方案便诞生了。
容器技术已经存在一段时间了,它以不同的形式实现且已取得不同程度的成功。这项技术从上世纪80年代初的chroot开始,并在之后带来了如Virtuozzo和Sysjail这样形式的产品。直到2013年Docker的诞生和其后的迅猛发展,一切才化零为整,才真正开始深刻影响了应用程序在容器模型中的开发、测试和部署。
“基础设施即代码”的实践,和Docker容器一起,象征着一个最具颠覆性和创新性的改变,它影响了我们今天开发和发布软件的过程。
什么是“基础设施即代码”(IaC)?
在深入探讨IaC及它和容器的关系之前,先看看IaC的具体含义吧。IaC指的是开发应用程序本身的同时,对硬件和操作系统需求的供应编写脚本的实践。通常,管理这些脚本的方式和软件代码库类似,包括版本控制和自动化测试。
当正确执行时,脚本将代替管理员登陆新机器并进行配置。这些脚本描述了新机器的理想状态,并会执行必要的步骤来配置机器,以实现这一状态。
“基础设施即代码”带来的核心便利
IaC旨在利用系统配置来缓解最常见的痛点,特别是以前配置一个新环境通常需要花费大量的时间。每一个环境都需要单独配置,且如果某处出现错误,通常需重新进行整个过程。IaC消除了这些痛点,并向开发者和运维人员提供了以下额外的便利:
-
重新使用常见的脚本变得相对简单了。
-
整个供应过程可实现自动化,连供应硬件都可以作为持续交付过程的一部分。
-
版本控制,可以根据需要测试和回滚较新的配置。
-
同行审查和脚本强化。不需手动地从文档或内存中配置,就可以对脚本进行审查、更新和持续改进。
-
文档是自动的,因为本质上它就是脚本本身。
-
过程可以被测试。
容器,将“基础设施即代码”带向新高度
作为开发者,我想我们都遇到过诸如“我不知道啊,反正它在我的机器上工作!”这样的情况。往好处说,这是一种诙谐有趣的说法;但往坏处说,它代表了我们每天都要处理的一个很大的问题。Docker这一革新性的技术不仅有效消除了开发者的这些担忧,它还使得IaC在开发过程中成为一个核心组件。
为了更好地说明这一点,让我们想象一个已经Docker化的Web应用,它有简单的UI界面。该应用将有一个类似于如下所示的Dockerfile,具体说明了包含该应用的容器的配置信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
FROM ubuntu:
12.04
# Install dependencies
RUN apt-get update -y && apt-get install -y git curl apache2 php5 libapache2-mod-php5 php5-mcrypt php5-mysql
# Install app
RUN rm -rf /var/www/*
ADD src /var/www
# Configure apache
RUN a2enmod rewrite
RUN chown -R www-data:www-data /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE
80
CMD [
"/usr/sbin/apache2"
,
"-D"
,
"FOREGROUND"
]
|
如果你熟悉Docker,这是一个相当典型和简单的Dockerfile,你应该已经知道了它是什么。如果你不熟悉Dockerfile,那么可以理解为,这个文件将用于创建一个Docker镜像,它本质上是一个用来创建容器的模板。Docker容器创建完毕后,镜像将用于构建容器,于是一个自包含的应用程序就这么产生了。从开发工作站到高可用云集群,它可以在已经将其实例化的任何机器上使用。
我们看一下文件中的几个关键参数,并看看它们在过程中实现了什么:
1
|
FROM ubuntu:
12.04
|
这一行是从Docker Hub中拉取一个Ubuntu Docker镜像,作为新容器的基础。Docker Hub是主要的Docker镜像在线仓库。如果你访问Docker Hub并在其中搜索这个镜像,你就能找到Ubuntu镜像仓库了。这是一个官方镜像,是由Docker支持的专门团队负责管理的。使用该镜像的好处是,当你的底层技术出现问题时,很有可能已经有人开发出了修复补丁并实现了它,并且你所需要做的只是更新你的Dockerfile到新版本,重建你的镜像,并再一次测试和部署你的容器。
Dockerfile中剩下的几行将使用apt-get在基础镜像上安装各种软件包。将应用程序的源添加到/var/www目录,配置Apache,然后将容器的公开端口设置为端口80。
最后,当容器搭建好后运行CMD指令,这将初始化Apache服务器,打开它以接收http请求。
这是“基础设施即代码”最简单的形式。这就是它的全部。
此时,假如你已经在工作站上安装并运行Docker了,你可以从Dockerfile所在的目录中执行以下指令:
1
|
$ docker build -t my_demo_application:v0.
1
|
Docker将为你构建镜像,将其命名为my_demo_application并加标签v0.1,v0.1实际是一个版本编号。镜像创建后,您可以使用以下命令获取该镜像,并使用该镜像创建容器。
1
|
$ docker run -d my_demo_application:v0.
1
|
就像这样,你就可以在本地机器上运行你的应用程序,或者在你选择的任何硬件上运行它。
结语
一份简单的Dockerfile,可以检查你的源代码,指定应用程序的环境、配置和访问路径,这就是Docker和“基础设施即代码”的最简单形式。同时你可以使用docker compose来定义多层次服务的组合应用,每个服务都包含一个独立的Dockerfile或者导入Docker仓库的一个镜像。你还可以使用docker compose的增强版本rancher compose,这是微服务部署利器,可以让我们更加便利得玩转rolling upgrade等高级特性。