OpenShift

OpenShift 4 Hands-on Lab- 应用部署和切换策略(蓝绿、金丝雀和A/B、回滚)

应用上线部署策略


本节介绍应用部署上线和切换应用访问的常用策略。虽然可以根据需要灵活使用以下策略,但由于本节使用了同一组验证的应用,因此请按顺序进行下面3个Lab操作。
在部署应用前,需要将https://github.com/liuxiaoyu-git/bluegreen.git的代码fork到自己的GitHub账户下,下文将用“MY_GITHUB”代表用户各自的GitHub账户名。

蓝绿部署



蓝绿部署是最常见的一种不间断的应用升级部署的方式,蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚。蓝绿部署的特点是在一个时间点请求会100%地发给蓝绿部署中的一个目标。

蓝绿部署通常生产环境需要两组配置,一组是active的生产环境的配置,一组是inactive的配置。用户访问的时候,只让用户访问active的服务器集群。蓝色环境(active)运行旧版本应用version1。当要升级到version2,先在绿色环境中部署新版本应用,并进行测试。如果测试没问题,就可以把路由指向绿色环境。

1.依次执行以下命令,首先创建项目,然后部署blue版的应用,在根据Service生成Route。

$ oc new-project USER-ID-bluegreen
$ oc new-app https://github.com/MY_GITHUB/bluegreen.git#master --name=blue -n USER-ID-bluegreen
$ oc expose service blue --name=bluegreen -n USER-ID-bluegreen
$ oc get route bluegreen -n USER-ID-bluegreen
NAME        HOST/PORT                                                                    PATH   SERVICES   PORT       TERMINATION   WILDCARD
bluegreen   bluegreen-mywar.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com          blue       8080-tcp                 

2.用浏览器访问以上Route地址,可以看到以下显示Blue的页面。

3.部署Green版的应用。

$ oc new-app https://github.com/MY_GITHUB/bluegreen.git#green --name=green -n USER-ID-bluegreen

4.将Route访问的后台服务切换到Green应用上。

$ oc patch route/bluegreen -p '{"spec":{"to":{"name":"green"}}}' -n USER-ID-bluegreen

5.再次用浏览器访问应用的Route对应的http://bluegreen-mywar.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com地址,可以看到此时显示的已经是Green版的应用页面了。

金丝雀发布和A/B测试


我把金丝雀发布和A/B测试放在一起,因为它们的特点都是在一个时间点允许将请求根据需要流向不同的目标,不过金丝雀发布和A/B测试有不同的目的。金丝雀发布又名灰度发布,是用逐步过渡的方法实现新版本应用上线的一种发布策略;而A/B测试主要是用来测试一个应用的不同实现版本的差异化表现的方法,例如评估两个不同界面风格的应用哪个更受用户的欢迎、其性能差异等。

通过调整Route权重实现

1.执行命令,编辑名为bluegreen的Route。

$ oc edit route bluegreen -n USER-ID-bluegreen

2.在“spec”区域的“to”后增加“alternateBackends”一段内容,修改完“spec”区域的内容应该如下:

。。。
spec:
  host: YOUR-HOST
  port:
    targetPort: 8080-tcp
  subdomain: ""
  to:
    kind: Service
    name: green
    weight: 50
  alternateBackends:
    - kind: Service
      name: blue
      weight: 50
  wildcardPolicy: None
  。。。

3.保存bluegreen的Route配置后执行命令查看bluegreen的Route的blue和green各有50%的机会接收请求。

$ oc get route bluegreen -n USER-ID-bluegreen
NAME        HOST/PORT                                                                    PATH   SERVICES               PORT       TERMINATION   WILDCARD
bluegreen   bluegreen-mywar.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com          green(50%),blue(50%)   8080-tcp                 

4.执行以下命令,查看红色加亮的字体,确认数量基本是一样的。

$ while true;do curl $(oc get route bluegreen -n USER-ID-bluegreen -o template --template '{{.spec.host}}') | grep -e green -e blue;done

5.分别执行以下命令,分别将blue和green接收请求的比例设为30%-70%以及50%-50%,然后用(4)脚本确认。

$ oc set route-backends bluegreen --adjust blue=30% -n USER-ID-bluegreen
$ oc set route-backends bluegreen --adjust blue=+10% -n USER-ID-bluegreen
$ oc set route-backends bluegreen --equal -n USER-ID-bluegreen

