使用 Spinnaker 在 Google Kubernetes Engine 上执行自动化 Canary 分析

本教程将指导您在 Google Kubernetes Engine (GKE) 上配置 Spinnaker 的自动化 Canary 分析功能。

简介

Spinnaker 是一个由 Netflix 和 Google 领导开发的开源持续交付系统,用于管理不同计算平台上的应用部署,包括 App Engine、GKE、Compute Engine、AWS 和 Azure。使用 Spinnaker,您可以实现各种高级部署方法,包括 Canary 部署。

在 Canary 部署中,您可以在全面部署一个应用新版本之前,将其公开给一小部分生产流量并分析应用的行为。这样可以在将新版本部署到所有用户之前降低风险。如需使用 Canary 部署,您必须准确地对比应用的旧版本和新版本的行为。差异可能并不明显,并且可能需要一些时间才会显现。此外,您可能还需要检查许多不同的指标。

为了解决这些问题,您可以使用 Spinnaker 的自动化 Canary 分析功能。此功能从您的监控系统读取新旧两个版本的指标,并运行统计信息分析进行自动对比。本教程将向您展示如何针对部署于 GKE 上并由 Stackdriver 监控的应用执行自动化 Canary 分析。

Spinnaker 是一个高级应用部署和管理平台,适用于具有复杂部署场景的组织,这些组织通常拥有专门的发布工程职能团队。虽然您可以在没有 Spinnaker 经验的情况下运行本教程,但通常情况下,在生产环境中实现自动化 Canary 分析是由拥有 Spinnaker 经验、强大的监控系统以及知道如何确定版本是否安全的团队完成的。

关于本教程

本教程中的应用是一个简单的“Hello World”应用,其错误率使用了环境变量进行配置。本教程为此应用提供了预构的 Docker 映像。如下图所示,此应用公开了 Prometheus 格式的指标。Prometheus 是一种 Kubernetes 社区常用的开源监控系统,与 Stackdriver 兼容。

应用架构

目标

  • 创建 GKE 集群。
  • 安装 Spinnaker。
  • 在没有 Canary 部署的情况下将应用部署到 GKE。
  • 配置并运行应用的 Canary 部署。
  • 配置自动化 Canary 分析。
  • 测试自动化 Canary 分析。

费用

准备工作

  1. 选择或创建 GCP 项目。

    转到“管理资源”页面

  2. 为您的项目启用结算功能。

    启用结算功能

  3. 创建一个 Stackdriver 帐号。

    转到 Stackdriver 文档

完成本教程后,您可以通过删除自己创建的资源来避免继续计费。如需了解详情,请参阅清理

设置您的环境

