Docker和Ansible如何配合实现Continuos Delivery / Continuous Deployment

我不熟悉configurationpipe理和部署工具。 我必须实施一个持续交付/持续部署工具,用于我曾经投入的最有趣的项目之一。

首先,我个人对AWS感到满意,我知道Ansible是什么,它背后的逻辑和目的。 我对Docker没有同样的理解,但是我明白了。 我经历了很多互联网资源,但是我无法得到大局。

我一直在挣扎的是他们如何融合在一起。 使用Ansible ,我可以将我的基础架构作为代码来pipe理; 构buildEC2实例,安装软件包…我甚至可以通过拉取代码,修改configuration文件和启动Web服务器来部署完整的应用程序。 Docker本身就是一个打包应用程序的工具,并确保它可以在你部署的任何地方运行。

我的问题是:

Docker(或Ansible和Docker)如何扩展持续集成过程!

假设我们有一个源代码库,团队成员完成了一个function的工作,他们推动他们的工作。 jenkins检测到这一点,运行所有的验收/单元/集成testing套件,如果他们都通过了,它宣称它是一个稳定的构build。 Docker如何适应这里? 我的意思是,当团队推动他们的工作时,Jenkins是否必须拉取应用程序中编码的Docker文件源,构build应用程序的图像,启动容器并运行所有testing,或者运行经典testing一切都很好,那么它会从Docker文件构buildDocker镜像并将其保存在一个私有的地方? jenkins应该使用xyz标记最终的图像!

Docker容器configuration:

假设我们有Jenkins构build的映像存储在某个地方,如何处理将相同的映像部署到不同的环境中,甚至是不同的configuration参数(Vhostsconfiguration,数据库主机,队列URL,S3端点等等)什么是最灵活的方式来处理这个问题而不破坏Docker原则? 这些configuration是否在构build时或者基于它的容器开始时支持在映像中,如果是的话,它们是如何被注入的?

Ansible和Docker

Ansible提供了一个Docker模块来pipe理Docker容器。 假设我解决了上面提到的问题,当我想部署我的应用程序的新版本xtz时,我告诉Ansible将它从存储的位置拉出来,启动应用程序容器,那么如何注入configuration设置? Ansible在运行之前是否需要loginDocker镜像(这听起来令人费解),并且使用Jinja2模板和经典主机一样! 如果没有,这是如何处理?!

对不起,如果这是一个很长的问题,或者我拼错了一些东西,但这是我的想法。 我在过去的两周被封锁了,我无法弄清楚正确的工作stream程。 我希望这是未来读者的参考。

请阅读您的经验和解决scheme非常有帮助,因为这看起来像一个常见的工作stream程。 先谢谢你。 任何帮助深表感谢。

我想分开回答

Docker(或Ansible和Docker)如何扩展持续集成过程!

由于docker图像在任何地方都是一样的,所以您可以像使用生产图像一样使用docker图像。 因此,当有人提交代码时,您将构build您的泊坞窗图像。 你对它进行testing。 当所有的testing通过,你相应地标记该图像。 由于docker速度很快,这是一个可行的工作stream程。 docker工人的变化也是增量的。 因此,您的图像将对存储影响最小。 当你的testing失败的时候,你也可以select保存那个图片。 通过这种方式,开发人员将拉取该图像,并轻松调查您的testing失败的原因。 开发人员也可能select在他们的机器上运行testing,因为jenkins和他们的机器中的docker图像没有什么不同。

由于您决定在Docker镜像中使用哪一个软件,所有开发人员将拥有相同的环境,相同版本的所有软件。 我遇到了由于开发人员机器之间的差异而导致的错误。 例如,在相同的操作系统中,unicode设置可能会影响您的代码。 但在docker图像中,所有的开发人员都将testing相同的设置,相同的版本软件。

Docker容器configuration:

如果您正在使用私有存储库,并且您应该使用一个,那么configuration更改不会太多影响硬盘空间。 因此,除安全性configuration(如db密码)之外,可以将configuration更改应用于泊坞窗映像( 将configuration烘焙到容器中 )。 然后,您可以使用环境variables或Docker卷,在启动之前/之后使用适当的方式将未存储的configuration应用于已部署的映像。

https://dantehranian.wordpress.com/2015/03/25/how-should-i-get-application-configuration-into-my-docker-containers/

Ansible在运行之前是否需要loginDocker镜像(这听起来令人费解),并且使用Jinja2模板和经典主机一样! 如果没有,这是如何处理?!

不,ansible不会loginDocker镜像,但可以使用Jinja2模板来更改dockerfile。 您可以使用模板更改dockerfile,并可以将您的configuration注入到不同的文件。 相应地标记文件,并将图像configuration为旋转起来。

关于使用同一个Docker镜像处理多个环境configuration的问题,我一直在计划使用Consul这样的Service Discovery工具作为集中的configuration/属性pipe理工具。 所以,当你启动你的容器时,你需要设置一个ENVvariables来告诉它它是什么应用程序(appID),以及它应该使用什么样的环境configuration(例如:MyApplication:Dev),并且它会在启动时从Consul中取出它的configuration。 我仍然需要调查Consul周围的安全性(就好像我们正在存储数据库连接证书,例如,我们如何限制谁可以查询/更新这些值)。 我不想只用这个容器,但一般的应用程序。 另一个很酷的function是改变Consul中的configuration值,并且有一个挂钩返回到你的应用程序来立即应用这些改变(也许就像你的应用程序中的REST端点来推动改变并dynamic应用它)。 当然,你的应用程序必须写出来支持这个!

您可能有兴趣查看Martin Fowler关于不可变基础架构和Phoenix服务器的博客文章。

虽然不是一个完整的解决scheme,但我有两个问题的build议。 虽然他们可能不完美,但这些是我们在工作stream程中使用的做法,并且certificate自己到目前为止。

  1. 定义不同的环境 – 假设您为每个启动的环境编写了不同的Ansibleangular色,我们定义了一个环境variables来设置我们希望容器所属的环境。 然后,我们使用之前设置的envvariables,将一个合适的configuration文件从S3存储桶下载到容器中(如果您提供AWS creds或为您的服务器提供IAMangular色,这应该是可能的),并在构build代码时将这些参数注入代码中。

  2. Ansible不需要login泊坞窗应用程序,但解决scheme有点棘手。 我已经尝试了两种解决这个问题的方法,但都不理想。 第一个是将configuration文件作为docker image命令行的一部分下载,并在容器启动时构build应用程序。 虽然这个解决scheme的工作原理 – 它违反了Docker的理念,并使图像极易造成错误。 另一个解决scheme是将几张图片推送到您的Docker Hub仓库,然后根据当前的环境提取适当的图像。

在更广泛的笔触中,我已经试过用Ansible完全启动我们的应用程序,它是地狱,许多configuration步骤是棘手的,当你试图实现他们作为一个剧本变得棘手。 当我转向使用Ansible单独维护服务器,并且使用Docker部署应用程序时,事情变得更加简单。