概要:Kubernetes改造与自动化灰度发布是一个长期的过程,需要克服很多困难。但改造也能实实在在带来研发效能的提升,支持灰度发布以后,测试的主要时间可以从晚上转到白天,减轻研发和测试和运维人员的负担。
文章作者:中移(苏州)软件技术有限公司 SaaS产品部 研发经理 王艳辉
本文由同事代发
今年以来,云视频技术团队陆续对7款子产品进行了架构上的调整。以短视频SDK为公司试点产品,率先接入公司的蓝鲸平台,并进行了灰度发布一期和二期的工作。其他6款子产品也快速跟进,首批完成了自动化的灰度发布。整个过程如下所示:分为容器化、Kubernetes部署、cicd/ops自动化部署与灰度发布4个阶段。如下图所示:
通过自动化部署和灰度发布,研发效能得到显著提升。本文将回顾自动化部署与灰度发布的改造历程,并详细介绍云视频灰度发布的整体架构、引流策略设置、自动化灰度发布过程以及成效。
容器化是改造的第一步。在改造以前,云视频各个子产品都是非容器化的。后端直接以jar包的形式部署在虚拟机上,前端以源文件的形式部署在nginx中。容器化的核心是制作镜像,制作镜像的核心是编写DockerFile。
云视频前端DockerFile的核心脚本如下:(以媒体转码为例)
FROM nginx
COPY.//usr/share/nginx/html/api/page/cloudvideo/vt/
COPY Nginx/default.conf /etc/nginx/conf.d/default.conf
云视频后端DockerFile的核心脚本如下:(以媒体转码为例)
FROM williamyeh/java8:latest
ARG JAR_VERSION
ENV RUN_USER root
ENV RUN_GROUP root
ADD cloud-video-vt-provider-encrypted.jar /app/cloud-video/transcoding/app.jar
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app/cloud-video/transcoding
USER $RUN_USER
CMD java -jar /app/cloud-video/transcoding/app.jar
进入DockerFile所在的目录
docker build -t 镜像名称 .即可打包镜像。
Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。
容器化改造完成,即可开始Kubernetes的部署。在接入cicd和ops平台以前,Kubernetes的部署采用手动的方式,即手动编写yaml脚本,手动执行Kubernetes命令对服务进行启动停止。云视频在研发域、测试域、生产域各自搭建了一套Kubernetes环境。
Kubernetes编排的载体是yaml文件,通过yaml文件描述pod、deployment、service等内容。以下展示云视频核心的yaml文件内容:(以视频安防为例)
如果仅仅实现Kubernetes,而不支持自动化,那么部署将是一件非常麻烦的事情。云视频改造之初也经历过这种痛苦。特别是生产环境,由于生产域对cicd制品库的网络不通,每次上线都需要手动上传镜像,然后加载到每一台机器,非常耗时。因为需要支持自动化的发布才能体现出容器化的优势。在研发域、测试域、生产域,支持自动化部署的方式各不相同。在研发和测试域通过cicd,在生产域则通过应用发布自动化平台。
研发域通过代码触发的方式,代码提交后自动触发编译,编译完成打包镜像推送至研发域镜像仓库,然后触发研发环境的Kubernetes重新部署镜像。
测试域域通过手动触发的方式,分为编译和部署两个阶段。编译阶段将镜像打包到部门镜像仓库,部署阶段测试域镜像仓库会将镜像同步到测试域的镜像仓库。在部署阶段,将测试域的镜像拉到Kubernetes进行部署。测试域的部署流水线如下:
线上则使用应用发布自动化平台。在应用发布自动化平台,可以创建模板集(Kubernetes的yaml文件)和发布流水线。应用发布自动化平台会同步制品库的镜像,因此使用应用发布自动化平台部署,不需要再手动上传镜像,但需要修改模板集中的镜像地址,由制品库的地址改为各个资源池的地址。
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
依赖ops平台可以实现自动化的灰度发布。以下是灰度发布流水线(以短视频为例):
流水线分为五步,开始、启动灰度服务,引流、切流、结束。中间三步是核心。启动灰度服务是指启动新版本的服务。引流是将特定的一些流量引到灰度版本。切流是将所有的流量引到新版本,完成正式发布。下一章将详解灰度发布的内容。
云视频已经完成统一域名改造,所有请求都会经过中心网关,然后再到云视频。网关中携带了用户信息。云视频的入口,是一主一备两台nginx。由nginx转发至Kubernetes的ingress。当做灰度发布时,启动了两个ingress,一个做正常的引流,一个做灰度引流。云视频采用的是基于用户id的引流,当特定的账号请求时,返回各产品灰度的前端和后端服务,当是非特定账号的请求时,返回正常的前端和后端服务。
云视频7款子产品都实现了全场景(前端、后端、数据库、配置)的灰度发布覆盖
覆盖场景如下所示(以视频安防为例)
云视频使用前后端分离的架构,前端与后端为独立的Kubernetes服务。在用户达到前端服务以前,先经过ingress,ingress根据用户判断请求灰度服务还是正常服务。
云视频灰度发布覆盖了数据库新增和配置新增的场景。新增数据库和配置后,新的代码可以用到新增的配置和数据库字段,老的代码不会用到新增的数据库和配置。请求示意图如下:
云视频基于ingress-nginx做引流。Ingress-nginx做引流有如下方式:
nginx.ingress.kubernetes.io/canary-by-header:基于Request Header的流量切分,适用于灰度发布与A/B测试
nginx.ingress.kubernetes.io/canary-by-header-value:需要匹配Request Header的值,用于通知Ingress将请求路由到Canary Ingress中指定的服务
nginx.ingress.kubernetes.io/canary-by-header-pattern:除了PCRE Regex匹配之外,它的工作方式与canary-by-header-value相同
nginx.ingress.kubernetes.io/canary-by-cookie:基于Cookie的流量划分,适用于灰度发布与A/B测试
nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量划分,适用于蓝绿发布
具体到策略上,最常用的,有基于ip的引流,基于流量的引流,基于用户的引流。
云视频选择基于基于用户的引流方式。是基于产品自身特点决定的。
(1)云视频一开始就接入了op网关,能够很方便的拿到用户信息(header中有user_id),对于前端服务和后端服务,都能够根据user_id进行引流。
(2)云视频做灰度发布的最主要作用,是方便测试。通过用户的方式,可以精准引流,需要测试时,只需要将所需要的的用户信息配置到ingress中就可以了。
因此,云视频选择基于用户的引流方式。主要基于nginx.ingress.kubernetes.io/canary-by-header和nginx.ingress.kubernetes.io/canary-by-header-pattern两个配置来做。这里需要注意的是,canary-by-header-pattern需要比较高的ingress-nginx版本才支持,短视频SDK试点时使用的ingress-nginx版本比较低,导致正则表达式不生效,排查了很久,最后将版本升级到0.35.0解决问题。
云视频灰度ingress截图:
灰度发布的流程图如下:
(1)研发阶段
研发阶段包括研发和测试域测试。这个过程和普通发布的要求是相同的。需要产出测试域测试报告。
(2)灰度发布阶段
灰度发布前先提变更工单,与普通发布不同,灰度发布可以提白天的变更工单,可以在白天开始变更。变更工单需要关联蓝鲸平台的流水线id。灰度发布的产出物为灰度发布测试报告。
(3)正式发布阶段
正式发布阶段不再需要部署,只需要切流即可。切流以后,测试可以使用非灰度的账号进行测试。测试完成出具正式环境的测试报告,变更结束。
Kubernetes自动化部署与灰度发布可以带来实实在在研发效能的提升。这主要体现在4个方面,分别是部署时机、部署时长、部署准确性和参与人数4个方面。
4.2.1 部署时机
常规发布需要在晚上进行,一般要提22:00以后的变更。这样势必造成主要的部署和测试工作在晚上进行,让研发人员、运维人员、测试人员经受熬夜通宵之苦。灰度发布可以提白天的变更,部署和主要的测试工作在白天进行,正式变更时只要进行切流,无需再进行部署,测试人员也不再需要全量测试。这样可以大大缓解晚上上线的压力。
4.2.2 部署时长
接入应用自动化平台可以大大降低部署时长。容器化后,没有接入自动化以前,需要手动上传镜像,然后发布到每一台node节点。非常耗时,部署一次在1小时左右,接入自动化平台以后10分钟左右即可完成。
4.2.3 部署准确性
接入应用发布自动化平台以后,可以提高部署的准确性,以前由于手动上传镜像。偶尔会出现部署不准确的现象。接入以后基本准确性能到100%。
4.2.4 部署时机
综合自动化部署和灰度发布的综合成效,一次发布节省人力在2人左右。原来需要投入4个人的,现在需要投入2个人即可。节省效能50%。
Kubernetes改造与自动化灰度发布是一个长期的过程,需要克服很多困难。但改造也能实实在在带来研发效能的提升,支持灰度发布以后,测试的主要时间可以从晚上转到白天,减轻研发和测试和运维人员的负担。希望有更多的产品能够接入进来,提升发布效率。
作者:王艳辉
链接:移动云开发者社区
来源:移动云官网开发者社区