在本部分中,您将配置完成本教程所需的基础架构。请从 Cloud Shell 运行本教程中的所有终端命令。

  1. 打开 Cloud Shell。

    转到 Cloud Shell

  2. 导出项目 ID 作为变量。

    export GOOGLE_CLOUD_PROJECT=[PROJECT_ID]
    

    其中:

    • [PROJECT_ID] 表示您正在使用的项目的 ID。
  3. 创建 GKE 集群。

    gcloud config set project $GOOGLE_CLOUD_PROJECT
    gcloud config set compute/zone us-central1-f
    gcloud services enable container.googleapis.com
    gcloud beta container clusters create kayenta-tutorial \
        --machine-type=n1-standard-2 --enable-stackdriver-kubernetes
    
  4. 安装 Stackdriver-Prometheus 集成插件

    kubectl apply --as=admin --as-group=system:masters -f \
        https://storage.googleapis.com/stackdriver-prometheus-documentation/rbac-setup.yml
    curl -sS "https://storage.googleapis.com/stackdriver-prometheus-documentation/prometheus-service.yml" | \
        sed "s/_stackdriver_project_id:.*/_stackdriver_project_id: $GOOGLE_CLOUD_PROJECT/" | \
        sed "s/_kubernetes_cluster_name:.*/_kubernetes_cluster_name: kayenta-tutorial/" | \
        sed "s/_kubernetes_location:.*/_kubernetes_location: us-central1-f/" | \
        kubectl apply -f -
    
  5. 在新的 GKE 集群中部署 Spinnaker。

    curl -sSL "https://www.spinnaker.io/downloads/kubernetes/quick-install.yml" | \
        sed 's/version:.*/version: 1.13.10/g' | kubectl apply -f -
    
  6. 部署需要几分钟才能完成。如需检查进度,请运行命令 watch kubectl -n spinnaker get pods。如需停止 watch 命令,请按 Ctrl+C。部署完成后,此命令会将所有 pod 输出为 Ready 1/1

    NAME                                READY  STATUS    RESTARTS   AGE
    minio-deployment-7c665c4b57-jx7px   1/1    Running   0          5m
    spin-clouddriver-789c6fff77-rjtc6   1/1    Running   0          4m
    spin-deck-68b5968f7f-trmkn          1/1    Running   0          4m
    spin-echo-57dbff9fb8-rq5qc          1/1    Running   0          4m
    spin-front50-67965475b8-l24db       1/1    Running   0          4m
    spin-gate-6d8bbf8c45-m9pzn          1/1    Running   0          4m
    spin-halyard-59fd54bd69-xns49       1/1    Running   0          5m
    spin-kayenta-99b97b85f-4gvsv        1/1    Running   0          4m
    spin-orca-5748974888-cph9g          1/1    Running   0          4m
    spin-redis-6d49c9c5b9-q2hzm         1/1    Running   0          4m
    spin-rosco-6b4ddbcb94-mjrht         1/1    Running   0          4m
    
  7. 如需访问 Spinnaker,请将一个本地端口转址到 Spinnaker 的 deck 组件。

    DECK_POD=$(kubectl -n spinnaker get pods -l \
        cluster=spin-deck,app=spin \
        -o=jsonpath='{.items[0].metadata.name}')
    kubectl -n spinnaker port-forward $DECK_POD 8080:9000 >/dev/null &
    
  8. 在 Cloud Shell 中,点击网页预览图标,然后选择在端口 8080 上预览

    端口 8080 的网页预览图标。

使用 Spinnaker 部署应用

在本部分中,您将配置 Spinnaker 以在 GKE 集群中部署应用。

创建 Spinnaker 应用

部署之前,请创建 Spinnaker 应用。

  1. 在 Spinnaker 中,点击 Actions > Create Application

    创建应用下拉菜单

  2. New Application 对话框中,输入以下值:

    • Namesampleapp
    • Owner Email[example@example.com]

  3. 点击 Create

您现在位于 Spinnaker 的 sampleapp 中。它尚未配置,因此大多数标签页都是空的。

创建并运行部署流水线

在本部分中,您首先使用简单的 Spinnaker 流水线部署应用,该流水线会使用 successRate 参数创建具有四个 pod 的 GKE 部署。这些 pod 以与 successRate 参数对应的速率随机抛出错误。在本教程中,它们以 100 - successRate 的速率抛出 500 个错误。

  1. 在 Cloud Shell 中,使用提供的 JSON 文件创建流水线。以下命令将流水线的 JSON 定义直接发布到 Spinnaker API。

    wget https://raw.githubusercontent.com/spinnaker/spinnaker/master/solutions/kayenta/pipelines/simple-deploy.json
    curl -d@simple-deploy.json -X POST \
        -H "Content-Type: application/json" -H "Accept: */*" \
        http://localhost:8080/gate/pipelines
    
  2. 在 Spinnaker 的“流水线”部分中,会出现一个名为“Simple deploy”的流水线。如果您没有看到此流水线,请重新加载页面。点击开始手动执行

    开始手动执行 Simple deploy 流水线

  3. 确认执行窗口中,将成功率选为 70,然后点击运行。几秒钟后,流水线会成功部署应用和四个 pod 的配置。

  4. 在 Cloud Shell 中,创建一个在教程结束前向新应用发出请求的 pod。

    kubectl -n default run injector --image=alpine:3.10 -- \
        /bin/sh -c "apk add --no-cache curl; \
        while true; do curl -sS --max-time 3 \
        http://sampleapp:8080/; done"
    

检查注入器日志

  1. 如需查看应用的行为,请检查注入器日志。

    kubectl -n default logs -f \
        $(kubectl -n default get pods -l run=injector \
        -o=jsonpath='{.items[0].metadata.name}')
    
  2. 日志中会显示大量内部服务器错误消息。如需停止关注注入器日志,请按 Ctrl+C