通过调整Pod数量实现


还可用一个Service对应多个Deployment,然后通过调整Deployment中运行的Pod实例数实现在不同版本的应用分配流量。

1.执行以下命令,先根据App Image创建ab-example应用和对应的Route资源,然后只保留应用的Service和Route配置(删除Deployment配置)。再根据App Image创建ab-example-a和ab-example-b应用,然后只保留它们的Deployment(删除Service配置)。这样就有了1个Service和2个Deployment。

$ oc new-project USER-ID-ab
$ oc new-app openshift/deployment-example:v1 --name=ab-example --labels=ab-example=true -n USER-ID-ab
$ oc expose svc/ab-example --name=ab-example -n USER-ID-ab
$ oc delete deployment/ab-example -n USER-ID-ab
$ oc new-app openshift/deployment-example:v1 --name=ab-example-a --labels=ab-example=true -n USER-ID-ab
$ oc new-app openshift/deployment-example:v2 --name=ab-example-b --labels=ab-example=true SUBTITLE=Shard-B COLOR=red -n USER-ID-ab
$ oc delete svc/ab-example-a -n USER-ID-ab
$ oc delete svc/ab-example-b -n USER-ID-ab

2.在OpenShift控制台的“开发者”视图中进入此项目的“拓扑”菜单,确认此时显示的“ab-example-a”和“ab-example-b”两个Deployment都没有对应的“服务”和“路由”。这是由于上一步我们手动删除了自动生成的“服务”。

3.此时名为ab-example的“服务”是通过“Pod选择器”选择用哪些Pod处理请求。在OpenShift控制台的“管理员”视图中进入“网络”的‘服务’。在列表中可以看到“Pod选择器”(见下图),然后点击“Pod选择器”下面的链接。

4.可以看到根据当前的条件(ab-example=true和deployment=ab-example),是没有对应的Pod。

5.如果删除“deployment=ab-example”条件,就可以选出2个Deployment定义的Pod。

6.再次通过“网络”的“服务”菜单进入ab-example,然后点击“操作”的“编辑Pod选择器”项目。

7.在“编辑 Pod 选择器”对话框中点击“deployment=ab-example”右侧删掉图标,然后点击“保存”关闭窗口。

8.此时在ab-example的“服务”界面中进入“Pod”标签,可以看到该Service已经对应上2个Pod了,它们分别由ab-example-a和ab-example-b部署的。

9.此时回到这个项目的“开发者”视图的“拓扑”菜单,可以看到下图,其中2个Deployment都对应了相同的Service名称和Route地址。

10.多次执行以下命令,确认可以轮流看到v1和v2版本应用。

$ while true;do curl $(oc get route ab-example -n USER-ID-ab -o template --template '{{.spec.host}}') | grep -e v1 -e v2;done

11.先执行以下命令,将名为ab-example-a的Deployment运行的Pod数设为0。然后在执行(9)命令,确认只能看到v2版本应用。

$ oc scale deployment/ab-example-a --replicas=0 -n USER-ID-ab

12.执行以下命令,将名为ab-example-b的Deployment运行的Pod数设为0,将名为ab-example-a的Deployment运行的Pod数设为1。然后在多次执行(9)命令,确认只能看到v1版本应用。

$ oc scale deployment/ab-example-a --replicas=1 -n USER-ID-ab
$ oc scale deployment/ab-example-b --replicas=0 -n USER-ID-ab
$ while true;do curl $(oc get route ab-example -n USER-ID-ab -o template --template '{{.spec.host}}') | grep -e v1 -e v2;done

部署回滚


注意:回滚Rollback只适用于使用OpenShift提供的DeploymentConfig部署的应用,而不适用于使用Kubernetes的Deployment部署的应用。
下面首先部署version 1版的blue应用,再更改应用到新版本version 2后再次部署blue,当发现部署后的新版本应用出现问题,可以通过部署回滚快速切换到以前运行正常的version 1版本应用。

1.使用DeploymentConfig部署version 1版的blue应用。

$ oc new-project USER-ID-rollback
$ oc new-app https://github.com/MY_GITHUB/bluegreen.git#master --name=blue --as-deployment-config -n USER-ID-rollback
$ oc expose service blue --name=bluegreen -n USER-ID-rollback
$ oc get route bluegreen -n USER-ID-rollback


