首页 微服务引擎MSE 最佳实践 微服务治理 通过云效CI/CD实现微服务全链路灰度

通过云效CI/CD实现微服务全链路灰度

为提高发布过程中产品整体的稳定性,开发人员希望能够用小部分特定流量验证新版本应用是否能正常工作,以在新版本出现问题时,及时发现并控制影响面。

前提条件

  • 在Kubernetes集群中部署应用。

  • 开通MSE微服务治理专业版。

整体架构

以如下Demo为例:

1

灰度验证通常采用以下策略。

  • 直接使用线上小部分流量来测试(按照百分比放量)。

  • 从线上按照特定规则选择流量(比如特定的Header、特定的Cookie等)。

  • 在客户端或浏览器上标识出流量是否灰度(比如通过Header传递)。

准备工作

开启MSE微服务治理

  1. 开通微服务治理专业版:

    1. 单击开通MSE微服务治理

    2. 微服务治理版本选择专业版,选中服务协议,然后单击立即开通

      关于微服务治理的计费详情,请参见计费概述

  2. 安装MSE微服务治理组件:

    1. 容器服务控制台左侧导航栏,选择市场 > 应用市场

    2. 应用市场页面搜索框输入ack-onepilot,单击搜索图标图标,然后单击组件。

    3. 详情页面开通该组件的集群,然后单击一键部署

    4. 创建面板中,选择集群和命名空间,然后单击下一步

    5. 参数配置页面,设置相应参数,然后单击确定

  3. 为应用开启微服务治理:

    1. 登录MSE治理中心控制台

    2. 在左侧导航栏选择微服务治理中心 > K8s集群列表

    3. K8s集群列表页面搜索目标集群,单击搜索图标图标,然后单击目标集群操作列下方的管理

    4. 集群详情页面命名空间列表区域,单击目标命名空间操作列下方的开启微服务治理

    5. 开启微服务治理对话框中单击确认

部署Demo应用程序

  1. 容器服务控制台左侧导航栏,单击集群

  2. 集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在集群管理页左侧导航栏,选择工作负载 > 无状态
  4. 无状态页面单击使用YAML创建资源

  5. 对模板进行相关配置,完成配置后单击创建

    本文示例部署A、B、C三个应用,以及注册中心Nacos Server,流量入口应用spring-cloud-zuul,流量调用链路为:spring-cloud-zuul->A->B->C。

    spring-cloud-zuul应用默认有100 qps正常流量,而另外有10 qps带有x-mse-tag: gray特殊Header,这个Header是MSE内置的灰度Header,只要带上x-mse-tag: gray这个Header,在开启MSE微服务治理并且安装Agent之后会自动路由到下游带有gray标签的节点上。根据需要,这个gray的值也可以替换成其他节点上打的标签。

    • 入口spring-cloud-zuul应用YAML。

      展开查看代码

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-zuul
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: spring-cloud-zuul
        template:
          metadata: 
            labels:
              app: spring-cloud-zuul
              msePilotCreateAppName: spring-cloud-zuul
          spec:
            containers:
              - name: spring-cloud-zuul
                image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-zuul:1.0.1
                imagePullPolicy: Always
                ports:
                  - containerPort: 20000
    • A应用基线(base)版本YAML。

      展开查看代码

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-a
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-a
        template:
          metadata:
            labels:
              app: spring-cloud-a
              msePilotCreateAppName: spring-cloud-a
          spec:
            containers:
            - name: spring-cloud-a
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 20001
              livenessProbe:
                tcpSocket:
                  port: 20001
                initialDelaySeconds: 10
                periodSeconds: 30
    • B应用基线(base)版本YAML:

      展开查看代码

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-b
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: spring-cloud-b
        strategy:
        template:
          metadata: 
            labels:
              app: spring-cloud-b
              msePilotCreateAppName: spring-cloud-b
          spec:
            containers:
            - name: spring-cloud-b
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 8080
              livenessProbe:
                tcpSocket:
                  port: 20002
                initialDelaySeconds: 10
                periodSeconds: 30
    • C应用基线(base)版本YAML。

      展开查看代码

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: spring-cloud-c
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: spring-cloud-c
        template:
          metadata:  
            labels:
              app: spring-cloud-c
              msePilotCreateAppName: spring-cloud-c
          spec:
            containers:
            - name: spring-cloud-c
              image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
              imagePullPolicy: Always
              ports:
              - containerPort: 20003
              livenessProbe:
                tcpSocket:
                  port: 20003
                initialDelaySeconds: 10
                periodSeconds: 30
    • Nacos Server应用YAML。

      展开查看代码

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nacos-server
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nacos-server
        template:
          metadata:
            labels:
              app: nacos-server
          spec:
            containers:
            - env:
              - name: MODE
                value: standalone
              image: nacos/nacos-server:v2.2.0
              imagePullPolicy: Always
              name: nacos-server
            dnsPolicy: ClusterFirst
            restartPolicy: Always
      
      # zuul网关开启SLB暴露展示页面
      ---
      apiVersion: v1
      kind: Service
      metadata:
        annotations:
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small
        name: zuul-slb
      spec:
        ports:
          - port: 80
            protocol: TCP
            targetPort: 20000
        selector:
          app: spring-cloud-zuul
        type: LoadBalancer
  6. 应用部署成功后,在MSE治理中心控制台观察A应用的流量,确认流量都打到未打标的节点,并没有灰度节点的流量。更多信息,请参见部署文档

    A应用流量分配