检查应用的运行状况

在您的应用已部署并服务流量后,请查看它是否正常运行。当然,在本教程中,您已经知道它不会正常运行,因为您部署应用时设置的成功率仅为 70%。

该应用公开一个 /metrics 端点,其中包含 Prometheus 格式的指标,这些指标由 Stackdriver 提取。在本部分中,您可以在 Stackdriver 中可视化这些指标。

  1. 在 Stackdriver 中,转到 Metrics Explorer

    METRICS EXPLORER

  2. Find resource type and metric 字段中,输入以下内容:

    external.googleapis.com/prometheus/requests
    
  3. 如需优化图表,请在 Group By 字段中输入 http_code。在下图中,应用应答的 HTTP 请求率按 HTTP 状态代码分组:

    应用响应的 HTTP 请求图表

如图表所示,应用目前具有不可接受的错误率(约 30%),这与预期相同。本教程的其余部分将指导您完成 Canary 部署流水线的设置和自动化分析,以防止将来部署具有如此高错误率的应用。

创建 Canary 部署

在本部分中,您将创建一个不含自动化分析的 Canary 部署流水线,从而在将应用完全部署到生产环境之前测试该应用的新版本。下图展示了此流水线的不同阶段:

Canary 部署流水线的阶段图示

  • 步骤 0:与“Simple Deploy”流水线一样,此流水线将“Success Rate”参数作为输入。这个新流水线使用此参数来模拟不同的成功率。这是此流水线的配置
  • 步骤 1:“Find Baseline Version”阶段从最新执行的“Simple Deploy”流水线中检索生产环境中运行的应用的当前版本。在本教程中,它将检索当前部署的应用的成功率。
  • 在“Find Baseline Version”阶段的同时,“Deploy Canary Config”阶段为应用的 Canary 版本部署新的成功率配置
  • 步骤 2:“Deploy Canary”和“Deploy Baseline”阶段会部署新的 Canary 版本和基准版本以进行对比。Canary 版本使用“Deploy Canary Config”阶段创建的配置,而基准版本使用生产版本使用的配置

  • 步骤 3:“Manual Judgement”阶段将停止流水线,直到您选择继续。在此阶段,您可以检查 Canary 版本是否正常运行。

  • 步骤 4:当完成“Manual Judgement”阶段并选择继续时,“Delete Canary”和“Delete Baseline”阶段均会清理基础架构。

  • 在清理的同时,“Deploy to Production”阶段将会启动并使用您最初提供的“Success Rate”参数触发“Simple Deploy”流水线。您在 Canary 中测试的应用的同一版本将部署到生产环境中。

  • 只有在“Manual Judgement”阶段选择“continue”,才会触发“Deploy to Production”阶段。

  • 步骤 5:最后,“Successful Deployment”阶段将验证整个流水线是否成功。它会检查您是否在“Manual Judgement”阶段中选择了继续,并且仅在“Deploy to Production”、“Delete Canary”和“Delete Baseline”阶段均成功执行时才会执行

