9.4.3. A/B 部署
A/B 部署策略允许您在生产环境中以有限的方式尝试应用程序的新版本。您可以指定生产版本获得大多数用户请求,同时让有限比例的请求进入新版本。由于您控制对每个版本的请求部分,在测试过程中,您可以增加对新版本的请求的比例,最终停止使用上一版本。当您调整每个版本的请求负载时,可能需要扩展各个服务中的 pod 数量,以提供预期的性能。
除了升级软件外,您还可以使用此功能来试验用户界面的不同版本。由于部分用户会使用旧版本,而另外的一部分用户会使用新版本,因此您可以评估用户对不同版本的反应,以做出明智的设计决策。
要实现这一目的,旧的和新版本需要足够相似,两者可以同时运行。这常用于对程序错误修复的发布,也适用于新功能不会影响到旧功能的情况。版本需要 N-1 兼容性 才能正常工作。
OpenShift Container Platform 通过 Web 控制台和命令行界面支持 N-1 兼容性。
9.4.3.1. A/B 测试的负载均衡
用户设置使用多个服务设置路由。每个服务负责应用程序的一个版本。
每个服务分配到一个 weight
,进入每个服务的请求的比例等于 service_weight
除以 sum_of_weights
。每个服务的 weight
分布到该服务的端点,使得端点 weight
的总和等于服务 weight
。
路由最多可有四个服务。服务的 weight
可以在 0
到 256
范围内。当 weight
等于 0
时,服务不参与负载均衡,但继续为现有的持久连接服务。当服务 weight
不为 0
时,每个端点的最小 weight
为 1
。因此,拥有大量端点的服务会得到高于必要值的 weight
。这时,可以减少 pod 数量来获得所需的负载均衡 weight
。如需更多信息,请参阅 Alternate Backends 和 Weights 部分。
Web 控制台允许用户设置权重并在它们之间显示平衡:
设置 A/B 环境:
创建两个应用程序并使用不同的名称。每一个都会创建一个部署配置。应用程序是同一程序的不同版本;一个是当前生产版本,另一个是提议的新版本:
$ oc new-app openshift/deployment-example1 --name=ab-example-a $ oc new-app openshift/deployment-example2 --name=ab-example-b
公开部署配置以创建服务:
$ oc expose dc/ab-example-a --name=ab-example-A $ oc expose dc/ab-example-b --name=ab-example-B
此时两个应用都已部署,并且正在运行并且具有服务。
通过路由对外提供应用程序。此时可以公开任何服务,公开当前生产版本和后来修改路由以添加新版本。
$ oc expose svc/ab-example-A
通过
ab-example.<project>.<router_domain>
访问应用程序,验证您能否看到所需的版本。当您部署路由时,路由器将根据为服务指定的
weight
来均衡流量。此时,有一个带有默认weight=1
的单个服务,因此所有请求都会进入该服务。将其他服务添加为alternateBackend
,调整weight
会使 A/B 设置生效。这可通过oc set route-backends
命令或编辑路由来完成。将
oc set route-backend
设置为 0 意味着服务不参与负载均衡,而是继续为现有的持久连接服务。注意对路由的更改只会改变流量进入各个服务的比例。您可能需要扩展部署配置,以调整 pod 数量,以处理预期的负载。
若要编辑路由,请运行:
$ oc edit route <route-name> ... metadata: name: route-alternate-service annotations: haproxy.router.openshift.io/balance: roundrobin spec: host: ab-example.my-project.my-domain to: kind: Service name: ab-example-A weight: 10 alternateBackends: - kind: Service name: ab-example-B weight: 15 ...
9.4.3.1.1. 使用 Web 控制台管理 Weights
- 导航到 Route 详情页面 (Applications/Routes)。
- 从 Actions 菜单中选择 Edit。
- 选中 Split traffic across multiple services。
Service Weights 滑块设置发送到各个服务的流量的百分比。
如果在超过两个服务之间进行流量分割,各个服务的相对权重通过 0 到 256 范围内的整数来指定。
在分割流量的应用程序的展开行中 Overview 上会显示流量加权情况。
9.4.3.1.2. 使用 CLI 管理 Weights
此命令会由路由管理服务和对应的权重负载均衡。
$ oc set route-backends ROUTENAME [--zero|--equal] [--adjust] SERVICE=WEIGHT[%] [...] [options]
例如,以下命令将 ab-example-A
设置为主服务,weight=198
和 ab-example-B
作为第一个替代服务,值为 weight=2
:
$ oc set route-backends web ab-example-A=198 ab-example-B=2
这意味着 99% 的流量将发送到服务 ab-example-A
,1% 发送到服务 ab-example-B
。
此命令不扩展部署配置。您可能需要进行此操作,才能有足够的 pod 来处理请求负载。
不带标志的命令会显示当前的配置。
$ oc set route-backends web NAME KIND TO WEIGHT routes/web Service ab-example-A 198 (99%) routes/web Service ab-example-B 2 (1%)
--adjust
标志可让您更改单个服务相对于自身或主服务的权重。指定百分比将调整相对于主服务或第一个替代服务(如果指定了主服务)的服务。如果还有其他后端,它们的权重会与更改的比例保持比例。
$ oc set route-backends web --adjust ab-example-A=200 ab-example-B=10 $ oc set route-backends web --adjust ab-example-B=5% $ oc set route-backends web --adjust ab-example-B=+15%
--equal
标志将所有服务的权重
设置为 100
$ oc set route-backends web --equal
--zero
标志将所有服务的 weight
设为 0。所有请求都将返回 503 错误。
并非所有路由器都支持多个后端或加权后端。
9.4.3.1.3. 一个 Service,多个部署配置
如果您安装了路由器,请通过路由(或直接使用服务 IP)提供应用程序:
$ oc expose svc/ab-example
通过 ab-example.<project>.<router_domain>
访问应用程序,验证您能否看到 v1 镜像。
根据与第一个分片相同的源镜像创建第二个分片,但使用不同的标记版本,并设置唯一值:
$ oc new-app openshift/deployment-example:v2 --name=ab-example-b --labels=ab-example=true SUBTITLE="shard B" COLOR="red"
编辑新创建的分片,以设置对所有分片通用的
ab-example=true
标签:$ oc edit dc/ab-example-b
在编辑器中,将
spec.selector
和spec.template.metadata.labels
所在的ab-example: "true"
行与现有的deploymentconfig=ab-example-b
标签一起添加。保存并退出编辑器。触发第二个分片的重新部署以获取新标签:
$ oc rollout latest dc/ab-example-b
在这一刻,路由下同时提供了两组 pod。但是,由于两个浏览器(通过保持连接打开)和路由器(默认为 Cookie)将尝试保留与后端服务器的连接,所以您可能不会看到两个分片都返回给您。要将浏览器强制到其中一个分片,请使用 scale 命令:
$ oc scale dc/ab-example-a --replicas=0
刷新浏览器应该会显示 v2 和 shard B (红色)。
$ oc scale dc/ab-example-a --replicas=1; oc scale dc/ab-example-b --replicas=0
刷新浏览器应该会显示 v1 和 shard A (蓝色)。
如果您在任一分片上触发部署,则只有该分片中的 pod 会受到影响。您可以通过
oc edit dc/ab-example-a
或oc edit dc/ab-example-b
更改SUBTITLE
环境变量来轻松地触发部署。您可以通过重复步骤 5-7 来添加额外的分片。注意这些步骤将在以后的 OpenShift Container Platform 版本中简化。