如何使用Docker和Ansible来实现持续交付/持续部署

18

我对配置管理和部署工具还不熟悉。我需要为一个我曾经参与过的最有趣的项目之一实现连续交付/连续部署工具。

首先,就个人而言,我对AWS感到舒适,我知道Ansible是什么,它背后的逻辑和目的。我对Docker的理解不够深入,但我有这个想法。我查阅了很多互联网资源,但是我无法获得整体情况。

我的困扰是它们如何结合在一起。使用Ansible,我可以管理基础设施作为代码;构建EC2实例,安装软件包……我甚至可以通过拉取其代码、修改配置文件并启动Web服务器来部署完整的应用程序。Docker本身是一个打包应用程序的工具,并确保它可以在任何部署之处运行。

我的问题是:

Docker(或Ansible和Docker)如何扩展持续集成流程呢?

假设我们有一个源代码仓库,团队成员完成一个功能的工作并推送他们的工作。Jenkins检测到此情况,运行所有的验收/单元/集成测试套件,如果全部通过,则将其声明为稳定版本。那么Docker在这里起什么作用呢?我的意思是,当团队推送他们的工作时,Jenkins是否必须拉取应用程序中编码的Docker文件源代码,构建应用程序的映像,并启动容器并针对它运行所有测试,还是以传统方式运行所有测试,如果一切正常,则从Docker 文件中构建Docker镜像并将其保存在私有位置中?Jenkins应该使用x.y.z标记最终的映像吗?

Docker容器配置:

假设我们有一个由 Jenkins 构建的图像存储在某个地方,如何处理将相同的图像部署到不同的环境中,甚至包括不同的配置参数( Vhosts 配置、DB 主机、Queues URLs、S3 终端等)?最灵活的方法是什么,而不违反 Docker 原则?这些配置在构建图像时是否备份,或者基于它的容器启动时备份,如果是,它们是如何注入的? Ansible 和 Docker: Ansible 提供了一个 Docker 模块来管理 Docker 容器。假设我解决了上述提到的问题,当我想要部署我的应用程序的新版本 x.t.z 时,我告诉 Ansible 从存储位置拉取该图像,启动应用程序容器,那么如何注入配置设置!? Ansible 是否必须登录 Docker 图像,在其运行之前(听起来这很疯狂)并像传统主机一样使用其 Jinja2 模板?如果不是,这个问题是如何处理的?
抱歉,如果问题很长,或者我拼写错了什么,但这是我大声思考的结果。我被卡了两个星期,我想不出正确的工作流程。我希望这可以成为未来读者的参考。
请分享您的经验和解决方案,因为这似乎是一个常见的工作流程。

1
Ansible + Docker == 魔法!这是一篇很棒的博客文章:https://developer.rackspace.com/blog/ansible-and-docker/,同时也有一个专门介绍Ansible + Docker的章节在http://www.ansiblefordevops.com/。 - Homer6
3个回答

5
我希望分段回答。
Docker(或Ansible和Docker)如何扩展持续集成流程?
由于docker镜像在任何地方都是相同的,您可以将docker镜像用作生产镜像。因此,当有人提交代码时,您会构建docker镜像并对其运行测试。当所有测试都通过时,您会相应地标记该镜像。由于docker速度很快,这是可行的工作流程。此外,docker更改是增量的;因此,您的镜像对存储的影响很小。当您的测试失败时,您也可以选择保存该镜像。以这种方式,开发人员将拉取该镜像并轻松地调查为什么测试失败。开发人员也可以选择在他们的机器上运行测试,因为jenkins中的docker镜像和他们的机器上的镜像没有区别。
这带来了什么?所有开发人员将拥有相同的环境,相同版本的所有软件,因为您决定在docker镜像中使用哪个软件版本。我遇到过由于开发人员机器之间的差异而导致的错误。例如,在相同的操作系统中,unicode设置可能会影响您的代码。但是在docker镜像中,所有开发人员都将针对相同的设置和相同版本的软件进行测试。
Docker容器配置:
如果您正在使用私有仓库(应该使用),那么配置更改不会对硬盘空间产生太大影响。因此,除了安全配置(如数据库密码)外,您可以将配置更改应用于Docker镜像(将配置烘焙到容器中)。然后,您可以使用Ansible在启动前/后使用环境变量或Docker卷将未存储的配置应用于部署的镜像。

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

没有,ansible不需要登录Docker镜像,但是可以使用Jinja2模板来更改dockerfile。您可以使用模板更改dockerfile,并将配置注入到不同的文件中。根据需要设置标签,以配置镜像进行部署。

1
我没有理解Ansible的应用场景?!它是用于编排吗?! - another geek

4
关于您关于如何使用相同的Docker镜像处理多个环境配置的问题,我计划使用诸如Consul之类的服务发现工具作为集中式配置/属性管理工具。因此,当您启动容器时,设置一个ENV变量告诉它是什么应用程序(appID),以及它应该使用哪个环境配置(例如:MyApplication:Dev),它将在启动时从Consul中获取其配置。我仍然需要调查Consul周围的安全性(例如,如果我们在其中存储DB连接凭据,我们如何限制谁可以查询/更新这些值)。我不想仅仅将其用于容器,而是所有应用程序。另一个很酷的功能是更改Consul中的配置值,并在应用程序中添加钩子以立即应用更改(例如,在您的应用程序上提供REST端点以推送更改并动态应用它)。当然,您的应用程序必须编写支持此功能!

您可能会对查看Martin Fowler的博客文章感兴趣,其中涉及不可变基础设施Phoenix服务器


1
尽管不是完整的解决方案,我有两个建议来解决你的问题。虽然它们可能不完美,但这些是我们在工作流程中使用的实践,并且到目前为止已经证明有效。
  1. 定义不同的环境 - 假设您为每个启动的环境编写了不同的Ansible角色,我们定义一个环境变量来设置我们希望容器所属的环境。然后,我们使用设置在容器中的env变量从S3存储桶中下载适当的配置文件,并在构建代码时将这些参数注入其中。
  2. Ansible不需要登录到docker应用程序中,但解决方案有点棘手。我尝试过两种解决此问题的方法,但都不理想。第一种方法是在docker镜像命令行中下载配置文件,并在容器启动时构建应用程序。虽然这个解决方案可行,但它违反了Docker的理念,并使镜像极易出现构建错误。另一个解决方案是向您的docker hub仓库推送多个镜像,然后根据手头的环境拉取适当的镜像。

总的来说,我曾经尝试使用Ansible来完全启动我们的应用程序,但是这是一场噩梦,许多配置步骤非常棘手,当你试图将它们作为一个playbook实现时,会变得更加棘手。当我改为仅使用Ansible来维护服务器,并使用Docker部署应用程序时,事情变得更加容易。


刚开始时,最好将Docker视为一种应用程序打包技术。这有助于解释为什么Ansible非常适合它。在最简单的情况下,需要安装Docker并启动容器。最后,我建议您了解一些支持直接部署Docker应用程序的新兴技术:Docker Swarm、Kubernetes和Marathon/Mesos。尽管与Ansible相比更加复杂,但具有其他值得探索的优点。 - Mark O'Connor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接