现在,您可以创建并运行“Canary Deploy”流水线。

  1. 如需创建“Canary Deploy”流水线,请运行以下命令以获取“Simple deploy”流水线的 ID 并将其注入“Canary Deploy”流水线:

    wget https://raw.githubusercontent.com/spinnaker/spinnaker/master/solutions/kayenta/pipelines/canary-deploy.json
    export PIPELINE_ID=$(curl \
        localhost:8080/gate/applications/sampleapp/pipelineConfigs/Simple%20deploy \
        | jq -r '.id')
    jq '(.stages[] | select(.refId == "9") | .pipeline) |= env.PIPELINE_ID | (.stages[] | select(.refId == "8") | .pipeline) |= env.PIPELINE_ID' canary-deploy.json | \
        curl -d@- -X POST \
        -H "Content-Type: application/json" -H "Accept: */*" \
        http://localhost:8080/gate/pipelines
    
  2. 如果在 Spinnaker 中没有看到“Canary Deploy”流水线,请重新加载 sampleapp 页面,然后点击 Pipelines

  3. 如需启动“Canary Deploy”流水线,请执行以下操作:

    1. 点击 Start Manual Execution
    2. Success Rate 选为 80
    3. 点击 Run
  4. 当流水线到达 Manual Judgement 阶段时,先不要点击 Continue,因为您需要将 Canary 版本与基准版本进行对比。

    Canary 流水线的 Manual Judgement 阶段

  5. 在 Cloud Shell 中,运行 kubectl -n default get pods 命令以查看标记为 Canary 和基准的新 pod:

    NAME                                READY STATUS  RESTARTS  AGE
    injector-66bd655ffd-9ntwx           1/1   Running 0         30m
    sampleapp-5cdf8f55dd-995rz          1/1   Running 0         28m
    sampleapp-5cdf8f55dd-dqq8n          1/1   Running 0         28m
    sampleapp-5cdf8f55dd-ntq57          1/1   Running 0         28m
    sampleapp-5cdf8f55dd-rlpzp          1/1   Running 0         28m
    sampleapp-baseline-567b8d6849-gsgqr 1/1   Running 0          4m
    sampleapp-canary-54b9759dd6-gmjhc   1/1   Running 0          4m
    
  6. 在 Stackdriver 中,转到 Metrics Explorer

    METRICS EXPLORER

  7. 如果 Metrics Explorer 中已配置有任何指标,请从表单中移除所有现有配置。

  8. 显示基准和 Canary 的错误率,并指定以下参数:

    1. Metricexternal.googleapis.com/prometheus/requests
    2. Filters

      • http_code500
      • version 不同于 (!=) prod
  9. 比较 Canary 版本(下图中的紫色部分)与基准版本(下图中的蓝色部分)。请注意,您的图表中的颜色可能有所不同。在本教程中,Canary 版本的错误率低于基准版本。因此,将 Canary 版本完全部署到生产环境中是安全的。如果 Canary 版本没有更低的错误率,您可能希望在此阶段停止部署并对应用进行一些更正。

    Canary 版本与基准版本的错误率对比图表

  10. 在 Spinnaker 的 Manual Judgement 对话框中,点击 Continue

    Canary 流水线的 Manual Judgement 阶段

  11. 部署完成后,在 Stackdriver 中返回 Metrics Explorer

    METRICS EXPLORER

  12. 如果 Metrics Explorer 中已配置有任何指标,请从表单中移除所有现有配置。

  13. 查找资源类型和指标字段中,输入以下内容:

    external.googleapis.com/prometheus/requests
    
  14. Group By 字段中,输入 http_code。在下图中,应用的 HTTP 请求响应率按 HTTP 状态代码划分:

    HTTP 请求率对比图表

    此图显示所有 pod 的 HTTP 代码 200 和 500 的代码率,包括生产、基准和 Canary。由于 Canary 版本的错误率较低,因此您将其部署于生产环境中。在部署期间的一小段时间后,请求总数略微降低,您可以看到整体错误率也在降低,这意味着 Canary 版本已正确部署于生产环境中。

自动化 Canary 分析

Canary 部署很有用,但在目前的实现中,它是一个手动流程。在进行全面部署之前,您必须手动检查 Canary 是否符合您的要求,并且 Canary 版本和基准版本之间的差异并不总是那么明显。

自动化 Canary 分析是一个好办法。如此一来,您不必自己动手,并且自动化统计信息分析比人类更适合检测一组指标中的问题。在本部分中,“Manual Judgement”阶段由自动化 Canary 分析代替。

启用 Canary 支持

