使用 Docker 进行持续交付实践(评论和视频)

我们将以基于技术总监最新演讲的出版物开始我们的博客 迪斯托尔 (德米特里·斯托利亚罗夫)。 所有这些都发生在 2016 年的各种专业活动中,并致力于 DevOps 和 Docker 主题。 我们已经在 Badoo 办公室观看了 Docker 莫斯科会议的一段视频 已发表 在线的。 新的报告将附有传达报告要点的文章。 所以…

31月XNUMX日 会议 根会议 2016作为“俄罗斯互联网技术”节(RIT++ 2016)的一部分,“持续部署和部署”部分以“Docker 持续交付最佳实践”报告作为开场。 它总结并系统化了使用 Docker 和其他开源产品构建持续交付 (CD) 流程的最佳实践。 我们在生产中使用这些解决方案,这使我们能够依赖实践经验。

使用 Docker 进行持续交付实践(评论和视频)

如果你有机会花一个小时 报告视频,我们建议完整观看。 否则,以下是文本形式的主要摘要。

使用 Docker 持续交付

下面 连续交付 我们了解 Git 存储库中的应用程序代码首先进入生产环境,然后最终进入存档的事件链。 她看起来像这样: Git → 构建 → 测试 → 发布 → 运行.

使用 Docker 进行持续交付实践(评论和视频)
报告的大部分内容致力于构建阶段(应用程序组装),并简要讨论了发布和操作主题。 我们将讨论问题和允许您解决问题的模式,这些模式的具体实现可能会有所不同。

为什么这里需要 Docker? 我们决定在这个开源工具的背景下讨论持续交付实践并不是没有原因的。 尽管整个报告都致力于其使用,但在考虑应用程序代码推出的主要模式时,揭示了许多原因。

主要推出模式

因此,当我们推出应用程序的新版本时,我们肯定会面临 停机问题,在生产服务器切换期间生成。 从旧版本应用程序到新版本应用程序的流量无法立即切换:首先,我们必须确保新版本不仅已成功下载,而且已“预热”(即完全准备好服务请求)。

使用 Docker 进行持续交付实践(评论和视频)
因此,在一段时间内,应用程序的两个版本(旧版和新版)将同时运行。 这会自动导致 共享资源冲突:网络、文件系统、IPC等。 使用 Docker,可以通过在单独的容器中运行不同版本的应用程序来轻松解决此问题,从而在同一主机(服务器/虚拟机)内保证资源隔离。 当然,你可以在没有绝缘的情况下使用一些技巧,但是如果有一个现成的方便的工具,那么就有相反的原因 - 不要忽视它。

容器化在部署时还提供了许多其他好处。 任何应用程序都取决于 具体版本 (或版本范围) 口译员、模块/扩展的可用性等,以及它们的版本。 这不仅适用于直接可执行环境,还适用于整个环境,包括 系统软件 及其版本(取决于所使用的 Linux 发行版)。 由于容器中不仅包含应用程序代码,还预装了所需版本的系统和应用软件,因此您可以忘记依赖关系的问题。

我们推广 主要推出模式 新版本考虑了以下因素:

  1. 首先,旧版本的应用程序在第一个容器中运行。
  2. 然后,新版本将在第二个容器中推出并“预热”。 值得注意的是,这个新版本本身可能不仅包含更新的应用程序代码,还包含其任何依赖项以及系统组件(例如,新版本的 OpenSSL 或整个发行版)。
  3. 当新版本完全准备好服务请求时,流量将从第一个容器切换到第二个容器。
  4. 旧版本现在可以停止了。

这种在单独的容器中部署不同版本的应用程序的方法提供了另一个便利 - 快速回滚 到旧版本(毕竟,将流量切换到所需的容器就足够了)。

使用 Docker 进行持续交付实践(评论和视频)
最后的第一个建议听起来连队长都挑不出毛病:“[使用 Docker 组织持续交付时] 使用 Docker [并了解它给出了什么]” 请记住,这并不是解决所有问题的灵丹妙药,而是提供良好基础的工具。

再现性

“再现性”是指操作应用程序时遇到的一系列普遍问题。 我们正在谈论这样的案例:

  • 质量部门检查的舞台脚本必须在生产中准确复制。
  • 应用程序发布在可以从不同存储库镜像接收包的服务器上(随着时间的推移,它们会更新,并且已安装应用程序的版本也随之更新)。
  • “一切都适合我本地!” (......并且不允许开发人员投入生产。)
  • 您需要检查旧(存档)版本中的某些内容。
  • ...

它们的一般本质归结为这样一个事实:完全符合所使用的环境(以及缺乏人为因素)是必要的。 如何保证重现性? 制作 Docker 镜像 基于 Git 的代码,然后将它们用于任何任务:在测试站点、生产中、程序员的本地计算机上......同时,尽量减少所执行的操作也很重要 组装图像:越简单,出现错误的可能性就越小。