2.进入https://github.com/MY_GITHUB/bluegreen.git,选择requestHandlers.js文件,然后点击History右侧的编辑图标。

3.找到“”,在后面增加“version 1”用来做版本跟踪,然后点击页面最下方的Commit changes图标

'<body> version 1'+

4.在OpenShift控制台的“开发者”视图中进入“构建”,然后进入名为“blue”的BuildConfig,在其中查看“构建”栏目。点击右上方的“操作”下拉菜单中的“开始构建”。

5.此时页面会转到“blue-2”的构建界面,进入“日志”栏目可以看到构建的进度。

6.进入OpenShift控制台“开发者”视图的“拓扑”菜单,可以看到blue图标的变化过程,这说明当构建完后OpenShift会自动触发部署新构建的App Image。

7.选中上图blue的图标,然后在右侧滑出部分进入“详细”。当DeploymentConfig部署过程完成后,blue的“最新版本”会变为2(DeploymentConfig每成功部署一次,“最新版本”会增加1)。

8.用命令查看blue的DeploymentConfig。注意,DeploymentConfig每变化一次,REVISION就会增加“1”。

$ oc get dc/blue -n USER-ID-bluegreen
NAME   REVISION   DESIRED   CURRENT   TRIGGERED BY
blue   2          1         1         config,image(blue:latest)

9.访问bluegreen的Route,会发现页面会显示“version 1”

$ curl $(oc get route bluegreen -n USER-ID-rollback -o template --template '{{.spec.host}}') | grep version

10.重复以上2-8操作,将页面从“version 1”改为“version 2”,然后再手动触发一次构建。在完成后OpenShift会自动将构建的最新App Image部署起来,此时再执行(9)页面就会显示“version 2”。

11.执行以下命令,将显示version 2的blue应用退回到上一个显示version 1的版本。在回退完后,用(9)步的命令验证。

$ oc rollout undo dc/blue -n USER-ID-rollback 
deployment.apps/blue rolled back

12.执行命令查看当前有多少和blue相关的Build,可以看有以下3个。

$ oc get build -n USER-ID-rollback
NAME     TYPE     FROM          STATUS     STARTED             DURATION
blue-1   Source   Git@31c4e83   Complete   About an hour ago   1m14s
blue-2   Source   Git@e7df24a   Complete   About an hour ago   1m29s
blue-3   Source   Git@69b099b   Complete   About an hour ago   1m26s

13.查看名为“blue-2”的构建生成的App Image。

$ oc describe build blue-2 -n USER-ID-rollback | grep 'Image Digest'
Image Digest:   sha256:5fae117dd73f9dc28cb3228a8efc2a53cf15289bfd8224ef2163de59f4930c05

14.查看名为blue的ImageStream信息,它用来跟踪blue的App Image。通过镜像签名可确认有对应build-2生成的App Image(以下结果从下向上第2行)。

$ oc describe is blue -n USER-ID-rollback | grep blue
Name:                   blue
Namespace:              user1-rollback 
Labels:                 app=blue
                        app.kubernetes.io/component=blue
                        app.kubernetes.io/instance=blue
Image Repository:       default-route-openshift-image-registry.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com/user1-bluegreen/blue
  * image-registry.openshift-image-registry.svc:5000/user1-rollback /blue@sha256:e7dac0f2191e385b25c39ec5bf2108c75a7d6770417551b03e5f79b1f8e989d7
    image-registry.openshift-image-registry.svc:5000/user1-rollback /blue@sha256:5fae117dd73f9dc28cb3228a8efc2a53cf15289bfd8224ef2163de59f4930c05
    image-registry.openshift-image-registry.svc:5000/user1-rollback /blue@sha256:085591991c22f4f76ab9ffa0f4247eb6047710b99547c7514f38168f6e25d5cd

15.我们刚刚已经将blue的DeploymentConfig使用的App Image版本回退到了显示version 1的版本。执行下面命令可再次将DeploymentConfig回退到最后一个版本(即显示version 2)。

$ oc rollback blue -n USER-ID-rollback
deployment.apps.openshift.io/blue deployment #6 rolled back to blue-3
Warning: the following images triggers were disabled: blue:latest
  You can re-enable them with: oc set triggers dc/blue --auto

16.执行以下命令可将应用回退到初始版本(即不显示version 1或version 2)

$ oc rollback blue --to-version=1 -n USER-ID-rollback