首先,在 Spinnaker 中,您可以配置名为 Kayenta 的自动化 Canary 分析功能。如需配置 Kayenta,请使用 Halyard,这是配置和部署 Spinnaker 的同一工具。

  1. 在 Cloud Shell 中,获取您的项目 ID。

    echo $GOOGLE_CLOUD_PROJECT
    
  2. 在 Halyard pod 中获取一个 shell。

    export HALYARD_POD=$(kubectl -n spinnaker get pods -l \
        stack=halyard,app=spin \
        -o=jsonpath='{.items[0].metadata.name}')
    kubectl -n spinnaker exec -it $HALYARD_POD -- bash
    
  3. 配置 Kayenta 将 Stackdriver 用作后端。

    hal config canary google enable
    hal config canary google account add kayenta-tutorial --project [PROJECT_ID]
    hal config canary google edit --stackdriver-enabled=true
    

    其中:

    • [PROJECT_ID] 表示您检索的项目 ID。
  4. 应用新配置并退出 Halyard pod。

    hal deploy apply
    exit
    
  5. 部署需要几分钟才能完成。如需检查进度,请运行命令 watch kubectl -n spinnaker get pods。部署完成后,此命令将所有 pod 输出为 Ready 1/1。如需停止 watch 命令,请按 Ctrl+C

    NAME                               READY  STATUS   RESTARTS AGE
    minio-deployment-7c665c4b57-prl6d  1/1    Running  0        1h
    spin-clouddriver-6c4f954667-8769c  1/1    Running  0        1h
    spin-deck-7d44499f9b-hkqz4         1/1    Running  0        1h
    spin-echo-6cf4bbbbfc-vxzlr         1/1    Running  0        1h
    spin-front50-7666c894c6-fm7sz      1/1    Running  0        1h
    spin-gate-76f789696d-vsn98         1/1    Running  0        1h
    spin-halyard-59fd54bd69-vb99h      1/1    Running  0        1h
    spin-kayenta-84f6b9b697-5krhh      1/1    Running  0        1m
    spin-orca-78f5c74c6f-srl4f         1/1    Running  0        1h
    spin-redis-6d49c9c5b9-gddgv        1/1    Running  0        1h
    spin-rosco-699cb484f7-grthh        1/1    Running  0        1h
    

配置自动化 Canary 分析功能

现在,Kayenta 已启用,请为 sampleapp 配置 Kayenta。

  1. 在 Spinnaker 中,点击配置

  2. 功能部分中,勾选 Canary,然后点击保存更改

    流水线功能的屏幕截图

创建 Canary 配置

在 Spinnaker 中,自动化 Canary 分析针对不同指标运行统计信息测试并输出得分。此得分的范围为 0 到 100,表示通过或未通过基准和 Canary 之间的对比的指标数。您可以通过将指标分为不同的分组,并为每个组分配不同的权重,从而影响得分。根据分析的得分,您可以决定继续部署或停止部署。如果您像本教程中所示一样使用单个指标,则得分只能为 0(未通过)或 100(通过)。

一个应用可以有多个 Canary 配置,并在多个应用之间共享。Canary 配置有两个主要元素:

  • 需要分析的一组指标(可能在不同的组中)。
  • 得分的边界和通过阈值。

在部署流水线中,Canary 配置用于“Canary Analysis”阶段。这个阶段可以包括多次 Canary 运行。如果任意一次运行的得分低于边界阈值,则停止该阶段并且不执行其他运行。最后一次运行的得分需要高于整个阶段的通过阈值才能被视为成功通过。

如需创建 Canary 配置,请按照下列步骤操作:

  1. 现在 Canary 已启用,Pipelines 部分将替换为 Delivery。如果您没有看到 Delivery 部分,请重新加载 Spinnaker。在 Delivery 部分中,转到 Canary Configs

  2. 点击 Add Configuration

  3. Configuration Name 中输入 kayenta-test

  4. Metrics 部分中,点击 Add Metric

  5. Add Metric 对话框中,输入以下值,然后点击 OK

    • Nameerror_rate
    • Fail onincrease
    • Resource Typek8s_container
    • Metric typeexternal.googleapis.com/prometheus/requests
    • AlignerALIGN_RATE
    • Filter Template:选择 Choose Create new...
      • 对于新过滤器模板的 Name,请输入 http_code
      • 对于新过滤器模板的 Template,请输入 metric.labels.http_code = "500" AND resource.label.pod_name = starts_with("${scope}")
      • 点击 Save
  6. 得分部分中,选择以下值:

    • 边界75
    • 通过95
    • 第 1 组100
  7. 点击保存更改

将 Canary 分析阶段添加到流水线中