基础设施就是代码

如果基础设施要求(服务器软件的可用性、版本等)没有正式化和“编程”,那么任何应用程序更新的推出都可能导致灾难性的后果。 例如,在暂存阶段,您已经切换到 PHP 7.0 并相应地重写了代码 - 那么它在生产中与一些旧 PHP (5.5) 的出现肯定会让某人感到惊讶。 您可能不会忘记解释器版本中的重大更改,但“细节决定成败”:令人惊讶的可能是任何依赖项的微小更新。

解决这个问题的方法被称为 IaC(基础设施即代码,“基础设施即代码”) 并涉及将基础设施需求与应用程序代码一起存储。 使用它,开发人员和 DevOps 专家可以使用同一个 Git 应用程序存储库,但位于其不同部分。 根据此代码,在 Git 中创建了一个 Docker 映像,在其中部署应用程序时考虑了基础设施的所有细节。 简单来说,组装镜像的脚本(规则)应该与源代码在同一个存储库中并合并在一起。

使用 Docker 进行持续交付实践(评论和视频)

在多层应用程序架构的情况下 - 例如,有 nginx,它位于已在 Docker 容器内运行的应用程序前面 - 必须从 Git 中的代码为每一层创建 Docker 镜像。 然后,第一个映像将包含一个具有解释器和其他“紧密”依赖项的应用程序,第二个映像将包含上游 nginx。

Docker 镜像,与 Git 通信

我们将从 Git 收集的所有 Docker 镜像分为两类:临时的和发布的。 临时图像 由 Git 中的分支名称标记,可以被下一次提交覆盖,并且仅用于预览(不适用于生产)。 这是它们与发布版本的主要区别:您永远不知道其中有哪个具体提交。

收集到临时映像中是有意义的:主分支(您可以自动将其推出到单独的站点以不断查看主版本的当前版本)、具有版本的分支、特定创新的分支。

使用 Docker 进行持续交付实践(评论和视频)
当临时图像预览到需要转化为生产后,开发人员会打上一定的标签。 按标签自动收集 发布图片 (其标签对应于 Git 中的标签)并已推出到暂存阶段。 如果质量部门验证成功,则进入生产。

DAPP

所描述的一切(推出、镜像组装、后续维护)都可以使用 Bash 脚本和其他“临时”工具独立实现。 但如果这样做的话,那么到了某个时候,实施就会导致极大的复杂性和较差的可控性。 理解这一点后,我们开始创建自己的专用工作流实用程序来构建 CI/CD - DAPP.

它的源代码是用Ruby编写的,开源并发布在 GitHub上。 不幸的是,文档目前是该工具的最弱点,但我们正在努力解决它。 我们将不止一次地撰写和讨论 dapp,因为…… 我们真诚地迫不及待地想与整个感兴趣的社区分享其功能,但与此同时,发送您的问题和拉取请求和/或在 GitHub 上关注项目的开发。

13 年 2019 月 XNUMX 日更新: 目前是一个项目 DAPP 重命名为 韦尔夫,其代码已完全用 Go 重写,其文档也得到了显着改进。

Kubernetes

另一个已经在专业环境中获得广泛认可的现成开源工具是 Kubernetes,一个Docker管理集群。 它在运行基于 Docker 的项目中的使用主题超出了报告的范围,因此演示仅限于概述一些有趣的功能。

对于部署,Kubernetes 提供:

  • 就绪探针——检查新版本应用程序的就绪情况(将流量切换到它);
  • 滚动更新 - 容器集群中的顺序映像更新(关闭、更新、准备启动、流量切换);
  • 同步更新 - 使用不同的方法更新集群中的映像:首先更新一半容器,然后更新其余容器;
  • 金丝雀发布 - 在有限(少量)数量的容器上启动新映像以监视异常情况。

由于持续交付不仅仅是一个新版本的发布,Kubernetes对于后续的基础设施维护有很多能力:对所有容器的内置监控和日志记录、自动伸缩等。这一切都已经在工作,只是等待适当的时机。在您的流程中实施。

最终建议

  1. 使用 Docker。
  2. 创建满足您所有需求的应用程序的 Docker 映像。
  3. 遵循“基础设施就是代码”的原则。
  4. 将 Git 链接到 Docker。
  5. 规范推出顺序。
  6. 使用现成的平台(Kubernetes 或其他)。

视频和幻灯片

演出视频(约一小时) 发布在 YouTube 上 (报告本身从第 5 分钟开始 - 点击链接从此时开始播放).

报告介绍:

PS

我们博客上有关该主题的其他报告:

来源: habr.com

添加评论