**本文作者:陈钧桐
腾讯云 CODING DevOps 高级解决方案架构师**,从事多年技术布道工作,对于云原生时代下企业数字化转型、IT 与 DevOps 建设、价值流体系搭建等有丰富的经验,曾为多家大型企业提供咨询、解决方案以及内训服务。既关注工程师视角的云原生开发建设与最佳实践落地,也关注管理者视角的过程管理与研发效能提升。
本文基于陈钧桐老师在 2023 年中国 DevOps 社区峰会·武汉站上的演讲内容进行创作,其在此次峰会中被评为“十佳讲师”,并被社区认可为优秀的知识分享者。
导语
随着云计算和微服务架构的普及,软件开发和运维的环境变得越来越复杂,在我们追求开发和交付的最佳实践时,GitOps 的概念应运而生,并迅速获得了广泛的认可。在许多有效的 GitOps 实践中,渐进式发布作为一种风险管理策略,扮演着重要的角色。它允许我们逐步发布新的服务版本,能够在保证系统稳定的同时,尽快地将新功能或修复带到生产环境。具体实现的策略有多种,包括滚动升级、蓝绿部署、灰度部署、金丝雀发布,以及 A/B 测试等。
在这篇文章中,我们将探讨如何将 GitOps 和渐进式发布结合起来,以实现在云原生环境中的高效、可靠和安全的服务部署。我们将会比较分析不同的渐进式发布策略,介绍主流的云原生工具,以及使用 CODING 自研的云原生应用管理平台 Orbit 进行优雅实现。我们希望这篇文章能为那些希望在自己的软件开发流程中引入 GitOps 和渐进式发布的读者提供有价值的信息和启示。
正文
GitOps 是由 Alexis Richardson 在 2017 年首次提出的,该模型主张将 Git 作为"单一事实来源"(Single Source of Truth)来管理和同步开发和生产环境,而不是使用传统的基础设施管理和部署方式。这个思想提出后,引发了一场对云原生部署和运维模式的讨论和反思。
GitOps 的概念在 2018 年开始被更多的组织和云服务提供商接受和应用,它们都开始探索如何将 GitOps 集成到自己的产品和服务中。例如,亚马逊、谷歌和微软等云服务提供商都在他们的 Kubernetes 服务中集成了 GitOps 工具。
到了 2020 年,为了进一步推广 GitOps 理念和实践,云原生计算基金会(CNCF)宣布成立了 GitOps 工作组。这个工作组由多家云服务提供商和软件公司组成,他们一起制定了一套标准化的 GitOps 最佳实践和原则。
2021 年,GitOps 成熟度模型诞生,这是 GitOps 工作组和社区共同努力的结果。该模型提供了一种量化和评估 GitOps 实施的方法,从而帮助组织更好地理解和实施 GitOps。
GitOps 可以精练地概括为以下三个原则:
- 代码仓库是整个系统的唯一真实来源(Single Source of Truth)。
- 所有的变更活动,包括创建、修改和销毁等,都以代码仓库为核心来进行。
- 所有的变更都必须是可观察和可验证的。
当然,GitOps 除了上述的三个基本原则之外,实践中通常还需要遵循一些前提条件和最佳实践,这包括但不限于:
- 代码和配置分离:在传统的应用部署中,代码和配置往往混在一起,这使得环境间的切换变得困难。在 GitOps 的实践中,我们推荐将代码和配置分离。这意味着应用的代码和其运行配置(例如环境变量,数据库连接等)应该在不同的仓库或者至少在不同的分支中。这样的做法不仅能够使得代码和配置的变更更加清晰,同时也能够避免因为配置错误导致的代码错误。
- 持续交付:持续交付是 GitOps 的一个重要部分。这意味着每一次提交都会通过自动化的构建、测试和部署流程,以便更快、更频繁地向生产环境部署新的更改。
- 清晰的审计轨迹:由于所有的变更都通过代码仓库进行,因此在 GitOps 中,我们有一条清晰的审计轨迹。这可以帮助我们更好地追踪变更的来源,更好地理解每一次更改背后的原因。
- 自动化和自愈:在 GitOps 中,我们尽可能地自动化所有操作,并在系统发生偏离预期状态时尽快进行修复。这通常通过声明式的基础设施管理和 Kubernetes 的自愈能力来实现。
- 权限管理和分离职责:为了避免单点故障和提高安全性,GitOps 推崇权限的最小化原则和职责分离。这意味着每个角色只应具有完成其任务所需的最小权限,并且应该将不同的职责分配给不同的角色或团队。
- 可观察性和反馈:GitOps 不仅需要对变更有清晰的可观察性,同时也需要有反馈机制,让开发者和运维人员知道他们的更改是否成功应用,以及系统的实际运行状态。这通常可以通过日志、监控和告警系统来实现。
我们还可以用一条简洁的公式来解释 GitOps:基础设施即代码(Infrastructure as Code,IaC)+ 合并请求(Merge Request)+ 持续集成/持续部署(Continuous Integration/Continuous Deployment,CI/CD)。
以 CODING 平台举例,在这个流程中,开发人员首先会将代码提交到 CODING 代码仓库。然后,代码评审人员会审查这些代码。只有在代码评审通过后,提交的代码才能被合并到主分支。一旦新代码被合并到主分支,就会触发相应的 CODING 持续集成流水线,自动构建和推送 Docker 镜像到 CODING 制品仓库。随后,当 CODING 的持续部署模块检测到新的 Docker 镜像被推送到制品仓库,就会自动触发相应的持续部署流水线,将新的 Docker 镜像发布到 Kubernetes 集群。
对于运维人员,他们无法像以前那样直接使用 kubectl apply 命令来操作 Kubernetes 集群。他们需要通过在 CODING 代码仓库中提交更新的配置文件来修改配置。当这些配置文件通过审查并被合并到主分支后,CODING 的持续部署模块会检测到这些配置文件的变化,并触发相应的持续部署流水线,将新的配置发布到 Kubernetes 集群。
这种模式的优点在于,所有的权限控制都可以通过代码仓库进行集中管理,不再需要为所有的运维人员开放 Kubernetes 集群的访问权限,从而大大提高了集群的安全性。此外,由于所有的操作都围绕着代码仓库进行,因此每一次操作都会留下提交记录,便于我们追溯问题源头。
总的来说,GitOps 是现代 DevOps 的关键实践,它强调以代码为核心进行一切操作,并确保所有变更的可观测和可验证性,提升了系统的透明度、可管理性和安全性。
在这篇分享里,我们讨论的主题聚焦在 GitOps 实践交付的最后一公里,即如何将应用服务发布部署到对应环境上,以满足业务场景的需求。关于这个话题,社区里已经沉淀了不少优秀的实践,接下来,让我们梳理下常见的部署策略。
滚动发布
✅ 无需停服,用户体验好。
❌ 版本升级和回退用时较长。
"滚动发布"是一种常见的部署策略,它一般涉及以下步骤:逐步取出一个或多个服务器停止服务,执行更新,然后更新完成后,再重新投入使用。这一过程循环进行,直到集群中所有的实例都被更新至新版本。
滚动更新的优势在于,整个更新过程不会中断服务,因此能够提供良好的用户体验。同时,滚动更新还可以在保持服务连续性的同时,逐步替换旧版本实例,这可以有效地降低因更新带来的风险。
然而,滚动更新也有其缺点。由于它是逐个升级实例,因此整个更新过程可能耗时较长,特别是在集群规模较大时。此外,如果新版本出现问题,执行回滚操作也需要花费较长的时间才能完成,这可能导致系统在此期间处于不稳定状态。
蓝绿发布
✅ 升级切换和回退速度非常快。
❌ 如果新集群出问题,影响面较大,需要两套机器资源,成本较高。
"蓝绿发布"是一种部署策略,它依赖于线上的两套完全相同的集群环境。这两套环境被标记为蓝色和绿色,通常在初始状态下,所有的流量都会被路由到绿色集群。当我们准备发布新版本时,我们会在蓝色集群上部署新的应用版本。一旦新版本在蓝色集群上部署完毕并通过测试,我们就将所有流量一次性切换到蓝色集群,以完成系统的升级切换。
蓝绿发布的优势在于,由于我们有两套独立的集群,并且流量可以一次性切换,因此系统的升级和回退操作都可以快速完成。这种策略也使得我们有充足的时间在蓝色集群上验证新版本的稳定性和性能,降低了发布新版本带来的风险。
然而,蓝绿发布也有其缺点。首先,由于流量的切换是一次性完成的,如果新集群出现问题,那么所有用户都会受到影响,影响面较大。其次,由于蓝绿发布需要维护两套完全一样的环境,因此这会带来更高的成本,包括硬件资源、维护工作以及复杂性等方面的成本。
金丝雀发布
✅ 平滑升级,风险小,用户无感知。
❌ 流量无差别地导向新版本,可能会影响重要用户的体验。
"金丝雀发布"是对“蓝绿发布”的一种优化策略,它借鉴了矿工使用金丝雀作为煤矿安全监测的方法。这种发布策略先将一小部分流量从当前版本的集群(我们称之为绿色集群,或者 V1)切换到新版本的集群(我们称之为蓝色集群,或者 V2)。这样我们就能在生产环境中对新版本进行测试。
金丝雀测试的复杂程度可大可小。简单的金丝雀测试可能只涉及手动验证,而复杂的金丝雀测试可能需要配备完善的监控基础设施,通过监控指标反馈,观察金丝雀环境的健康状况,作为后续发布或回退的依据。
如果金丝雀测试成功,我们会将剩余的流量全部切换到蓝色集群(V2)。如果金丝雀测试失败,我们将停止流量切换,将新版本声明为发布失败,并进行相应的故障排查和修复。
与蓝绿发布相比,金丝雀发布的优势在于它在生产环境中增加了一个验证过程,可以降低新版本出现问题的风险和影响面。由于存在两套集群,我们可以在不停止服务的情况下平滑升级,使整个发布过程对用户无感知。
然而,金丝雀发布也有缺点。在新版本发布过程中,流量会被无差别地路由到新版本,如果新版本存在问题,可能会影响那些被路由到新版本的重要客户的体验。
A/B 测试
✅ 可以对特定的用户群体提供新版本的服务,如果出现故障影响范围小。
❌ 发布周期相对较长。
"A/B 测试"是一种同时运行多个程序版本的在线测试策略,它根据用户请求的元信息将流量动态路由到不同的版本。换句话说,我们可以根据请求的内容来决定将流量路由到哪个版本。以一个具体的例子来说明,我们可以设定规则,将 User-Agent 值为 Android 的请求(即来自安卓系统的手机请求)路由到新版本,而将来自其他系统(例如 iOS)或其他设备(例如电脑端)的请求继续路由到旧版本。
这样做的优势在于,我们可以对比两个版本的表现,从而确定哪个版本更受用户欢迎,哪个版本的用户反馈更好。
AB 测试的主要优点是我们可以根据请求信息进行动态路由,针对特定的用户群体提供新版本的服务。这样如果新版本出现故障,其影响的范围也会相对较小。
然而,AB 测试也有其缺点:由于需要同时部署并维护多个版本,并且需要花费一段时间来观察不同版本的运行情况并收集用户反馈,因此整个发布周期可能会比较长。
现在让我们对这些常见的部署策略做简要的对比分析。
- 停机重建(Recreate):这种方法不支持新旧版本并行运行,不能进行真实流量验证,发布效率低,但在一些特定的情况下可能比较可靠。
- 滚动升级(Rolling Updates):这种方法可以在不停机的情况下进行部署,但需要控制好滚动升级的速度以避免资源过载。它允许新旧版本并行运行一段时间,流量控制粒度较低,可以进行真实流量验证,发布效率和发布可靠性中等。
- 蓝绿部署(Blue-Green Deployment):它允许新旧版本并行运行,流量控制粒度较高,可以进行真实流量验证,发布效率和发布可靠性较高。
- 灰度部署(Canary Deployment):这种策略允许新旧版本并行运行,流量控制粒度较高,可以进行真实流量验证,发布效率和发布可靠性较高。
- A/B 测试(A/B Testing):它可以在新旧版本并行运行的情况下进行,流量控制粒度较高,可以进行真实流量验证,发布效率和发布可靠性取决于测试的具体实施。
- 自动渐进式(Automatic Progressive):这种策略结合了多种部署策略的优点,通过自动化的工具和流程,逐步推出新版本的应用,以减少风险。它允许新旧版本并行运行,流量控制粒度较高,可以进行真实流量验证,发布效率和发布可靠性较高。
在云原生环境中,应用程序的更新和部署是常见且关键的操作,因此 Kubernetes 作为容器编排系统,内置了一些基础的发布策略以满足大多数常见的部署需求,其主要是通过 Deployment 和 StatefulSets 资源来实现的:
- 停机重建 (Recreate):在这种策略中,Kubernetes 会首先停止所有旧的 Pod,然后启动新的Pod。这种策略会导致应用程序在部署过程中出现一段时间的停机。
- 滚动更新 (Rolling Update): 这是默认的部署策略。在这种策略中,Kubernetes 会逐渐将新的 Pod 替换旧的 Pod。这种策略可以确保在部署过程中应用程序始终保持运行,不会出现停机时间。我们可以通过设置 maxUnavailable 和 maxSurge 来控制滚动更新的速度。
滚动更新包括一系列明确定义的检查和操作,用于升级由 Deployment 管理的任意数量的副本。Deployment 资源编排 ReplicaSets 以实现滚动更新,下图显示了这种机制的工作原理:
每当更新 Deployment 资源时,默认情况下会启动滚动更新机制。其将创建一个新的 ReplicaSet 来处理使用在 spec.template 中定义的新更新配置创建的 Pod。这个新的 ReplicaSet 不会立即启动所有三个副本,因为这会导致资源消耗激增。因此,它会创建一个单独的副本,验证其是否就绪,将其连接到服务池,最后才终止具有旧配置的副本。
- 蓝绿部署 (Blue/Green Deployments): 虽然 Kubernetes 本身并不直接支持蓝绿部署,但是我们可以通过使用 Service 和两个不同的 Deployment 来实现类似的功能。我们可以创建一个新的 Deployment(绿色)来部署新版本的应用程序,并将Service 切换到新的 Deployment,然后删除旧的 Deployment(蓝色)。
- 金丝雀部署 (Canary Deployments): Kubernetes 本身也不直接支持金丝雀部署,但是我们可以通过手动管理多个 Deployment 和 Service 来实现。我们可以创建一个新的 Deployment 来部署新版本的应用程序,并将一部分用户的流量路由到新的 Deployment,然后逐渐增加流量比例,最后将所有流量都路由到新的Deployment。
虽然 Kubernetes 提供了这些基本的发布策略,但在实际的生产环境中,我们可能需要更高级和灵活的发布策略。比如自动回滚、度量分析和复杂的流量路由规则,从而能够更好地控制和管理应用程序的发布过程。因此社区里诞生了许多工具,其中比较流行的有 Argo 提供的 Rollouts,以及 Flux 提供的 Flagger。
Argo Rollouts 由 Argo 项目开发和维护的,Argo 项目是一个开源项目,专注于 Kubernetes 的工作流、CI/CD、以及应用部署。Argo 项目在云原生计算基金会(CNCF)的孵化阶段,背后的主要公司是 Intuit。Argo Rollouts 的产品理念是利用 Kubernetes 的原生特性,提供灵活、可配置的渐进式部署方式。通过引入新的自定义资源定义(CRDs),Argo Rollouts 扩展了 Kubernetes 的部署功能,使得用户能够在 Kubernetes 环境中实现更复杂的部署策略。实现原理上,Argo Rollouts 引入了新的资源类型 Rollout,用户可以使用 Rollout 资源定义部署策略和配置。当 Rollout 资源发生变化时,Argo Rollouts 控制器会根据定义的策略自动执行部署。
Flux 也是一个开源的 GitOps 工具,专注于在 Kubernetes 上实现持续交付。Flux 项目也是 CNCF 的孵化项目,背后的主要公司是 Weaveworks。Flagger 的产品理念是通过自动化实现渐进式交付,并最小化人为干预。Flagger 的目标是提供一种自动、安全且可观察的方式来推出新的应用程序版本,以便在不影响用户体验的情况下进行持续交付。实现原理上,Flagger 通过自动更改 Kubernetes 服务对象的流量权重,逐步将流量转移到新版本的服务,从而实现渐进式交付。在此过程中,Flagger 会持续监控应用程序的性能指标,如果发现任何异常,它将自动回滚到之前的版本。
如图所示的表格,是对 Argo Rollouts 和 Flux Flagger 做的简要对比分析。比如在负载侵入的角度上,Rollouts 属于完全侵入,而 Flagger 中的原对象将被视作灰度验证对象,而真正对外暴露服务是其复制。比如关于部署过程中是否可以重复验证新版本,Argo 支持得非常好,而 Flux 虽然也支持,不过本质上是进行了一次新的部署。两者在其他层面上的能力也各有不同。
展开来说,两者都支持负载管理和复杂部署,它们都提供像金丝雀和蓝绿这样的部署策略,并且支持运行时的流量分割和切换功能。这些工具都可以整合开源服务网格软件,如 Istio, Linkered, AWS App Mesh 等,以及入口控制器,如 Envoy API 网关,NGINX,Traefik 等。它们还支持从监控或 APM 工具收集的度量的 CRD 分析,如 Prometheus, Datadog, Stack driver, Graphite, 和 New Relic 等。
在安全和策略集成方面,Argo CD 和 Flux CD 都提供了身份验证、授权和秘密管理来增强平台的安全性。然而,Flux 主要依赖于 Kubernetes 的基础 RBAC,Argo 则支持应用权限更细粒度,并支持对没有 Kubernetes 资源访问权的生产系统的只读模式。在治理方面,Flux 没有提供将安全和合规检查作为软件交付策略的部分。Argo CD 提供了最小的能力,确保所有的应用程序都经过了检查才被部署到目标集群。在易用性方面,Flux 没有提供开箱即用的 UI,而 Argo 则提供了出色的 UI。对于复杂性,Argo Rollouts 提供了大量的选项和配置来适应各种部署需求,包括流量路由,实验,分析,抗亲和性配置,以及灰度部署中的延迟设置等,然而这些配置可能增加了其使用的复杂性。
总的来说,Argo Rollouts 和 Flux Flagger 都是强大的 GitOps 工具,但是它们的关键优点和使用场景有所不同。Argo 可能更适合需要更高级安全和策略集成,以及更全面可观察性的环境。而 Flux 可能更适合那些希望简化部署和管理过程的团队。在选择哪一款工具时,需要考虑到具体的需求和使用场景。
腾讯云 CODING 是面向企业的一站式研发管理解决方案,许多客户依赖我们的平台进行研发流程管理。由于服务始终处于使用中,我们需要确保任何发布活动都几乎无需停机,并且对用户几乎无感知。
我们的发布策略是每个月推出一个大版本,这些版本通常包含了新的特性。在正式发布之前,我们会邀请部分用户进行试用和测试。在这个过程中,必须确保老用户的体验不会受到任何影响。因此,我们需要支持按用户进行精细化的流量控制。当验证新版本没有问题后,我们才会分批发布给付费用户。如果在发布过程中出现任何问题,我们需要有能力快速进行回滚。
除了每月的大版本之外,我们每天都会发布数次的轻量级补丁(Livepatch)。这些补丁通常不会经历灰度发布,但需要保证如果发布失败,能够快速进行回滚。对于部分服务,有时候会选择跳过灰度发布,因此我们的系统需要能够支持忽略指定服务的发布。
此外,每个月发布的版本特性需要分发到不同的渠道,因此我们的发布系统需要具备自动化收集这些特性并形成发布说明(Release Notes)的能力。
这些要求不仅确保了我们的服务具有高可用性,也保证了我们能够在保持高效发布的同时,最大程度地降低任何可能的风险。
根据以上业务诉求,自动渐进式发布显然成为了最适合的部署策略,它可以为进一步优化发布过程提供可能性,实现真正的自动化、无感知的发布,最大程度地提升用户体验。
虽然 Argo Rollouts 和 Flux Flagger 已经提供了大量支持渐进式发布的功能,然而根据现有的需求,这两个工具仍存在一些无法满足的地方。
- 负载侵入问题:在 Argo 和 Flux 中,进行灰度发布或者 A/B 测试时,我们需要在服务层面加入相应的逻辑来支持流量切分,这在一定程度上增加了应用的复杂度和开发负担。
- 流量平滑问题:Argo 和 Flux 在进行版本升级时,流量切换的过程并非完全平滑。有可能导致在切换过程中出现流量抖动,影响服务的稳定性。
- 配置复杂度:Argo 和 Flux 的配置相对较复杂,这对于开发和运维人员来说,需要花费更多的时间去理解和掌握,增加了使用门槛。
- 全链路灰度缺失:Argo 和 Flux 对于全链路灰度的支持并不完善,难以满足复杂的灰度发布需求,如根据用户特性进行精细化的流量路由。
- 版本管理问题:在使用 Argo 和 Flux 进行发布时,存在重复验证新版本的问题,而且版本管理机制相对较弱,对于频繁的版本发布可能会带来一定的困扰。
- 交付复杂度:Argo 和 Flux 的设计初衷是针对软件工程中的服务应用交付,它们主要处理的是技术层面的问题。然而,交付不仅仅是软件工程中的服务应用交付,也是业务层面的用户价值交付。这涉及到如何将新版本的特性准确地、有效地传递给目标用户,如何在保证用户体验的前提下,根据项目管理中的产品需求来进行灵活的版本控制和发布策略制定。这是一种对业务理解和业务需求的深入挖掘,需要我们在技术实现之外,更多地去关注业务价值的实现和优化。这种复杂度和细微之处的处理,是两者当前的设计和实现所无法覆盖和支持的。
基于前述原因,常见的开源工具比如 Argo 和 Flux 的当前设计和实现均未能满足我们的业务需求。因此,我们构建了自己的自动渐进式发布解决方案。它的流程可以简要地概述如下:
整个流程构成一个持续调和(Reconcile)循环。首先,进行准备阶段,对预备上线的金丝雀工作负载(pre canary workload)进行配置和部署。随后,灰度负载的比例逐渐提高(pre canary traffic)。接着,我们增加导向金丝雀版本的流量比例,即 post canary traffic 阶段。
在这一步后,系统会验证灰度发布是否成功。如果检测到问题或失败,系统将退回到 pre canary workload 阶段,否则,流程将持续进行。
接下来是 pre promote 阶段,准备晋升新版本到正式环境。然后,在晋升(promote)阶段,新版本将在正式环境中部署。紧接着是 pre route traffic 阶段,准备将全部流量切换到新版本。正式流量切换(route traffic)阶段开始后,所有流量将指向新版本。
在 pre finalize 阶段,我们准备完成所有流程并进行清理。当整个 Reconcile Loop 结束后,如果需要回滚,那么 pre rollback 阶段将开始,并随后进行 post rollback,以恢复到初始状态。
总的来说,我们对灰度发布流程进行了深度定制和优化,让其更符合我们的业务场景。
针对上述流程,可以从资源的视角进行解析。整个部署过程可以拆分为以下几个环节:
- 预部署阶段:创建新的 "金丝雀" 命名空间(canary namespace),此时,其内部的 pod 工作负载比例为 0%。
- 第一阶段灰度部署:逐步增加 canary namespace 的工作负载比例,例如将 pod 数量提高到 15%。同时,调整流量权重,让一部分流量路由到 canary namespace,以便在此环境中验证新版本的性能和稳定性。
- 第二阶段灰度部署:如果第一阶段的验证没有问题,我们将继续提高 canary namespace 的工作负载比例和流量权重,以进行更大范围的验证。
- 正式部署:在两轮灰度测试都成功通过后,我们将在原生产环境的 "production" 命名空间内部署新版本的应用,这一过程称为晋级。在晋级之后,所有的流量都将被切换到 production namespace,这意味着用户将开始使用新版本的服务。
- 清理阶段:完成新版本的部署后,我们将对 canary namespace 进行清理。
不同于传统的蓝绿部署方式,这一过程并不是一次性切换所有流量,而是在两轮灰度验证成功之后,再对原生产环境进行晋级。这种设计的理念在于,传统的蓝绿部署方式在多次切换之后,由于每次生产环境都被切换到新的命名空间,可能会导致混淆,使我们难以确定用于生产环境的命名空间是哪一个。而通过固定对 "production" 命名空间进行持续晋级,我们可以确保这个命名空间一直被用于生产环境,而其他命名空间被专用于进行灰度测试,避免了混淆带来的潜在风险。
基于上述设计的解决方案,我们参考优秀开源方案,实现了自主研发的应用发布引擎——Orbit。Orbit 以产品化的形式,提供了一系列先进而灵活的发布策略,比如分批进行蓝绿部署和灰度部署等。此外,它还有能力支持对指定服务实行“忽略灰度”的操作。这些功能的设计和实现,使得 Orbit 在满足复杂发布需求方面表现出显著的优势。
Orbit 的设计理念注重实践和创新,它有着一套健全的变更审核机制,确保发布的准确性和可靠性。发布流程在满足自动化的同时,保留了足够的可控性,用户可以根据实际需要灵活地管理和调整发布流程。
在发布过程中,Orbit 支持对变更进行预执行,确保发布过程的准确性和可靠性。在整个部署过程中,每一个变更都会被详细记录并在需要时进行审核。
在自动化的流程中,Orbit 特别增设了人工确认环节,以人工审核的方式降低发布风险,避免因自动化过程中的未预期事件导致的问题。这样既保留了自动化带来的效率,又兼顾了人工审核在风险控制上的优势。
Orbit 也具备快速回滚的功能,一旦在发布过程中或新版本上线后发现问题,可以迅速回滚到旧版本,最大程度减小问题带来的影响。
此外,Orbit 还自动管理和清理灰度环境。在新版本成功发布并稳定运行后,Orbit 能自动清理无需再用的灰度环境。这意味着团队无需手动进行清理工作,减轻了维护负担,同时确保了资源的合理利用和环境的整洁。
总的来说,Orbit 以其全面且灵活的设计,为应用发布提供了一站式的解决方案,从变更执行到环境清理,每个环节都体现出其高效、稳定和可靠的特性。
此外,Orbit 进一步深化了对业务价值交付的理解,它不仅仅是一个工具,而更像是一个桥梁,将技术层面的软件版本管理与业务层面的价值创造紧密地结合起来。在 Orbit 的管理下,每一个发布版本都不再仅仅是代码的改动和镜像的更新,而是直接反映了特定的用户故事和业务价值的交付。这种方式将技术与业务融为一体,提供了一种全新的视角来看待应用的发布管理。
通过这种方式,Orbit 能够帮助企业更加精准地了解每一个版本变更背后所包含的业务价值,使得技术团队与业务团队之间的沟通和理解变得更为流畅。此外,通过将业务价值映射到具体的版本变更中,也使得企业能够更加明确地了解和评估每次发布带来的实际效果,从而实现更为有效的产品迭代和持续优化。这种创新性的设计理念,使 Orbit 不仅在应用发布管理的全面性和深度上具有显著优势,更在价值交付的效果上实现了显著的提升。
不同的工具拥有各自的优点和特性。这里,我们将针对 Orbit、Argo Rollouts 和 Flux Flagger 这三款工具进行深入的对比和分析,尤其是聚焦于我们自研的 Orbit:
- 支持的负载类型:Orbit 支持任意类型的负载,包括但不限于 Rollout 和 Flagger。相比之下,Argo 和 Flux 的支持范围更为有限。
- 侵入性:Orbit 的设计完全无侵入,可以无缝地与现有环境进行集成。而 Argo Rollouts 则具有完全的侵入性,可能需要对现有环境进行较大的调整。
- 灰度副本指定:Orbit 允许用户指定灰度副本部署到特定的 namespace,提供了更大的灵活性。
- 流量平滑度:Orbit 的流量平滑度可以通过配置进行调整,以满足不同的业务需求。而 Flux Flagger 在晋升过程中可能无法提供完全平滑的流量切换。
- 全链路灰度支持:Orbit 支持全链路灰度发布,可以更好地协调工作负载。而 Argo Rollouts 和 Flux Flagger 主要以单一工作负载为粒度,可能较难进行全链路的协调。
- 配置复杂度:Orbit 的基础功能可通过 UI 界面进行操作,高级功能可通过 yaml 文件进行声明,用户体验更友好。而 Argo Rollouts 的配置可能较为复杂,Flux Flagger 则需要配置灰度用 Service、TrafficRef 等。
- 产品观测性:Orbit 的观测性出色,用户可以通过 UI 界面对整个环境进行全局性的观测。相比之下,Argo Rollouts 也提供了详细的观测信息,但需要通过命令行进行操作,Flux Flagger 则未提供相关功能。
- 版本管理:Orbit 的版本管理基于 Open Application Model (OAM),与业务模型相结合。而 Argo Rollouts 主要基于 revision 进行版本管理,Flux Flagger 则不支持版本管理。
- 业务价值交付的整合:Orbit 在业务层面的价值交付方面具有显著优势。它整合了版本变更管理,能够自动识别并关联变更事项,实现发布的版本不仅仅是镜像的版本号,也包含了用户故事与业务价值的交付。这一点超越了 Argo Rollouts 和 Flux Flagger 的功能范围,让发布过程与业务价值更紧密地结合在一起。
在基于 Orbit 实践 GitOps 渐进式交付的流程中,开发人员需要将他们负责的代码、配置和 SQL 脚本等变更提交到代码仓库。业务代码的提交会触发持续集成(CI)流程,该过程将构建新的应用镜像,并将其存储在镜像仓库中。
此时,Orbit 的 GitOps 自动拣配引擎开始发挥作用。它会持续监听应用制品库和代码仓库,自动拣配镜像、配置和 SQL 变更。这些变更不仅被整合到同一个版本范畴里,还以可视化的方式在版本中展示,使得开发者或发布人员能够在版本发布前对所有变更进行审核。
接着,这些变更将通过 Orbit 的 All In One 发布引擎进行发布。该引擎将应用的所有变更进行聚合,并原子化、版本化地发布到多个环境中。这一过程保证了发布的一致性和可靠性,减少了因环境不一致而引发的问题。同时,Orbit 也支持基于版本进行原子化的回滚,进一步提升了发布流程的可控性和安全性。
总体来说,Orbit 通过 GitOps 自动拣配引擎和 All In One 版本化发布,实现了高效、准确和灵活的应用发布流程。开发者只需关注他们负责的代码、配置和 SQL 脚本等,而发布的一致性、可靠性和可追溯性由 Orbit 提供保障,大大简化了发布过程,提高了工作效率。
GitOps 的实践不仅仅局限于交付阶段,其理念和方法同样可以运用到应用的建模和运维等其他生命周期阶段。Orbit 作为云原生应用全生命周期管理工具,能更好地实现 GitOps 全流程。
Orbit 提出了云原生架构下应用的三层架构模型,业务层声明了应用的基础元素,包含服务、服务配置和数据库脚本,交付层声明了应用的交付流程,资源层则声明了应用运行时的环境和基础设施,基于 Application as Code 理论将应用模型存储在代码仓库中,实现统一演进,可审计、可回溯。
除此之外,我们基于 OAM 规范提供了视角分离的解决方案,企业内少部分云原生专家通过服务模板去封装 k8s 的规范,通过运维插件去封装 k8s 生态的扩展能力,比如说资源限制、探针等 k8s 原生能力,或者是监控、链路追踪等 k8s 生态能力,云原生专家可以根据实际情况,规定生产环境必须开启资源限制、探针、监控等运维插件,落地云原生规范,研发同学基于服务模板和运维插件以可视化表单的方式填写业务参数即可完成服务的创建,大幅降低云原生复杂性左移对研发的影响。
面对应用发布效率和可靠性的挑战,Orbit 的解决方法是 GitOps 自动拣配引擎和 All In One 版本化发布,开发者只需要专注自己负责的代码、配置和 SQL 脚本,Orbit 的 GitOps 自动拣配引擎会持续监听应用制品库和代码仓库,自动拣配镜像、配置、SQL 变更。
随后这些应用的变更物料会被我们的 All in One 发布引擎聚合,并以可视化的方式在版本中体现,开发者或者发版人员在版本发布前可以对所有变更进行审核,确认无误后执行应用发版流程,将应用以原子化、版本化地发布到多个环境中,保障了多环境发布的一致性和可靠性,同时 Orbit 也可以基于版本进行原子化的回滚。
应用发布效率和可靠性的问题解决后,面对应用运维出现的工具孤岛、视角割裂和数据断层的问题,Orbit 推出了以应用为中心的混合云统一观测平面,Orbit 自研 adapter 服务,统一处理监控告警、日志和链路追踪数据,并对每一种类型提供了一套数据标准,实现了观测工具的可扩展性,用户可自由选择 Orbit 官方支持的观测工具,也可以自行扩展其他观测工具。
adapter 模式屏蔽了观测工具的复杂性,在此基础上,我们重新设计观测界面,并全部内置到应用的环境内,再结合应用模型,最终为用户呈现出以应用为中心,以研发为视角的观测产品,无是开源和云混合使用的场景,还是多云多环境场景,对于研发来说,均是在同一个应用中浏览,无需再切来切去费时费力,解决工具孤岛问题,同时,观测产品所呈现出来的数据是以应用为中心的,也就是说,在这个应用内,通常仅可以看到当前应用内的观测数据,解决视角割裂问题。
面对数据断层问题,我们需要建立观测工具之间的关联性, OpenTelemetry 技术的兴起,给了我们一条很好的通路,微服务架构下,链路追踪记录了一次用户请求所经过的全部节点以及上下文信息,使系统数据具备业务性质,将链路追踪的唯一标识 TraceID 记录到日志和监控系统中,不仅可以解决观测工具间的数据断层问题,还可以让整个观测数据具备业务属性,建立业务相关的统一观测平面。
目前 Orbit 开源生态兼容上,支持 Prometheus、Loki、EFK、Skywalking、Jaeger 等主流开源观测产品,同时,为了保证用户在生产环境上观测工具的可靠性,我们也对接了腾讯云云监控、应用性能观测和日志服务产品,为生产环境保驾护航。
尽管 GitOps 是 DevOps 的重要实践之一,但我们明白 DevOps 的领域远不止于此。因此,Orbit 只是 CODING 平台中一部分产品能力的表现。
权威机构 Gartner 认为,在云原生环境下,我们需要建立面向服务的 DevOps 理念,通过平台级能力为服务团队提供 DevOps 的支持。这种模式被认为是最适合微服务的 DevOps 服务模式,其核心价值主张就是“DevOps as a Service”。
在这个背景下,研发支持团队的任务就是为开发团队提供一个稳定而强大的工程平台,帮助他们屏蔽复杂的底层基础设施。这个平台应包含开发者所需的各种工具、自助的开发者服务界面、以及可复用的模板,以满足开发团队的日常需求。
在这里,团队拓扑理论为我们提供了一个理解和设计开发组织的框架。它强调根据组织的业务目标和沟通流动性来设计开发团队的结构,以达到最优的协作效果。团队拓扑帮助我们理解,不同类型的团队(例如,平台团队和开发团队)之间如何通过明确定义的交互模式(例如,协作或服务)进行有效的合作。
而平台工程的出现,其实是团队拓扑发展的必然结果。在现代软件开发中,由于技术复杂度和变化速度的加快,以及微服务架构的广泛使用,开发团队不再能够有效地关注所有的技术细节。平台工程就是将这些通用、底层的工作抽象出来,由专门的平台团队来提供,从而让服务团队能够专注于他们的主要目标。
因此,CODING 平台的目标是作为平台工程的核心支持力量,通过实现优秀的团队拓扑和提供强大的平台工程能力,来帮助各个团队更好地面向价值交付,实现工业化的软件生产线。