在另一篇文章中,我们讨论了蓝绿部署。在本节中,我们将了解另一种部署策略,它具有相同的优势,但风险更低,并且通常会带来更好的洞察力。
持续集成(continuous integration)改变了我们开发软件的方式。但是 CI 环境与生产环境不同,综合测试并不总是足以揭示问题。有些问题只有在生产时才会出现,到那时,损害已经造成。金丝雀部署使我们能够在跳入之前测试水域。
什么是金丝雀部署
在软件工程中,金丝雀部署是分阶段发布的做法。我们首先向一小部分用户推出软件更新,以便他们进行测试并提供反馈。一旦更改被接受,更新就会发布给其他用户。
Canary 部署向我们展示了用户如何与现实世界中的应用程序变化进行交互。与蓝绿部署一样,金丝雀策略提供无停机升级和轻松回滚。与蓝绿不同,金丝雀部署更顺畅,故障影响有限。
发布与部署
一个金丝雀发布(canary release)是一个应用程序的早期构建。拆分稳定和开发分支是开源世界中的普遍策略。许多项目使用奇数/偶数编号方案将稳定版与非稳定版分开。
公司通常会发布其产品的金丝雀版本,希望精通技术或高级用户想要下载并试用它们。公司对其应用程序进行金丝雀发布的例子有 Mozilla 及其夜间和测试版 Firefox,以及谷歌及其 Chrome 的金丝雀发布渠道。
另一方面,在金丝雀部署中,我们在系统中安装更新并将用户分成两组。他们中的一小部分将转到金丝雀,而其余的则保留在旧版本中,作为控制。
稍后,一旦我们花时间评估 Canary 版本,我们就可以决定将其余用户迁移到 Canary 或将所有人回滚到旧版本。
金丝雀部署的工作原理
正如我们所见,金丝雀部署涉及同时运行应用程序的两个版本。我们将旧版本称为“稳定版”,将新版本称为“金丝雀”。我们有两种部署更新的方式:滚动部署和并行部署。
让我们看看它们是如何工作的。
滚动部署
在滚动部署中,我们以波次或阶段的形式安装更改——一次安装几台机器。其他人继续运行稳定版本。这是进行金丝雀部署的最直接方式。
一旦金丝雀在一台服务器上运行,一些用户就会开始看到更新。
在发生这种情况时,我们会观察升级后的机器的运行情况。我们检查错误和性能问题,并听取用户反馈。
随着我们对金丝雀越来越有信心,我们继续在其余机器上安装它,直到它们都运行最新版本。
如果我们检测到故障或得到令人失望的结果,我们可以通过将升级后的服务器回滚到初始状态来撤消更改。
并行部署
并行策略与蓝绿部署有很多共同之处。我们不是分阶段升级机器,而是创建一个全新的重复环境并在那里安装金丝雀版本。
假设应用程序在多台机器或容器、几个服务和一个数据库上运行。
为了进行部署,我们克隆硬件资源并安装更新。一旦金丝雀在新环境中运行,我们会将其展示给部分用户群。这通常使用路由器、负载均衡器、反向代理或应用程序中的某些其他业务逻辑发生。
与滚动部署一样,我们在逐渐将越来越多的用户从控制版本迁移的同时监控金丝雀。这个过程一直持续到我们检测到问题或所有用户都在金丝雀上。
部署完成后,我们移除控制环境以释放资源。金丝雀版本现在是新的稳定版。
金丝雀部署的好处
为什么要去实施金丝雀策略的麻烦?好处很多:
- A/B 测试:我们可以使用金丝雀进行 A/B 测试。换句话说,我们向用户提供了两种替代方案,看看哪个能获得更好的接收效果。
- 容量测试:无法测试大型生产环境的容量。对于金丝雀部署,容量测试是内置的。随着我们慢慢地将用户迁移到金丝雀,我们系统中的任何性能问题都会开始出现。
- 反馈:我们从真实用户那里得到宝贵的意见。
- 没有冷启动:新系统可能需要一段时间才能启动。金丝雀部署缓慢地建立势头以防止冷启动缓慢。
- 无停机时间:与蓝绿部署一样,金丝雀部署不会产生停机时间。
- 轻松回滚:如果出现问题,我们可以轻松回滚到以前的版本。
第一个金丝雀
使用金丝雀作为预警系统的想法由来已久。早在 Google 或 Netflix 使用它们之前,煤矿工人就带着真正的金丝雀寻找气体泄漏点。当这些小鸟——比人类更容易受到无味烟雾的影响——检查出来时,是时候离开矿井了。
可以预见的是,随着技术的进步,事情变得更好了。今天,云技术使事情对野生动物的危害减少,变得更加实用:
- Canary 发布:只要我们有某种远程更新软件的方法,我们就可以进行 Canary 发布。应用商店就是一个很好的例子。Google Play 和 Apple 的 App Store 都支持分阶段推出。此功能让我们可以一次性向一定比例的用户推送更新。
- 滚动金丝雀:我们有许多工具,如 AWS CodeDeploy、Chef、Puppet 或 Docker,可帮助我们执行滚动更新。
- 并行金丝雀:云允许我们按需创建和拆除硬件和服务。我们有 Terraform、Ansible 或 AWS CloudFormation 等工具来使用代码定义基础设施。
- CI/CD:当我们将持续交付和部署(CI/CD)添加到组合中时,我们得到了最有效的代码交付模式之一。
Kubernetes
Kubernetes 值得一个单独的部分,因为它是专门为部署复杂的分布式系统而设计的。Kubernetes 是一种流行的编排平台,具有用于滚动和并行部署的内置工具。该平台非常适合金丝雀部署,因为它允许我们仅使用代码来部署、更新和扩展应用程序。
规划金丝雀
在规划金丝雀部署时,我们必须考虑以下几点:
- 阶段:我们首先向金丝雀发送多少用户,以及在多少阶段。
- 持续时间:我们计划运行金丝雀多久?Canary 部署通常会运行几分钟或几小时。Canary 版本不同,因为我们必须等待足够多的客户端更新才能评估结果。这可能会在几天甚至几周内发生。
- 指标:我们应该记录哪些指标来分析进度,包括应用程序性能和错误报告。精心选择的参数对于成功部署 Canary 至关重要。
- 评估:我们将使用什么标准来确定金丝雀是否成功。
首先,我们可以尝试使用 1-10-100 步长的对数方法。也就是说,首先将 1% 的用户群发送给金丝雀,以确保没有任何严重问题。然后,我们将金丝雀增加到 10%,看看它在负载下的表现。最后,我们迁移 100% 的用户群并完成该过程。
我们可以根据需要设置多个阶段。也许 2-100 的两个阶段就足够了,而有些人可能更喜欢 10-20-50-100 的渐进步骤。
迁移用户的策略
一旦我们计划好了阶段,我们就必须定义我们将如何选择参与金丝雀的用户:
- 随机:我们可以随机将一定比例的用户发送到金丝雀。
- 按地区:一次在一个地理区域部署金丝雀。例如,我们可以选择夜间跟踪策略,并在每个地区的夜间在线用户最少的时候发布。
- 早期采用者计划:让用户有机会选择加入(或退出)金丝雀计划可能会带来最佳结果。早期采用者更有可能提供高质量的反馈。
- Dogfooding:这个术语与“吃自己的狗粮”有关,涉及首先将金丝雀发布给内部用户和员工。
最佳选择标准可以结合不同的策略。例如,Facebook 使用多个 canary。第一个在内部部署并分配给其员工。然后,第二波到达一小部分用户。后来,他们逐渐将其扩大到整个人口。
金丝雀部署的缺点
没有什么是完美的。金丝雀部署也不例外。让我们看看金丝雀部署的另一面。
- 挫折:第一组使用金丝雀会发现最严重的错误。更重要的是,一些用户可能会推迟了解他们被用作豚鼠。如果您对此感到担心,请考虑启动一个选择加入计划(将其称为“早期采用者”或“内部计划”以增加酷感)。
- 成本:并行部署成本更高,因为我们需要额外的基础设施。充分利用云;按需创建和删除资源以降低成本。
- 复杂性:金丝雀部署与蓝绿部署具有相同的复杂性。拥有多台生产机器,迁移用户,监控新系统;这些都是复杂的任务。不惜一切代价避免手工操作,始终使用稳健的CI/CD 平台自动化部署过程。
- 时间:建立一个健康的金丝雀部署管道(CI/CD pipeline)需要时间和精力。从好的方面来说,一旦我们做对了,我们就可以进行更频繁、更安全的部署。
- 数据库:整本书都写了如何更改数据库架构。问题是数据库在部署期间必须同时与金丝雀版本和控制版本一起工作。所以,如果我们有破坏性的架构更改,我们就有麻烦了。我们需要在进行更改时保持向后兼容性,这又增加了一层复杂性。
金丝雀并不适合所有人
不幸的是,并不是每个人都能使用金丝雀部署。在某些情况下,我们将无法使用该策略:
- 在不允许任何类型的持续部署的环境中工作时,例如在医疗或航空航天行业。
- 当我们处理关键任务或生命支持系统时,例如能源网或核反应堆的应用程序。
- 当失败具有灾难性的经济后果时,例如对金融系统。
- 当我们需要在数据库或存储后端中进行破坏性架构更改时。
- 当我们依赖安装在用户计算机上的软件而无法远程更新时。
金丝雀与蓝绿色
我们在上一篇博文中讨论了蓝绿部署的优缺点。现在我们了解了金丝雀,百万美元的问题是:哪个更好?
有许多变量需要考虑,从来没有一个对每个人都有效的答案。但根据经验,如果以下任一情况属实,我们应该考虑二进制蓝绿部署:
- 我们对新版本充满信心。我们已经彻底测试了代码,我们估计失败的可能性非常低。
- 我们正在小型安全迭代中工作。
- 我们需要一次切换所有用户。
在以下情况下,Canary 可能是更好的选择:
- 我们对新版本不是 100% 有信心,我们认为我们失败的可能性很低。
- 我们担心性能或扩展问题。
- 我们正在进行重大更新,例如添加闪亮的新功能或实验性功能。
- 我们可以缓慢推出。
- 我们的应用程序依赖于我们无法在测试环境中复现(replicate)的遗留系统或第三方系统。在这种情况下,只能在实时生产系统上进行测试。
结论
当人们开始使用我们的软件时,真正的考验就来了。Canary 部署允许我们对真实用户进行受控试验。当我们将此策略与快速 CI/CD 工作流相结合时,我们将获得高效、功能丰富的发布周期。