当我初次担任 MLOps 工程师时,我曾负责发布一个包含图像分类 ML 模型的应用程序。最初的发布非常顺利,但当模型更新时,混乱随之而来。首先,承载新模型的 Pod 因测试环境与生产环境之间的差异而无法启动。更糟糕的是,承载旧模型的 Pod 已经被新的、无法启动的 Pod 替换,导致客户无法正常工作。这简直是一场噩梦。我不得不手动回滚,并向该模型的用户道歉。
然而,我从这次经历中吸取了教训,并转向使用**蓝绿部署(Blue-Green Deployment)策略。这种 DevOps 方法能够无缝地发布新更新,实现零停机(Zero Downtime)**和无忧回滚。
本指南将带你了解蓝绿部署在实践中的应用:如何设置、其权衡、以及那些你可能在官方文档中找不到的经验教训。无论你是构建 ML 服务、API 还是全栈应用程序,这种方法都能为你的团队提供所需的安全网,让你自信地推出新功能。
蓝绿部署核心解析
蓝绿部署听起来可能比实际情况复杂(至少对我而言,初次听说时觉得很难)。
它其实只是一个巧妙的技巧,用于在不中断用户的情况下发布新版本。它通过维护两个相同的生产环境并在它们之间切换流量来实现这一点。
如果你曾遇到过应用程序在测试环境(staging)正常工作,但在生产环境(production)却崩溃的问题,那么这个策略非常适合你!
核心架构与操作机制
基本思想是:你维护两个相同的生产环境。一个被称为“蓝色(Blue)”,另一个被称为“绿色(Green)”。
蓝色环境是用户当前正在交互的环境。当你有一个新版本要发布时,你将其部署到绿色环境,进行测试。一旦你确信它运行正常,就将生产流量从蓝色环境重新路由到绿色环境。
这种策略能带来零停机,没有“抱歉,我们正在更新”的提示。只是一次在幕后进行的平滑过渡,用户甚至不会察觉。
在实践中,这一切的“魔力”发生在**负载均衡器(Load Balancer)**中。你将其配置为根据部署状态将流量路由到任一环境。这提供了对流量的精细控制,使得回滚(Rollback)变得像将流量切换回蓝色环境一样简单。
这个策略解决了我在新 ML 模型发布时遇到的“但在测试环境是好的啊”的问题。由于绿色环境也是生产环境,你可以在用户实际使用之前,对真实环境进行测试。
以下是典型的流程概览:
- 将新版本部署到绿色环境。
- 运行集成测试和冒烟测试(Smoke Tests)。
- 使用负载均衡器切换流量。
- 监控绿色环境是否存在异常。
- 如果一切正常,可以降级蓝色环境或保留它以备回滚。
蓝绿部署阶段1:新应用部署到绿色环境进行测试,流量仍路由到蓝色环境
蓝绿部署阶段2:流量重新路由到绿色环境
历史演进与行业应用
蓝绿部署方法最早由 Daniel Terhorst-North 和 Jez Humble 于 2005 年左右在 ThoughtWorks 内部命名并使用。后来,Jez Humble 和 Dave Farley 在 2010 年的著作《持续交付(Continuous Delivery)》中对其进行了文档化和推广。
从那时起,它被广泛应用于各种场景,从初创公司到当今的云原生巨头,如 Netflix 以及任何每天需要进行多次部署而又不出问题的组织。
云平台加速了这一转变。借助基础设施即代码(Infrastructure-as-Code, IaC)、**自动扩缩组(Auto-scaling Groups)**和 Kubernetes 等容器编排工具,快速启动和维护重复环境变得简单。
蓝绿部署甚至启发了其他部署模型,例如金丝雀发布(Canary Releases)和特性开关(Feature Flags)。理解蓝绿部署,也能为你理解其他部署策略奠定基础。
蓝绿部署的关键优势
老实说,我第一次听说蓝绿部署时,觉得维护两个生产环境完全没有意义。然而,当我看到它如何轻松地发布新的 ML 模型,以及用户投诉和升级事件的减少,我意识到这一切都是值得的。
在接下来的章节中,我将重点介绍蓝绿部署的优势。
接近零停机
这是最明显的优势,因为没有人希望出现停机。
通过蓝绿部署,你可以立即将流量从旧环境切换到新环境,而无需等待服务降级。你的用户甚至不会察觉到切换过程,这正是它应有的样子。
当你运行用户面对的 API、仪表板或无法承受几分钟中断的 ML 流水线时,这是一个改变游戏规则的策略。
轻松回滚
想象一下,你发布了一个新版本,却在几分钟后发现它抛出了大量内部服务器错误。使用蓝绿部署,你可以简单地将负载均衡器切换回蓝色环境,然后在不慌不忙的情况下修复错误。
这种安全级别让团队更自信地频繁发布。不再有“不要改变正在运行的系统”的说法。
生产环境安全测试
你可以在生产环境中进行测试,而不会让用户面临风险。这正是绿色环境的魅力所在。你可以在任何实际流量到达应用程序之前,运行负载测试、集成检查,甚至模拟用户行为。
与传统的测试环境(staging environments)不同,你是在相同的基础设施(Infrastructure)、**配置(Configuration)**和其他一切生产条件上运行测试的。
这使得测试结果更可能反映真实情况。
支持A/B测试与分阶段发布
一旦你运行了两个相同的生产环境,你就可以用它们做更多的事情。你可以将 90% 的流量路由到蓝色版本,将 10% 的流量路由到绿色版本。
你还可以集成**特性开关(Feature Flags)**来控制哪些功能何时上线,而蓝绿部署则可以作为底层部署基础提供良好的支持。
提升用户体验与业务连续性
蓝绿部署有助于:
- 向用户暴露更少的错误。
- 在问题出现时,工程团队能更快响应。
- 简化备份恢复。
如果你正在部署关键的机器学习服务或人们每天依赖的内部数据工具,这非常重要。
规划蓝绿部署
在实施蓝绿部署之前,深入了解其原理至关重要。
让我们从架构、成本考量和内部准备情况方面进行分解。
基础设施要求
你需要拥有两个相同的生产环境。这意味着双倍的设置和双倍的维护工作。
但在你担心成本之前,请记住这并不总是意味着双倍的成本。通过云平台或 Kubernetes,你可以在需要时才启动绿色环境的资源,并在之后将其关闭。
以下是帮助你设置两个环境的一些建议:
- 基础设施即代码(IaC)(例如 Terraform),用于快速复制环境。
- 配置管理(Configuration Management),用于防止因配置漂移(Configuration Drift)引起的问题。
- 在 Kubernetes 中,使用不同的**命名空间(Namespaces)或部署对象(Deployment Objects)**来区分蓝色和绿色环境。
此外,请记住,在本地部署(On-prem setups)中情况会变得更复杂,因为你需要确保:
- 负载均衡器配置足够灵活,能够即时切换流量。
- 你可以快速配置环境(可能通过虚拟化或容器)。
- 外部依赖(例如数据库、API)是同步且隔离的。
成本效益分析
怀疑论者总是指出维护两个生产环境会增加成本。是的,运行两个环境并非免费。然而,第二环境增加的成本与业务停机带来的损失之间存在权衡。
问问自己:
- 一次失败部署的平均影响(时间或金钱)是多少?
- 调试、回滚和解释停机需要多少小时?
- 你多久在压力下发布一次,只是祈祷它不会崩溃?
这正是蓝绿部署的最大卖点:更少的宕机、更快的迭代、以及更小的工程压力和倦怠。
优化成本的建议:
- 使用**自动扩缩(Auto-scaling)**功能根据测试负载调整绿色环境的规模。
- 为绿色环境选择Spot Instances(竞价实例)或Ephemeral VMs(临时虚拟机)。
- 在单独的 Kubernetes 命名空间中运行绿色版本,并在切换后将其缩减到零。
配置良好的 **CI/CD 流水线(CI/CD Pipeline)**甚至可以自动处理这种扩缩。
先决条件与组织准备
这一部分经常被忽视,但它非常重要。
即使你有基础设施和工具的预算,如果你的团队文化和系统尚未准备好,蓝绿部署也无法成功。
你需要:
- CI/CD 工作流(CI/CD Workflows):能够独立部署和测试绿色环境的流水线。
- 监控与可观测性(Monitoring and Observability):你需要在将流量从蓝色切换到绿色之前检查各项指标。
- 清晰的回滚策略(Rollback Strategy):最好是自动化的,并且肯定经过实践演练。
- 跨职能协作(Cross-functional Alignment):开发、运维、QA 和产品团队都应该理解整个流程如何运作。
技术实现细节
到目前为止,我们已经探讨了为什么应该使用蓝绿部署。在本节中,我将向你展示如何实现它。
我将分解一个典型的蓝绿部署生命周期,重点关注处理数据库这一挑战性方面。
你将了解需要自动化哪些内容、需要监控哪些内容以及哪些内容不应跳过。
标准部署生命周期
一个良好实现的蓝绿部署遵循精确的顺序。以下是它在实践中通常的样子:
- 准备绿色环境:启动一个镜像当前(蓝色)环境的生产级环境,无论是在云端、本地还是使用 Kubernetes。
- 将新版本部署到绿色环境:你的 CI/CD 流水线应该在此处构建和部署代码,理想情况下将其标记为当前的候选发布版本。
- 运行自动化测试:这包括冒烟测试、集成检查以及任何模拟用户行为的健康探测。你检查绿色环境是否已为用户准备就绪。
- 监控日志和指标:如果你的仪表板看起来干净,没有警报,那么你就可以继续了。如果没有,请修复问题并重新部署到绿色环境。
- 切换流量到绿色环境:重新配置你的负载均衡器以将所有流量路由到绿色服务器。
- 停用蓝色环境:一旦你对绿色环境充满信心,就可以关闭蓝色环境,或者将其作为备份,直到下一次发布。
确保回滚步骤与发布一样快,以便团队成员可以在一分钟内撤销部署。
数据库同步策略
这部分很棘手。你的应用程序是无状态的,但你的数据库不是。
如果你不仔细处理这一部分,你就无法轻松回滚,蓝绿部署的全部意义也将不复存在。
以下是你如何处理它的方法:
- 设计向下兼容(Backward Compatibility):在切换过程中,用户可能仍然会在几毫秒内访问蓝色环境。你的数据库 Schema 在此期间需要同时支持两个应用程序版本。
- 不要立即删除或重命名字段。
- 添加新列/表时,使用默认值。
- 在两个版本都支持更改之前,避免硬性约束。
- 版本化迁移(Version your Migrations):使用 Flyway 或 Liquibase(用于 Java-based 系统)或 Alembic(用于 Python + SQLAlchemy)等工具。
- 处理会话状态(Handle Session State):如果你的应用程序使用内存会话存储,切换环境可能会导致用户登出或功能中断。使用 Redis、Memcached 或共享数据库来避免这种情况。
- 切换后验证数据一致性:自动化对关键数据的检查以确保一致性。
- 用户能否登录?
- 最近的更改是否已保存?
- 分析流水线是否仍在正确摄取数据?
- 监控缓慢漂移(Monitor Slow Drifts):有时更改不会抛出错误并似乎有效,但它们可能会导致细微的问题,例如事件处理延迟或格式错误的记录。使用日志记录和可观测性工具尽早发现此类问题。
与其他部署策略的比较
蓝绿部署通常被用作其他部署策略的基础,提供各种变体来解决部署过程中的不同问题。
根据你的架构、发布频率和对复杂性的要求,可以考虑替代方案,甚至将几种方法混合成一种新的方法。
让我们比较最常见的场景:蓝绿部署(Blue-Green)与金丝雀部署(Canary Deployments)。
蓝绿部署 vs. 金丝雀部署
这些策略经常混合使用,但它们的目标不同。
蓝绿部署是一种完全切换的发布模型。你部署到绿色环境,测试它,一旦准备好,就将 100% 的流量切换过去。
而金丝雀部署则是一种渐进式切换。你将新版本与旧版本一起部署,并逐渐转移一小部分流量(例如,1%,然后 10%,然后 50%),同时监控潜在问题。
两种策略的关键区别:
| 特性 | 蓝绿部署(Blue-Green) | 金丝雀部署(Canary) |
|---|---|---|
| 流量切换 | 一次性全部切换 | 渐进式切换 |
| 回滚 | 即时(切换回蓝色) | 部分或渐进式回滚 |
| 风险暴露 | 如果绿色环境有问题,影响较大 | 较低(问题较早被发现) |
| 基础设施需求 | 两个完整的环境 | 需要流量拆分路由层 |
| 发布可见性 | 清晰、受控的切换 | 需要更复杂的可观测性(Observability) |
| 最适合 | 小型团队、稳定应用 | 关键服务、庞大用户群体 |
我个人曾将蓝绿部署用于将新的 ML 模型部署到生产环境,但用户群也有限。如果我的模型暴露给更大的用户群,我可能会更倾向于金丝雀发布。
基础设施与操作权衡
两种策略都需要良好的工具支持,但它们的复杂性体现在不同领域。
蓝绿部署需要相同的环境,这增加了基础设施成本。然而,路由非常简单,因为它只涉及将流量从一个环境切换到另一个环境。
金丝雀部署在基础设施成本方面更轻量,但需要更多逻辑来实现流量的渐进式切换。它还需要更详细的**可观测性(Observability)**来尽早发现问题。
以下是一些你需要考虑的其他因素:
- 监控(Monitoring):金丝雀部署需要粒度更细的指标(例如,每用户或每请求延迟),而蓝绿部署只需要知道应用程序是否健康。
- 自动化工具:诸如 Argo Rollouts 和 Flagger 之类的工具在 Kubernetes 中支持两种模型,但金丝雀部署需要更多的设置。
- 部署时间:蓝绿部署快速。金丝雀部署谨慎且耗时。
那么,哪种适合你呢?
如果你的团队的 CI/CD 成熟度仍在提升,蓝绿部署可能是建立信心的最佳方式。蓝绿部署也是一个很好的起点,让你积累一些经验。
然而,如果你拥有庞大的用户群或部署具有显著风险的更改(例如定价逻辑),金丝雀部署可能是一个不错的选择。
平台特定的实现
现在,理论部分到此为止。让我们深入技术细节。让我们看看蓝绿部署是如何在数据团队日常使用的平台上实现的,例如 Kubernetes、托管云服务和自动化工具。
每个平台都提供不同的功能,但核心思想保持不变:你需要两个相同的环境和一个流量切换机制。
Kubernetes编排模式
使用 Kubernetes 实现蓝绿部署非常直接,因为所有必要的工具都已内置在 Kubernetes 中。
有几种设置方式:
- 单独的 Deployment:将
my-app-blue和my-app-green作为两个独立的 Deployment 进行部署,共享标签和 Service。 - 带修订的单个 Deployment 对象:不常见,但如果使用注解(Annotations)来跟踪版本,也是可能的。
- 命名空间(Namespaces):在单独的命名空间中运行蓝色和绿色环境以实现完全隔离。
这里的关键组件是 Kubernetes Service。它充当负载均衡器,通过标签选择器将流量路由到蓝色或绿色的 Pod。
假设你有:
selector:
version: blue
在验证绿色版本后,你将 Service 的选择器更新为 version: green,流量就会立即重新路由。
我建议使用 readinessProbes 来确保新版本在路由任何流量之前已完全准备就绪。
这个过程可以使用 Argo Rollouts 和 Flagger 等工具实现自动化,它们处理:
- 渐进式流量转移
- 健康检查和监控
- 如果出现崩溃,自动回滚
云原生托管服务
如果你使用 AWS、Azure 或 GCP,好消息是蓝绿部署已经内置在其中,你只需要启用它即可。
AWS CodeDeploy(配合 Elastic Beanstalk 或 EC2):
- 提供专用的蓝绿部署策略
- 你定义哪个环境是绿色环境,CodeDeploy 会处理流量转移和回滚
Azure Container Apps 或 Azure App Service:
- Azure 允许你将版本作为“Slot(部署槽)”进行暂存,并以零停机的方式进行交换
- 结合 Azure DevOps 流水线实现完整的 CI/CD 自动化
Google Cloud(Cloud Run 或 GKE):
- Cloud Run 支持在修订版本之间渐进式拆分流量,非常适合测试和发布
- 使用 GKE,可以通过负载均衡器规则或 Istio 管理蓝绿逻辑
每个云提供商都有自己的设置和功能,但它们都能让你的生活更轻松,因为你无需自行实现太多功能。
使用托管服务也总有一个好处,那就是你无需自己维护这些东西,因为云提供商会更新他们的服务,你只需要担心正确配置它们。
Cloud Foundry及其他工具示例
Cloud Foundry 是一个开源的平台即服务(PaaS),它抽象了底层的大部分基础设施,让开发者能够专注于代码推送。它在大企业中特别受欢迎,因为它具备自动化、合规性功能和快速部署工作流。
以下是 Cloud Foundry 中使用官方 CLI 进行典型蓝绿部署的流程:
-
使用子域名
demo-time推送应用程序的蓝色版本:cf create-route example.com --hostname my-app cf push my-app cf map-route my-app example.com --hostname my-app蓝色版本现在正在运行,路由器将所有流量发送到
my-app.example.com。 -
使用新名称和路由推送应用程序的绿色版本:
cf create-route example.com --hostname my-app-temp cf push my-app-green cf map-route my-app-green example.com --hostname my-app-temp现在应用程序的两个实例都已启动并运行,但它提供两个可以发送流量的路由(
my-app.example.com用于蓝色,my-app-temp.example.com用于绿色)。 -
将生产路由映射到绿色版本:
cf map-route my-app-green example.com -n my-app此时,旧版本(蓝色)和新版本(绿色)都已上线,但流量将路由到两者,除非你明确移除蓝色。
-
验证绿色版本是否正常工作。 你可以通过其路由进行测试,或在切换后监控实际流量。
-
从蓝色版本取消映射路由,完全切换到绿色部署:
cf unmap-route my-app example.com -n my-app路由器不再将流量发送到蓝色版本。
-
删除旧应用程序和绿色路由(可选但建议):
cf delete my-app cf unmap-route my-app-green example.com --hostname my-app-temp
这个过程最大限度地减少了停机时间,并让你完全控制何时以及如何切换版本。
如果你想通过可视化流水线、手动批准或自动化回滚进一步改进此工作流,Octopus Deploy、Codefresh 或 Spinnaker 等工具是不错的选择。它们与 CI/CD 流水线无缝集成,使团队能够自动化复杂的部署生命周期。
最佳实践与优化策略
蓝绿部署听起来很棒,并且能提供很大帮助,但如果你没有正确管理成本、风险或自动化,它也可能很快变得一团糟。我曾见过团队因过于复杂的设置或意外的边缘情况而受困。
让我们看看你应该怎么做才能避免这种情况,并使你的蓝绿部署策略取得成功。
成本管理技巧
复制环境当然会带来额外成本。
但你可以使用以下策略最大限度地降低它们:
- 自动扩缩(Auto-scaling):利用水平 Pod 自动扩缩器(HPA)或云原生自动扩缩来匹配实际工作负载,防止资源浪费。
- 竞价实例(Spot Instances)与抢占式虚拟机(Preemptibles):非常适合绿色环境,如果你只是进行测试(并且可以接受可能的干扰)。
- 临时资源调配:不要让绿色环境运行时间超过所需。通过 CI/CD 流水线启动它,然后在完成后将其拆除。
- 容器化(Containerization):它们轻量、快速且成本高效,尤其是在 Kubernetes 或 Azure Container Apps 等平台上运行时。
自动化验证框架
你绝不应该在没有完全确信你的绿色应用程序按预期工作的情况下切换流量。
在切换前使用这些测试层级来建立信任:
- 冒烟测试(Smoke Tests):关键端点是否存活和健康?
- 集成测试(Integration Tests):核心工作流(身份验证、数据访问等)是否在绿色版本中正常工作?
- 端到端测试(End-to-End Tests):针对临时绿色路由模拟实际用户行为(在 Cloud Foundry 和 Azure 中特别有用)。
将这些集成到你的 CI/CD 流水线中,以便在成功部署后自动运行。
数据库迁移方法
这是一个棘手的部分,因为你的应用程序可以在两个环境中运行,但你的数据库最终通常是相同的。
以下是安全过渡的方法:
- 向后兼容的 Schema 更改:始终假设绿色版本上线时,蓝色版本可能仍在访问数据库。
- 特性开关(Feature Toggles):仅在新 Schema 部署后才推出依赖 Schema 的特性。
- 版本化迁移(Versioned Migrations):使用 Flyway、Alembic 或 Liquibase 等工具来使更改可跟踪和可逆。
- 会话/数据一致性:如果你依赖会话状态,请使用外部存储(如 Redis),两个环境都可以共享。
特性开关与渐进式交付
将蓝绿部署与**特性开关(Feature Flags)**结合使用,可以提供更大的灵活性。
通过特性开关,你可以:
- 将新功能发布给绿色环境中的一部分用户
- 部署功能但保持隐藏
- 安全测试边缘情况或性能影响,而无需暴露完整的功能集
利用 LaunchDarkly、ConfigCat 或 Unleash 等工具来简化管理,而无需更改代码。
强大的监控与可观测性
**监控(Monitoring)和可观测性(Observability)**对于安全地切换流量至关重要,因为它们能让你评估绿色环境是否可以正确部署到蓝色环境。
你应该拥有:
- 健康检查(Health Checks):Kubernetes
readinessProbes、Azure 修订 URL 等。 - 日志(Logging):集中式、可搜索,并按环境(蓝色与绿色)标记。
- 告警(Alerting):设置阈值并在错误率增加时获取通知。
- 流量分析(Traffic Analysis):比较蓝色和绿色环境之间的行为(例如,延迟、错误率和吞吐量)。
然而,强大的监控和可观测性无论你是否使用蓝绿部署,都应该是你基础设施的一部分。
回滚与灾难恢复规划
事情有时会出错。目标是尽可能轻松快速地从故障中恢复。
以下是操作方法:
- 即时回滚:始终保持蓝色环境运行,直到你确认绿色环境稳定为止。
- 自动化回滚触发器:使用 Argo Rollouts 或 Spinnaker 等工具,如果关键指标失败,则回滚流量。
- 操作手册与预案(Runbooks and Playbooks):为团队预先编写步骤,以便每个人都知道该怎么做。
安全强化
拥有两个环境意味着你也有两个潜在的攻击点。
以下是实施适当安全措施的一些建议:
- 隔离环境:分离子网、命名空间或云资源组以确保隔离。
- 频繁轮换密钥:尤其是如果你在蓝色和绿色环境之间使用共享凭据。
- 修补两个环境:不要仅仅因为绿色环境尚未上线就让它在安全更新方面滞后。
- 审计日志:捕获部署事件和环境切换以进行可追溯性。
总结
蓝绿部署不仅仅是一个只有过度工程化流程才使用的花哨部署策略。对于那些优先考虑正常运行时间(Uptime)、**快速反馈(Fast Feedback)**和安心夜晚睡眠的团队来说,它是一种实用可靠的策略。
它为你提供:
- 出现问题时即时回滚。
- 在没有实际用户风险的情况下进行生产级测试。
- 更清晰、更自信的发布,即使是在周五(不是开玩笑)。
但它是否完美适用于所有情况?我会说不。你需要建立完善的 CI/CD 设置,并拥有支持整个过程的工具。否则,它可能会很快变得混乱。
但这并不是避免它的理由。相反,它是一个信号,表明你应该改进你的部署实践。
我们通过采用蓝绿部署,极大地改善了发布流程,此后我们的发布日变得异常轻松,甚至自信到可以在周五进行发布。
如果你想深入了解,可以从 DevOps Concepts 或 MLOps Deployment and Life Cycling 开始,它们将帮助你建立蓝绿部署的基础。
现在,自信地发布你的应用程序吧。
蓝绿部署常见问题解答
蓝绿部署有哪些好处?
它提供无缝回滚、快速发布、更安全的生产测试,并由于降低风险和接近零停机而使用户更满意。
蓝绿部署与金丝雀部署有何区别?
金丝雀发布(Canary releases)逐渐将新版本暴露给一部分用户,而蓝绿部署(Blue-Green deployments)则一次性将所有流量切换到新版本。
如何在蓝绿部署中管理数据库更改?
通过向后兼容的 Schema 更改、版本化迁移和仔细的数据同步策略。
蓝绿部署需要哪些基础设施?
两个相同的环境(蓝色和绿色)、一个类似于负载均衡器的流量切换机制,以及强大的 CI/CD 思维是必不可少的。
关于
关注我获取更多资讯