创建泳道

  1. 登录MSE治理中心控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择治理中心 > 全链路灰度

  3. 全链路灰度页面,单击创建泳道组及泳道。如果您选择的微服务空间内已经创建过泳道组,则单击+创建泳道组

  4. 创建泳道组面板中,选择入口应用以及整个链路涉及到的应用,然后单击确定

    配置项

    描述

    泳道组名称

    自定义设置泳道组的名称。

    入口类型

    选择Java服务网关

    入口应用

    根据实际情况选择。本示例为mse-test-spring-cloud-zuul。

    泳道组涉及应用

    选择入口应用或入口网关所涉及的所有相关服务。

    开启消息灰度

    开启消息灰度会打开泳道组所有应用的消息灰度开关。

    泳道组创建完成后,在全链路灰度页面的泳道组涉及应用区域,查看创建的泳道组。检查入口应用和所涉及的应用是否正确,如需变更泳道组信息,单击右侧的编辑图标并修改。

  5. 全链路灰度页面上方选择创建和泳道组时相同的微服务空间,然后底部单击点击创建第一个分流泳道

    如果您选择的微服务空间内已经创建过泳道,则单击创建泳道

    重要

    加入全链路流量控制的应用,将不再支持金丝雀发布、标签路由等功能。

  6. 创建泳道面板中设置流控泳道相关参数,将符合规则的应用划入gray泳道。然后单击确定

    配置项

    描述

    泳道名称

    自定义设置流控泳道的名称。支持大小写字母、数字、短划线(-)和下划线(_),长度不超过64个字符。

    配置应用标签

    配置方式:登录容器服务管理控制台,在应用YAML的spec.template.metadata.annotations下增加alicloud.service.tag:{tag}

    添加应用

    配置应用标签后,单击刷新按钮,下拉框中会出现相应的标签列表,选择对应的标签,就会自动添加相应的应用。

    路由规则

    • Path:要匹配的路径,可以多选。如不填写,将匹配任意路径。

    • 条件模式:路由条件之间的关系。

    • 条件列表:

      • 参数类型:表示参数的来源,可选值包括:Parameter(请求参数)、Header(请求头部)、Cookie、Body Content(JSON格式的请求body)。

      • 参数:参数名称。

      • 条件:匹配规则。

      • 值:表示要匹配的参数值。

配置完成后,访问网关。

  • 如果不符合灰度规则,走基线环境。1

  • 如果符合灰度规则,走灰度环境。1

配置云效流水线

本示例使用其他 · 空模板创建云效流水线。

