ASM 蓝绿发布

更新时间:
复制 MD 格式

阿里云服务网格(简称 ASM)企业版实例中,兼容 Istio,支持多个 Kubernetes 集群统一流量管理,为容器和虚拟机应用服务提供一致性的通信控制。基于服务网格最新的“数据面 KubeAPI 访问"能力,能够通过数据面集群的 kubeconfig 来管理 Istio 资源。和云效 Flow 集成后,可以享受 DevOps、GitOps带 来的应用发布的便利性,还能够利用 Istio 细粒度的流量管控能力来实现蓝绿发布,保障上线的稳定性。

前提条件

  • 创建 Istio 版本为 1.12.4.50 或更高版本的阿里云服务网格 (ASM) 实例。

  • 创建容器服务 Kubernetes (ACK) 集群。

  • 将 ACK 集群添加到 ASM 实例。

  • Service/VirtualService/DestinationRule 同名。

  • Deployment 的 labels 内包含有 Service 的全部 selector labels。

  • ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: spring-boot-sample
      name: spring-boot-sample
    spec:
      replicas: 2
      selector:
        matchLabels:
          run: spring-boot-sample
      template:
        metadata:
          labels:
            run: spring-boot-sample
        spec:
          containers:
          - image: ${IMAGE}
            name: app
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: spring-boot-service
      labels:
        test: test
        labele2: label
    spec:
      ports:
        - name: http
          port: 8080
          protocol: TCP
          targetPort: 8080
        - name: https
          port: 443
          protocol: TCP
          targetPort: 443
      selector:
        run: spring-boot-sample
      sessionAffinity: None
      type: ClusterIP

实践1:流水线部署应用

目标:以 Istio book-info 为例,我们将首页的标题文字进行更换。代码提交后,执行阿里云云效流水线,生成镜像,自动将应用的流量管理(VirtualService、Gateway、DestinationRule)相关的资源创建或更新到阿里云服务网格 ASM 集群中,将应用程序编排(Deployment、Service)创建或更新到阿里云容器服务平台 ACK 集群中。

创建流水线如下。流水线源配置为 GitHub 仓库,测试地址为https://github.com/AliyunContainerService/asm-labs,您也可以 fork 出来,然后进行个性化修改。分支选择 flow-demo

执行的步骤如下:流水线命名为 ASM-Flow-v1,在流程配置 Tab 中依次设置四个阶段:流水线源阶段对接 GitHub 仓库,测试阶段添加代码扫描任务,构建阶段添加Python 构建任务,部署阶段添加Kubernetes 发布任务。

  1. 流水线流程配置

将镜像仓库地址为替换为您的地址空间:registry.cn-hangzhou.aliyuncs.com/{your_name_space}/productpage:${DATETIME}。这里我们使用 DATETIME 作为版本号。Dockerfile 路径为 productpage/Dockerfile。在 Kubernetes 发布的 Kubectl 发布中,设置变量 ProductpageImage 为前面配置的镜像仓库地址,在代码仓库的 YAML 文件中,productpage 的镜像被设置为了 ${ProductpageImage} 与其对应。流水线包含三个任务:第一个任务代码扫描,添加Python 代码扫描步骤,Python 版本选择 3.7,排除子目录填写 test/。第二个任务Python 构建,添加镜像构建并推送至自定义镜像仓库步骤,镜像仓库地址填写 registry.cn-hangzhou.aliyuncs.com/xxx/productpage,凭据类型选择服务连接,Dockerfile 路径填写 productpage/Dockerfile。第三个任务Kubectl 发布,集群连接选择 flow-cs,Kubectl 版本选择 v1.16.4,命名空间填写 default,YAML 路径填写 manifests,并设置变量 Productpage 的值为 registry.cn-hangzhou.aliyuncs.com/xxx/productpage:${DATETIME}

  1. 添加数据面集群并注入 Sidecar 代理

在阿里云服务网格 ASM 控制台,进入 ASM 实例后,在集群与工作负载管理中,添加希望流水线配置的 ACK 容器服务实例。并在全局命名空间中,为选定的命名空间(如 default)启用 Sidecar 自动注入。在 ASM 控制台的网格实例中,进入Kubernetes集群页面,确认数据面集群(如 flow-demo)已添加且状态为运行中。然后进入全局命名空间页面,单击Kubernetes集群同步自动注入,同步成功后确认 default 命名空间的标签中包含 istio-injection:enabled,表示 Sidecar 自动注入已启用。

  1. 创建ASM网关

为了方便的访问我们流水线部署出的应用程序,需要创建 ASM 网关来作为访问入口,端口设置为 80。在左侧导航栏单击ASM网关,单击创建。在基本信息区域,设置名称ingressgateway命名空间istio-system,选择部署集群,网关类型选择南北向-入口负载均衡类型选择公网访问新建负载均衡规格选择简约型I (slb.s1.small)。在端口映射中添加 HTTP 协议对应服务端口 80 和 HTTPS 协议对应服务端口 443。

  1. 执行流水线

执行流水线后,测试(代码扫描)、构建(Python 构建)和Kubernetes 发布三个阶段均运行成功。其中代码扫描发现 4 个严重问题(0 阻塞、0 一般),可单击扫描报告查看详情。

  1. 查看部署效果

在 ACK 集群中,确认镜像能够成功拉去并且启动正常,如拉取个人私有镜像失败可参考使用免密组件拉取容器镜像

