[关闭]
@babydragon 2015-10-12T13:34:03.000000Z 字数 1517 阅读 2123

IFTTT使用Docker作为开发环境实践

原创 docker


IFTTT正在将基础设施容器化,在此过程中,他们首先尝试了将开发环境容器化。本文列举了一些方案和实施过程中遇到的问题。

由于IFTTT工程师都使用苹果电脑,因此该方案没有考虑跨平台。同时,整个流程对应的脚本,IFTTT已经创建了一个开源项目Dash

基础软件安装

Dash项目提供了一个安装脚本,可以一键完成基础软件的安装。

  1. bash <(curl -fsSL https://raw.githubusercontent.com/IFTTT/dash/master/bin/bootstrap)

该脚本的主要功能,是安装HomebrewAnsible,拉取Dash仓库内容。然后需要通过Ansible来安装和配置所有容器化环境需要依赖的组件,包括:

创建Docker Machine

首先需要通过docker-machine命令创建Docker Machine。然后,需要将这个脚本复制到新创建的虚拟机中并执行。这样就能基本完成Docker Machine的创建。

前文提到的脚本,其主要功能是将Virtual Box的硬盘共享(vboxfs)修改成NFS方式。然后修改虚拟机DNS到自定义的DNS服务器(用于解析开发环境使用的.dev域名)。

使用容器进行开发

使用容器进行开发和传统开发方式类似:编写代码、运行代码、执行测试。但是,随着应用依赖的复杂,按照传统开发方式(直接在本机或者虚拟机上进行开发和测试),需要在机器上安装各种依赖软件,开发人员可能会在这些依赖软件的配置、版本上花费大量的时间。尤其是需要测试依赖软件/中间件的兼容性时。

容器化开发方式,则可以直接使用已有的镜像,快速部署起应用需要的依赖。同时,一个镜像可以快速启动多个不同的容器,这对于相同应用需要测试不同配置的场景是非常有用的。对于更加复杂的依赖,Docker提供了Compose工具,可以通过一个简单的yaml,定义应用对应的dockerfile和其依赖(dockerfile或者镜像的形式),Compose会根据这些定义,按照顺序启动这些容器,并关联这些容器。

浏览器访问和容器间交互

通过前面几个步骤,应用已经在容器中启动完毕。然后就是需要通过浏览器来进行验证。

由于容器的隔离性,在容器中的应用之间相互隔离,因此需要访问应用,不同于直接在本机上进行部署,需要一些额外的操作。

在基础软件安装步骤中,已经包含了一个DNS安装的步骤。通过这个DNS,可以将开发环境的域名解析到对应的Docker Machine中。但是,由于Docker容器的网络配置,默认采用桥接的方式,并且每个容器会随机分配内网IP。如果采用端口重定向的方式,直接将容器中的服务端口暴露到虚拟机中,可能会遇到端口冲突的问题。

IFTTT使用了Nginx反向代理容器。该容器绑定了虚拟机(Docker Machine)中的80端口,并且可以通过传递启动环境变量的方式,自动将请求转发到对应的容器中去。采用了这种方式,还可以防止容器之间循环依赖的出现。所有的域名都通过这个反向代理进行转发,应用之间的依赖可以通过反向代理中定义虚拟主机(Virtual Host)的方式关联到容器。如果一个域名没有对应的容器,反向代理容器会返回503错误。

总结

容器化和Docker工具的结合,可以帮助解决部分开发自测是时常遇到的依赖问题。同时,解决了开发环境容器化之后,也是生产环境容器化的一个实践。如果后续希望能够将容器技术应用到生产环境,不妨从开发环境开始入手。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注