步骤一:流水线源配置

  1. 登录云效Flow控制台

  2. 在左侧导航栏,单击我的流水线,然后单击右上角的新建流水线

  3. 选择流水线模板对话框,在左侧导航栏底部,单击其他,在右侧区域单击其他 · 空模板,然后单击创建

  4. 添加流水线源面板,配置流水线的来源,例如代码仓库等。单击添加

    1

    配置项

    描述

    选择代码源

    选择业务代码所在的代码源,本示例以通用Git为例。

    说明

    不同代码源需要配置的参数不同,请根据实际界面进行配置。

    代码仓库

    选择代码仓库。本示例为https://gitee.com/mse-group/alibabacloud-microservice-demo.git。

    默认分支

    手工运行和定时运行流水线时使用的分支,本示例为master。

    选择凭证类型

    选择服务连接

    服务连接

    添加服务连接按钮添加。本示例中代码仓库为公开代码仓库,按照默认值创建。

    开启分支模式

    在各特性分支上开发,流水线管理分支的集成和发布。

    工作目录

    配置流水线源的源文件将会被下载至工作目录下。如填写demo_abc,流水线会将文件下载至构建环境的/root/workspace/demo_abc路径。

步骤二:构建阶段配置

本阶段介绍配置云效如何构建Docker镜像、删除原有的阶段和空任务、手动添加新任务镜像构建。

  1. 单击阶段1区域的1,修改阶段名称为构建

    1
  2. 单击空任务,配置任务名称、构建集群等信息。

  3. 任务步骤右侧,单击添加步骤,选择构建 > 镜像构建并推送至阿里云镜像仓库个人版开始配置任务步骤,配置完成后,单击仅保存

11

配置项

描述

任务名称

自定义的任务名称,不修改则显示为默认名称。本示例为镜像构建。

构建集群

就近选择,可以选择北京构建集群。更多信息,请参见构建集群

下载流水线源

可为任务选择是否下载流水线源。开启下载流水线源后,配置流水线源的源文件将会被下载至对应的工作目录。本示例选择下载全部流水线源。

任务步骤

选择任务步骤。

步骤名称

输入自定义的步骤名称,不修改则显示为默认名称。

选择服务连接

选择任务连接的服务。如果没有服务连接,单击添加服务连接,根据界面提示添加ACR的服务连接,通过RAM授权的方式,让云效可以推送镜像到ACR中。

地域

在下拉列表中选择地域,例如华北3(张家口)。

仓库

在下拉列表中选择需要推送、部署的镜像仓库。

标签

保留默认${DATETIME}即可。

更多标签

同步构建更多Tag的镜像版本(非必填)。

Dockerfile路径

Dockerfile路径为Dockerfile文件相对于代码库根目录所在路径,例如mse-simple-demo/A/Dockerfile

ContextPath

ContextPath为docker build命令执行上下文路径。填写相对于代码根目录的路径,如果不填则为Dockerfile文件所在目录。

不使用缓存

如果选中,Docker Build将使用--no-cache=true参数进行镜像构建。

构建参数

构建参数为运行时会以-build-arg的形式传递到build命令中的一组参数。单击添加参数可以新增并配置构建参数。

任务插件

可以根据需要配置任务插件来发送流水线通知。

  • 钉钉机器人通知插件

    • webhook地址:配置钉钉机器人的webhook地址,钉钉机器人的创建步骤,请参见钉钉机器人配置

    • 运行时机:可以选择任务插件发送通知的时机。

  • 邮件通知

    • 邮件地址:配置需要发送通知的邮件地址。

    • 运行时机:可以选择任务插件发送通知的时机。

  • Webhook通知插件

    • webhook地址:配置需要发送通知的webhook地址,地址必须公网可访问。

    • 运行时机:可以选择任务插件发送通知的时机。

  • 企业微信群通知:你可以通过企业微信群接收通知。更多信息,请参见企业微信机器人发送群消息

  • 飞书群通知:在流水线任务中配置飞书群通知插件,为指定飞书群推送流水线运行信息。更多信息,请参见飞书机器人发送群消息

步骤三:部署gray阶段配置