在 ACK 控制台选择 flow-demo 集群,将命名空间切换为 default,进入工作负载 > 无状态页面,可看到 Bookinfo 示例的 6 个 Deployment(details-v1、productpage-v1、ratings-v1、reviews-v1、reviews-v2、reviews-v3)均显示容器组数量为 1/1,表明部署成功。在左侧导航栏单击ASM网关,可看到名为 ingressgateway 的网关已创建成功,命名空间为 istio-system。记录 Kubernetes服务 列中的 IP 地址用于后续访问应用,端口映射包含 HTTP 80:80 和 HTTPS 443:443。复制前面创建的 ASM 网关的地址,在浏览器中输入 http://{ASM网关地址}/productpage,可以看到我们修改的标题已生效。

当前显示界面固定为 reviews-v1 版本。

实践2:蓝绿发布

阿里云服务网格 ASM 和云效集成,提供了蓝绿发布的能力。从而让用户可以更安全的基于 Istio 的流量管理策略实现应用的安全发布。

目标:在完成“实践1:流水线部署应用”的前提下,通过蓝绿发布,将 reviews 版本从原来的 v1 更新为 v2 版本。

  1. 创建新的流水线

如实践 1 配置流水线源,创建阶段 ASM 蓝绿发布。这里我们设置镜像为 reviews-v2 版本的镜像:docker.io/istio/examples-bookinfo-reviews-v2:1.16.4。灰度初始化流量为 0%,并且只有带特定 cookie 标识的用户能够访问到蓝绿版本。

ASM 蓝绿发布任务编辑面板中,选择Kubernetes集群连接ASM集群连接,设置Kubectl版本v1.16.4命名空间default容器名称reviews灰度流量Cookie^(.*?;)?(gray=true)(;.*)?$

  1. 执行

在阿里云云效 Flow 中,蓝绿发布前需要明确指明使用哪个版本的工作负载,将其他的版本的工作负载全部清空,确保流量只流入稳定版(reviews-v1)。

解决冲突页面中,单击 reviews-v1 对应的接管流量,在弹出的确认对话框中单击确定。流水线进入冲突解决阶段,日志显示已删除 deployment/reviews-v2deployment/reviews-v3,右侧状态卡片显示版本 v20220622103841 处于灰度验证中,可选择继续发布回退发布

此时,在阿里云服务网格ASM控制台查看虚拟服务 VIrtualService 状态。此时状态如下:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews
  namespace: default
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            cookie:
              regex: ^(.*?;)?(gray=true)(;.*)?$
      route:
        - destination:
            host: reviews
            subset: v20220622103841
    - route:
        - destination:
            host: reviews
            subset: v1
          weight: 100
        - destination:
            host: reviews
            subset: v20220622103841

目标规则如下所示:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews
  namespace: default
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v20220622103841
      name: v20220622103841
  1. 测试验证

因为 reviews 服务是由后端服务 productpage 来调用的,不方便携带特定 token 来进行灰度测试。

修改 header 中 cookie 设置,改为使用 end-user 的登录信息,设定只要登录用户名称为 asm,则显示灰度版本。

修改后的 reviews VirtualService 状态如下。其中 headers 匹配条件已从 cookie 改为 end-user,当登录用户名称为 asm 时路由到灰度版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
    creationTimestamp: '2022-06-20T08:19:10Z'
    generation: 9
    name: reviews
    namespace: default
    resourceVersion: '3403073'
    uid: b8b5cd0b-9b6e-4853-a5ae-2642d4ff5c84
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            end-user:
              exact: asm
      route:
        - destination:
            host: reviews
            subset: v20220620xxx1
    - route:
        - destination:
            host: reviews
            subset: v1
          weight: 100
        - destination:
            host: reviews
            subset: v20220620xxx1

复制前面创建的 ASM 网关的地址,在浏览器中输入 http://{ASM网关地址}/productpage,点击右上角进行登录,输入用户名称为 asm,密码任意输入。如果是未登录状态,则显示 v1 版本的 reviews 信息。

登录用户名称为 asm 后,页面 Book Reviews 区域显示带有星级评分的评论信息(Reviewer1 为 5 星、Reviewer2 为 4 星),说明当前命中了灰度版本 reviews-v2。

  1. 继续发布

在通过了灰度版本的测试之后,将全部的流量转为新版本(reviews-v2)。点击继续发布,完成发布。

发布完成后,未登录时也显示 reviews-v2 的版本。

发布完成后,查看 reviews VirtualService 的状态。

此时 VirtualService 的路由规则已将全部流量(weight: 100)指向新版本 subset reviews-v2,不再按请求头区分灰度流量。

总结

在 Kubernetes 中 Service 与多个版本的 Deployment 实例通过 Label 进行关联。蓝绿发布开始,阿里云 Flow 会基于当前的 Deployment 实例创建一个新版本的应用 Deployment 实例。等待蓝环境创建完成后通过更新 阿里云服务网格 ASM 的 VirtualService 和 DestinationRule 资源对象,进一步控制流量与特定版本 Deployment 实例之间的路由策略。

根据发布设置,可以修改 VirtualService 确定蓝/绿环境的流量权重。用户也可以设置灰度标,确定哪些流量会直接进入到蓝环境中。在人工验证完成后,完成发布将所有流量切流到蓝环境,并且将原有的绿环境实例移除。

作为业内首个全托管 Istio 兼容的阿里云服务网格产品 ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM 产品是基于社区 Istio 定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了 Istio 组件与所管理的 K8S 集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从 2022 年 4 月 1 日起,阿里云服务网格 ASM 正式推出商业化版本, 提供了更丰富的能力、更大的规模支持及更完善的技术保障,更好地满足客户的不同需求场景, 详情可见产品介绍:https://www.aliyun.com/product/servicemesh