应用灰度发布
Canary Deployment 是一种渐进式发布策略,它会将新版本应用逐步引入到一小部分用户或流量中。这种增量式发布允许团队在全面部署之前监控系统行为、收集指标并确保稳定性。该方法可以显著降低风险,尤其是在生产环境中。
Argo Rollouts 是一个 Kubernetes 原生的渐进式交付控制器,支持高级部署策略。它通过提供 Canary、Blue-Green Deployments、Analysis Runs、Experimentation 和 Automated Rollbacks 等功能扩展了 Kubernetes 的能力。它还可与可观测性栈集成,用于基于指标的健康检查,并提供基于 CLI 和监控面板的应用交付控制。
关键概念:
- Rollout:Kubernetes 中的自定义资源定义(CRD),用于替代标准的 Deployment 资源,从而支持蓝绿发布、灰度发布等高级发布控制。
- Canary Steps:一系列逐步切换流量的操作,例如先将 25% 的流量导向新版本,再将 50% 的流量导向新版本。
- Pause Steps:在进入下一个灰度步骤之前,引入等待间隔以进行手动或自动验证。
Canary Deployment 的优势
- 风险缓解:通过先将变更部署到一小部分服务器,你可以在全面发布前发现并解决问题,从而将对用户的影响降到最低。
- 增量式发布:这种方式允许逐步暴露新功能,有助于你有效监控性能和用户反馈。
- 实时反馈:Canary Deployment 能在真实环境条件下,提供有关新版本性能和稳定性的即时洞察。
- 灵活性:你可以根据性能指标调整部署过程,从而实现可动态暂停或回滚的发布。
- 成本效益:与 Blue-Green Deployments 不同,Canary Deployment 不需要单独的环境,因此资源利用率更高。
使用 Argo Rollouts 进行 Canary Deployment
Argo Rollouts 支持使用 canary 发布策略来发布 deployment,并通过 Gateway API Plugin 控制流量。在 ACP 中,你可以使用 ALB 作为 Gateway API Provider,为 Argo Rollouts 实现流量控制。
前提条件
- 集群中已安装带有 Gateway API plugin 的 Argo Rollouts。
- Argo Rollouts kubectl plugin(从这里安装)。
- 一个用于在其中创建 namespace 的 project。
- 集群中已部署 ALB,并已分配到该 project。
- 集群中用于部署应用的 namespace。
操作步骤
创建 Deployment
首先定义应用的“stable”版本,也就是用户当前访问的版本。创建一个 Kubernetes deployment,并设置合适的副本数、容器镜像版本(例如 hello:1.23.1)以及正确的标签,例如 app=web。
使用以下 YAML:
YAML 字段说明:
apiVersion:用于创建该资源的 Kubernetes API 版本。kind:指定这是一个 Deployment 资源。metadata.name:deployment 的名称。spec.replicas:期望的 pod 副本数。spec.selector.matchLabels:定义 Deployment 如何查找要管理的 pod。template.metadata.labels:应用到 pod 上的标签,供 Service 进行选择。spec.containers:每个 pod 中运行的容器。containers.name:容器名称。containers.image:要运行的容器镜像。containers.ports.containerPort:容器暴露的端口。
使用 kubectl 应用配置:
这就完成了生产环境的设置。
或者,你也可以使用 Helm Chart 来创建这些 deployment 和 service。
创建 Stable Service
创建一个 Kubernetes Service,用于暴露 stable deployment。该 service 会根据匹配标签将流量转发到 stable 版本的 pod。最初,service selector 会选择带有 app=web 标签的 pod。
YAML 字段说明:
apiVersion:用于创建该 Service 的 Kubernetes API 版本。kind:指定该资源是一个 Service。metadata.name:Service 的名称。spec.selector:根据标签标识要路由流量到哪些 pod。ports.protocol:所使用的协议(TCP)。ports.port:Service 暴露的端口。ports.targetPort:流量被转发到容器上的端口。
使用以下命令应用:
这样就可以从外部访问 stable deployment。
创建 Canary Service
创建一个 Kubernetes Service,用于暴露 canary deployment。该 service 会根据匹配标签将流量转发到 canary 版本的 pod。最初,service selector 会选择带有 app=web 标签的 pod。
YAML 字段说明:
apiVersion:用于创建该 Service 的 Kubernetes API 版本。kind:指定该资源是一个 Service。metadata.name:Service 的名称。spec.selector:根据标签标识要路由流量到哪些 pod。ports.protocol:所使用的协议(TCP)。ports.port:Service 暴露的端口。ports.targetPort:流量被转发到容器上的端口。
使用以下命令应用:
这样就可以从外部访问 canary deployment。
创建 Gateway
使用 example.com 作为访问服务的域名,创建 Gateway 以通过该域名暴露服务:
使用以下命令:
该 gateway 将分配一个外部 IP 地址,你可以从 gateway 资源中 status.addresses 里类型为 IPAddress 的条目获取该 IP 地址。
DNS 配置
在你的 DNS 服务器中配置该域名,使其解析到 gateway 的 IP 地址。使用以下命令验证 DNS 解析:
它应该返回 gateway 的地址。
创建 HTTPRoute
使用以下命令:
访问 Stable service
在集群外,使用以下命令通过该域名访问服务:
或者也可以在浏览器中访问 http://example.com。
创建 Rollout
接下来,使用 Canary 策略创建 Argo Rollouts 的 Rollout 资源。
YAML 字段说明:
-
spec.selector:pod 的标签选择器。会被该选择器选中的现有 ReplicaSet,将会受到此次 rollout 的影响。它必须与 pod template 的标签匹配。 -
workloadRef:指定 workload 引用以及要应用到 rollouts 的缩容策略。 -
scaleDown:指定在迁移到 Rollout 后是否缩减 workload(Deployment)。可选项如下:"never":Deployment 不会缩容。"onsuccess":Rollout 变为健康状态后,Deployment 才会缩容。"progressively":随着 Rollout 扩容,Deployment 会逐步缩容。如果 Rollout 失败,Deployment 会重新扩容。
-
strategy:Rollout 策略,支持BlueGreen和Canary策略。 -
canary:Canaryrollout 策略定义。canaryService:指向一个 service,controller 会更新它以选择 canary pod。流量路由时必需。stableService:指向一个 service,controller 会更新它以选择 stable pod。流量路由时必需。steps:定义在更新 canary 时要执行的一系列步骤。首次部署 Rollout 时会跳过这些步骤。setWeight:设置 canary ReplicaSet 的流量比例。pause:无限期或指定时长暂停 rollout。支持的单位:s、m、h。{}表示无限期暂停。plugin:执行已配置的插件,这里我们配置的是gatewayAPI插件。
使用以下命令应用:
这就为该 deployment 设置了 Canary 策略的 rollouts。它会先将权重设置为 50,并等待提升。50% 的流量将转发到 canary service。提升 rollout 之后,权重将设置为 100,100% 的流量将转发到 canary service。最终,canary service 将成为 stable service。
验证 Rollout
创建 Rollout 后,Argo Rollouts 会创建一个与 deployment 模板相同的新 ReplicaSet。当新 ReplicaSet 的 pod 处于健康状态时,deployment 会缩容到 0。
使用以下命令确保 pod 正常运行:
准备 Canary Deployment
接下来,将应用的新版本作为绿色部署准备就绪。使用新的镜像版本(例如 hello:1.23.2)更新 deployment web。使用以下命令:
这就为测试准备好了新的应用版本。
rollouts 会创建一个新的 ReplicaSet 来管理 canary pod,并且 50% 的流量会转发到 canary pod。使用以下命令验证:
当前有 3 个 pod 在运行,分别是 stable 和 canary 版本。此时权重为 50,50% 的流量会转发到 canary service。rollout 过程已暂停,等待提升。
如果你使用 Helm Chart 部署应用,请使用 Helm 工具将应用升级到 canary 版本。
访问 http://example.com 时,50% 的流量会转发到 canary service。你应该会从该 URL 得到不同的响应。
提升 Rollout
当 canary 版本测试通过后,你可以提升 rollout,将所有流量切换到 canary pod。使用以下命令:
要验证 rollout 是否完成:
如果 stable 的 Images 更新为 hello:1.23.2,并且 revision 1 的 ReplicaSet 已缩容到 0,这就表示 rollout 已完成。
访问 http://example.com 时,100% 的流量会转发到 canary service。
中止 Rollout(可选)
如果你在 rollout 过程中发现 canary 版本存在问题,可以中止该过程,将所有流量切回 stable service。使用以下命令:
验证结果:
访问 http://example.com 时,100% 的流量会转发到 stable service。