云效可以直接替换Kubernetes中的Workload镜像,您可以直接使用此机制来发布。

  1. 流程配置页面的新阶段区域,单击新的任务

  2. 选择任务组页面的左侧导航栏,单击部署,再单击Kubernetes 镜像升级,配置任务名称构建集群等信息。单击仅保存

1

配置项

描述

任务名称

自定义的任务名称,不修改则显示为默认名称。本示例为发布gray。

构建集群

可为任务选择不同的构建集群。本示例为云效北京构建集群

下载流水线源

可为任务选择是否下载流水线源。开启下载流水线源后,配置流水线源的源文件将会被下载至对应的工作目录下。 本示例选择下载全部流水线源

任务步骤

Kubectl镜像升级会自动添加。

步骤名称

输入自定义的步骤名称。本示例为Kubectl镜像升级。

集群链接

用来授权云效修改ACK集群中workload配置。按照授权添加对应ACK集群连接。

Kubectl版本

选择相近版本。本示例选择v1.22.9

命名空间

按照实际情况选择。本示例为default。

Workloads类型

选择你要升级的Workloads(工作负载)类型。本示例选择Deployment

Workloads名称

选择你要升级的Workloads(工作负载)名称。本示例为spring-cloud-a-gray。

容器名称

Kubernetes中一个Pod可能包含多个容器,因此需要指定升级的容器名称。本示例为spring-cloud-a-gray。

镜像

选择上一步构建的结果,可以选择镜像公网地址。本示例选择镜像构建并推送至阿里云镜像仓库个人版.镜像公网地址

发布超时时长

按照实际情况选择,本示例选择十分钟

跳过TLS校验

当自定义证书中声明insecure-skip-tls-verify为true时需要勾选该配置,以确保Kubectl跳过校验。

步骤四:部署线上阶段配置

部署线上阶段配置项与部署gray阶段类似。

  1. 流程配置页面的新阶段区域,单击新的任务

  2. 选择任务组页面的左侧导航栏,单击部署,再单击Kubernetes 镜像升级,配置任务名称构建集群等信息。

1

配置项

描述

Workloads名称

与上一步不同,这里代表基线环境的Workloads,本示例为spring-cloud-a

容器名称

本示例为spring-cloud-a。

部署gray阶段和部署线上阶段的触发模式改为手动触发

1

配置好后的效果如下图所示:

1

流水线运行

配置好流水线后,按照发布流程运行流水线:

1

步骤一:打包构建

手动运行刚刚的创建好的流水线,观察构建状态。

1

运行成功效果如下:

1

您也可以通过查看日志确定运行状态、排查问题等。

11

步骤二:部署gray并验证

  1. 单击部署gray阶段的等待手动触发

    1
  2. 在Kubernetes控制台确认部署后容器镜像是否符合预期。

    1. 登录容器服务管理控制台。在左侧导航栏,单击目标集群名称或者目标集群右侧操作列下的详情

    2. 在集群管理页左侧导航栏中,选择工作负载 > 无状态

    3. 单击目标应用名称或者目标应用右侧操作列的详情

      如下图所示,可以看到对应镜像已经部署到gray。

      1

可以尝试用小流量进行验证,按照之前在MSE全链路灰度上的配置,访问只需带上参数name=xiaoming即可访问到gray节点:

1

此时请求到达Agray节点,同时新的代码也生效。

此时观察线上的流量:

1

没有带灰度参数的流量走基线环境,新版本的修改也未生效。

在验证完gray环境后,就可以开始发布线上。如果此时验证不通过,可以中止流水线运行,排查问题后重新运行流水线。

步骤三:部署线上

  1. 单击部署线上阶段的等待手动触发

    1
  2. 线上部署成功后,查看是否符合预期。

    1. 登录容器服务管理控制台。在左侧导航栏,单击目标集群名称或者目标集群右侧操作列下的详情

    2. 在集群管理页左侧导航栏中,选择工作负载 > 无状态

    3. 单击目标应用名称或者目标应用右侧操作列下的详情

      1

观察线上流量,看下修改是否生效:

1

此时,修改后的新版本已成功发布到线上。

阿里云首页 微服务引擎 相关技术圈