现在您已经拥有了 Canary 配置,接下来您可以修改现有的部署流水线,用一个使用此配置的“Canary Analysis”阶段替换“Manual Judgement”阶段。

  1. 转到 Delivery > Pipelines,然后对于 Canary Deploy 流水线,点击 Configure

    Canary 部署的配置按钮的屏幕截图

  2. 点击添加阶段

  3. 类型中,选择 Canary Analysis

  4. 决定条件部分中,修改新阶段以使其取决于以下选择:

    • 部署 Canary 版本
    • 部署基准版本
  5. 使用以下值填写 Canary 分析配置部分:

    参数名称 定义
    分析类型 实时(手动) 为您创建了 Canary 和基准的自动模式尚不可用于 Kubernetes。
    配置名称 kayenta-test 您之前创建的 Canary 配置的名称。
    生命周期 0 小时 5 分钟 Canary 分析应持续的时长。
    延迟 0 在进行分析之前为应用设置的预热时间。
    间隔 5 Kayenta 应使用以进行单个统计信息分析的时间窗口。
    基准 sampleapp-baseline Kayenta 应用作基准的 GKE 部署。
    基准位置 默认 基准所在的 GKE 命名空间。
    Canary sampleapp-canary Kayenta 应用作 Canary 的 GKE 部署。
    Canary 位置 默认 Canary 所在的 GKE 命名空间。
  6. 执行选项部分中,选择忽略失败。选择忽略失败,是为了即使 Canary 分析失败,您也可以销毁基准版本和 Canary 版本。在本教程的后半部分,您将修改该阶段,以将潜在的 Canary 失败考虑在内。

  7. 在流水线架构中,点击部署到生产环境

    流水线的“部署到生产环境”按钮的屏幕截图

  8. 决定条件部分更改为以下参数:

    1. 添加 Canary Analysis
    2. 移除 Manual Judgement
  9. 如需确保仅在 Canary 分析成功时部署到生产环境,请更改条件表达式参数。

    ${ #stage('Canary Analysis')['status'].toString() == 'SUCCEEDED'}
    
  10. 在流水线架构中,点击删除 Canary,然后将决定条件部分更改为以下参数:

    1. 添加 Canary Analysis
    2. 移除 Manual Judgement
  11. 在流水线架构中,点击删除基准,然后更改决定条件部分:

    1. 添加 Canary Analysis
    2. 移除 Manual Judgement
  12. 如果需要在 Canary 分析失败时确保整个流水线失败,请在流水线架构中点击成功部署,然后在现有前提条件下点击修改图标。

    修改成功部署的现有前提条件

    1. 表达式更改为以下内容:

      ${ #stage('Canary Analysis')['status'].toString() == 'SUCCEEDED'}
      
    2. 点击更新

  13. 完成使用新创建的“Canary Analysis”阶段替换“Manual Judgement”阶段的操作

    1. 在流水线架构中,点击 Manual Judgement
    2. 点击移除阶段
  14. 点击保存更改。您的流水线现在如下图所示:可视化 Canary 分析流水线

测试新流水线

现在,自动化 Canary 分析已完成配置,接下来您可以测试该流水线以确保其行为符合预期。

  1. 转到 Delivery > Pipelines,然后对于 Canary Deploy 流水线或 Automated Canary Deploy(如果使用 CLI),点击 Start Manual Execution

  2. Success Rate 选为 60,然后点击 Run

  3. 如需检查 Canary 分析的当前进度,请点击 Canary Analysis,然后点击任务状态。几分钟后,Canary Analysis 阶段失败,因为当前生产环境中的成功率为 80。当 Canary Analysis 阶段失败时,请转至此 Canary 分析的报告。

    1. 点击 Canary Analysis
    2. 点击 Canary Summary
    3. 点击报告图标。在报告页面上,会发现 Canary 版本的错误率高于基准版本的错误率。

      Canary 分析摘要的报告图标

  4. 重复本部分中的步骤,将成功率选为 90 以实现成功的 Canary 分析。

清理

为避免系统因本教程中使用的资源向您的 Google Cloud Platform 帐号收取费用,请执行以下操作:

  1. 在 GCP Console 中,转到“项目”页面。

    转到“项目”页面

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除资源

如果希望保留在本教程中使用的 GCP 项目,请删除各个资源:

  1. 卸载 Spinnaker。

    kubectl delete -f https://www.spinnaker.io/downloads/kubernetes/quick-install.yml
    
  2. 删除 GKE 集群。

    gcloud container clusters delete kayenta-tutorial
    
  3. 当系统提示确认时,键入 Y

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Solutions