如何在 DigitalOcean Kubernetes 上使用 Flagger 逐步发布版本

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

Kubernetes 可以监控集群的健康状况,并在必要时重新启动容器,但它不包括处理不良或错误的容器的策略。

Flagger是Kubernetes的渐进交付操作员,通过逐步将流量转移到新版本,同时监控配置的指标来解决所描述的问题。它可以对新版本进行自动分析和测试,决定是否将其传播到整个集群,或者如果发现问题,停止。

在本教程中,您将安装Flagger,并使用它为您的DigitalOcean Kubernetes群集设置 podinfo应用程序的渐进交付。 podinfo 是一个提供其运行环境的详细信息的Web应用程序。您将设置Flagger来监控其部署的资源,自动测试新版本,并使用Webhooks通知您Slack。

前提条件

在您开始本教程之前,您将需要:

  • DigitalOcean Kubernetes集群,第1.19版或更新版本,您的连接配置配置为kubectl默认值。 关于如何配置 kubectl 的指令, 将显示在您的集群** 步骤的 ** 下。 要学习如何在数字海洋上创建库伯内特斯集群,请参见 [Kubernetes Quickstart] (https://www.digitalocean.com/docs/kubernetes/quickstart/).
  • 在您本地机器上安装的 Helm 包管理器 。 要做到这一点,请使用 Helm 3 软件包管理器完成 [如何在 Kubernetes 集群上安装软件] (https://andsky.com/tech/tutorials/how-to-install-software-on-kubernetes-clusters-with-the-helm-3-package-manager) 教程中的 ** 第 1 段 ** 。
  • Nginx 入侵控制器和 Cert-Manager 安装在集群上. 关于如何做到这一点的指南,见[如何在使用Helm的数字海洋库伯内特斯上设置Nginx入侵 (https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-on-digitalocean-kubernetes-using-helm). *您所属的黑工作区。 为了学习如何创建工作空间,请访问[官方文件] (https://slack.com/help/articles/206845317-Create-a-Slack-workspace)。
  • 一个有DNS A记录的域名指向了入侵者所使用的数字海洋负载平衡器. 如果您正在使用 DigitalOcean 来管理您的域名的 DNS 记录,请查看[如何管理 DNS 记录 (https://www.digitalocean.com/docs/networking/dns/how-to/manage-records/) 创建 A 记录. 在这个教程中,我们将将A记录称为`app. your_domain'. <$ > [注] ** 注:** 您在此教程中使用的域名必须不同于 ** 如何在 DigitalOcean Kubernetes ** 上设置 Nginx 入侵的域名。 < $ >

步骤 1 — 安装 Flagger 并配置 Nginx Ingress 控制器

在本节中,您还将配置 Nginx Ingress 控制器以使其内部指标可用于其他应用程序,Flagger 将使用它来决定是否允许或拒绝新版本,这取决于它如何运作。

您首先需要通过运行添加包含 Flagger 的存储库到 Helm:

1helm repo add flagger https://flagger.app

结果将看起来像这样:

1[secondary_label Output]
2"flagger" has been added to your repositories

更新 Helm 以便让它知道它包含的内容:

1helm repo update

然后运行以下命令来安装 Flagger:

1helm install flagger flagger/flagger \
2--set prometheus.install=true \
3--set meshProvider=nginx

此命令会从您刚刚添加的图表存储库中安装Flagger,并命名Helm版本为flagger

输出将类似于以下,详细说明Flagger正在部署:

1[secondary_label Output]
2NAME: flagger
3LAST DEPLOYED: ...
4NAMESPACE: default
5STATUS: deployed
6REVISION: 1
7TEST SUITE: None
8NOTES:
9Flagger installed

要暴露 Nginx Ingress Controller 指标,您需要在其 Helm 发布中设置额外的变量,同时保持已定义的变量。

1helm upgrade nginx-ingress ingress-nginx/ingress-nginx \
2--reuse-values \
3--set controller.metrics.enabled=true \
4--set controller.podAnnotations."prometheus\.io/scrape"=true \
5--set controller.podAnnotations."prometheus\.io/port"=10254

此命令修改了nginx-ingress头盔释放,并允许Prometheus收集控制器及其插头上的指标。

结果将看起来像这样:

 1[secondary_label Output]
 2Release "nginx-ingress" has been upgraded. Happy Helming!
 3NAME: nginx-ingress
 4LAST DEPLOYED: ...
 5NAMESPACE: default
 6STATUS: deployed
 7REVISION: 2
 8TEST SUITE: None
 9NOTES:
10The ingress-nginx controller has been installed.
11...

请注意,修改号码现在是2,表示升级发生了。

在本节中,您已经安装了 Flagger 并配置了 Nginx Ingress 控制器,以揭示其内部指标。

步骤 2 – 部署应用程序

现在你将部署podinfo网络应用程序,并创建一个 _canary 资源,以控制其发布。 Canary 资源来自Flagger,并告诉它如何,何时,以及在应用或拒绝它之前测试新版本的时间。

podinfo应用程序将存储在名称空间中,称为test

1kubectl create ns test

然后,通过运行podinfo来部署:

1kubectl apply -k https://github.com/fluxcd/flagger//kustomize/podinfo?ref=main

此命令将从官方Flagger GitHub存储库中提取podinfo宣言,并将其应用到您的集群中。

kubectl将显示以下输出:

1[secondary_label Output]
2deployment.apps/podinfo created
3horizontalpodautoscaler.autoscaling/podinfo created

要验证它已部署,请运行以下命令:

1kubectl get pods -n test

你会看到类似于此的输出:

1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3podinfo-78fd6c49bf-jsjm5 1/1 Running 0 18s
4podinfo-78fd6c49bf-k2nh4 0/1 Running 0 3s

现在 pods 正在运行,你会创建一个 Ingress 来暴露应用程序在你的域. 打开一个名为 podinfo-ingress.yaml 的文件来编辑:

1nano podinfo-ingress.yaml

添加以下几行:

 1apiVersion: networking.k8s.io/v1
 2kind: Ingress
 3metadata:
 4  name: podinfo
 5  namespace: test
 6  labels:
 7    app: podinfo
 8spec:
 9  ingressClassName: nginx
10  rules:
11    - host: "app.your_domain"
12      http:
13        paths:
14          - pathType: Prefix
15            path: "/"
16            backend:
17              service:
18                name: podinfo
19                port:
20                  number: 80

这个 Ingress 暴露了 podinfo 服务在 app.your_domain 域. 请记住用自己的域代替它,然后保存并关闭文件。

请注意,podinfo服务尚未在您的集群中存在,它将由Flagger自动创建作为卡纳里的一部分,这不会阻止Ingress的部署。

在 Kubernetes 中创建 Ingress 通过运行以下命令:

1kubectl apply -f podinfo-ingress.yaml

在创建 Canary 之前,您需要部署 Flagger 的负载测试器,它允许 Canary 资源通过发送 HTTP 请求来测试版本。

1helm install flagger-loadtester flagger/loadtester -n test

头盔将显示以下输出:

1[secondary_label Output]
2NAME: flagger-loadtester
3LAST DEPLOYED: Thu Jan 6 11:37:45 2022
4NAMESPACE: test
5STATUS: deployed
6REVISION: 1
7TEST SUITE: None
8NOTES:
9Flagger's load testing service is available at http://flagger-loadtester.test/

您现在将定义卡纳里,并将其存储在名为podinfo-canary.yaml的文件中。

1nano podinfo-canary.yaml

添加以下几行:

 1apiVersion: flagger.app/v1beta1
 2kind: Canary
 3metadata:
 4  name: podinfo
 5  namespace: test
 6spec:
 7  provider: nginx
 8  targetRef:
 9    apiVersion: apps/v1
10    kind: Deployment
11    name: podinfo
12  ingressRef:
13    apiVersion: networking.k8s.io/v1
14    kind: Ingress
15    name: podinfo
16  progressDeadlineSeconds: 60
17  service:
18    port: 80
19    targetPort: 9898
20  analysis:
21    interval: 10s
22    threshold: 10
23    maxWeight: 50
24    stepWeight: 5
25    metrics:
26    - name: request-success-rate
27      thresholdRange:
28        min: 99
29      interval: 1m
30    webhooks:
31      - name: acceptance-test
32        type: pre-rollout
33        url: http://flagger-loadtester.test/
34        timeout: 30s
35        metadata:
36          type: bash
37          cmd: "curl -sd 'test' http://podinfo-canary/token | grep token"
38      - name: load-test
39        url: http://flagger-loadtester.test/
40        timeout: 5s
41        metadata:
42          cmd: "hey -z 1m -q 10 -c 2 http://app.your_domain/"

spec下,你首先定义了targetRef,它指定了要监视的部署,即podinfo

通过progressDeadlineSeconds,您允许卡纳利在任何时刻最多停留 60 秒,然后新的更改完全被扭转。这会防止停滞,并为其执行设定截止日期。然后,您将定义 Ingress 将使用的podinfo服务。Flagger 也可以在卡纳利执行期间创建多个临时服务,但主要服务将在卡纳利的生命周期内始终可用。

分析块定义了Flagger将如何看待从Nginx Ingress控制器获得的指标。间隔指示它每10秒查看它们,而门槛限制了在新发布回滚之前测量检查可能失败或不可用多少次。

接下来的两个部分,即指标网页,定义了新版本将如何测试 - 通过使用您之前部署的负载测试器创建流量,并监控请求的成功率。

记住用你自己的域代替突出的域,然后保存和关闭文件。

kubectl滚动它:

1kubectl apply -f podinfo-canary.yaml

你会看到加拿大人被创建:

1[secondary_label Output]
2canary.flagger.app/podinfo created

您现在可以导航到 app.your_domain. 您将看到 podinfo 应用:

podinfo app - Main Page

主页显示了已向您提供的podinfo版本以及从哪个pod. 您可以按 Ping按钮更新其他pod的版本号码。

若要验证 Flagger 接管根据 Canary 中描述的配置来更新部署的过程,请运行以下命令来设置podinfo的不同版本:

1kubectl set image deployment/podinfo podinfod=stefanprodan/podinfo:6.0.3 -n test

部署将更新:

1[secondary_label Output]
2deployment.apps/podinfo image updated

Flagger 会检测部署修订号发生了变化,您可以通过列出与podinfo相关的事件来检查:

1kubectl describe canary/podinfo -n test

过了一会儿,结果会像这样:

 1[secondary_label Output]
 2Events:
 3  Type Reason Age From Message
 4  ----     ------  ----               ----     -------
 5  Normal Synced 117s flagger New revision detected! Scaling up podinfo.test
 6  Warning Synced 107s flagger canary deployment podinfo.test not ready: waiting for rollout to finish: 0 of 2 (readyThreshold 100%) updated replicas are available
 7  Warning Synced 97s flagger canary deployment podinfo.test not ready: waiting for rollout to finish: 1 of 2 (readyThreshold 100%) updated replicas are available
 8  Normal Synced 87s flagger Starting canary analysis for podinfo.test
 9  Normal Synced 87s flagger Pre-rollout check acceptance-test passed
10  Normal Synced 87s flagger Advance podinfo.test canary weight 5
11  Warning Synced 67s (x2 over 77s)  flagger Halt advancement no values found for nginx metric request-success-rate probably podinfo.test is not receiving traffic: running query failed: no values found
12  Normal Synced 57s flagger Advance podinfo.test canary weight 10
13  Normal Synced 47s flagger Advance podinfo.test canary weight 15
14  Normal Synced 37s flagger Advance podinfo.test canary weight 20
15  Normal Synced 27s flagger Advance podinfo.test canary weight 25
16  ...

Flagger 记录了它根据加拿大定义所采取的所有操作. 检测到新修订后,它将测试支柱从中滚动,并通过提前加拿大体重开始分析,这意味着更多的流量被转移到新的支柱。

回到您的浏览器并观看版本号的闪烁,因为应用程序不断更新自己. 版本正在改变,因为Flagger正在增加流量量被路由到正在测试的新版本:

podinfo - Different Versions During Release

Flagger 表示流量转移的事件,从Advance podinfo.test canary weight开始,然后是被转移的流量百分比:

1[secondary_label Output]
2...
3  Normal Synced 116s flagger Advance podinfo.test canary weight 10
4  Normal Synced 106s flagger Advance podinfo.test canary weight 15
5...

过了一段时间,卡纳里部署应该成功,版本号数将稳定:

podinfo - New Version Is Completely Deployed

加拿大的最终事件日志将看起来像这样:

 1[secondary_label Output]
 2Events:
 3  Type Reason Age From Message
 4  ----     ------  ----                  ----     -------
 5  Normal Synced 2m56s flagger New revision detected! Scaling up podinfo.test
 6  Warning Synced 2m46s flagger canary deployment podinfo.test not ready: waiting for rollout to finish: 0 of 2 (readyThreshold 100%) updated replicas are available
 7  Warning Synced 2m36s flagger canary deployment podinfo.test not ready: waiting for rollout to finish: 1 of 2 (readyThreshold 100%) updated replicas are available
 8  Normal Synced 2m26s flagger Starting canary analysis for podinfo.test
 9  Normal Synced 2m26s flagger Pre-rollout check acceptance-test passed
10  Normal Synced 2m26s flagger Advance podinfo.test canary weight 5
11  Warning Synced 2m6s (x2 over 2m16s)  flagger Halt advancement no values found for nginx metric request-success-rate probably podinfo.test is not receiving traffic: running query failed: no values found
12  Normal Synced 116s flagger Advance podinfo.test canary weight 10
13  Normal Synced 106s flagger Advance podinfo.test canary weight 15
14  Normal Synced 96s flagger Advance podinfo.test canary weight 20
15  Normal Synced 86s flagger Advance podinfo.test canary weight 25
16  Normal Synced 76s flagger Advance podinfo.test canary weight 30
17  Warning Synced 16s flagger podinfo-primary.test not ready: waiting for rollout to finish: 1 old replicas are pending termination
18  Normal Synced 6s (x6 over 66s)      flagger  (combined from similar events): Routing all traffic to primary

最后的事件说,流量将被路由到主要服务,这意味着加那利部署已经完成。

在此步骤中,您已经部署了podinfo应用程序,并创建了一个 Ingress 来将其暴露在您的域中。您还创建了一个canary资源来控制和测试新的部署修订。

步骤 3 – 向 Slack 报告

现在,您将设置 Flagger 将其日志发送到您的 Slack 工作区,因此您和您的团队将能够随时查看完整的事件日志。

要使用 Slack 集成,您需要为您的工作区设置一个 Slack 上的 WebhookIncoming webhooks 是应用程序提供来自其他应用程序的实时信息的简单方法。

要做到这一点,先登录 Slack 并导航到 应用创建页面

您将被重定向到新应用程序的设置页面. 点击左导航栏的 Incoming Webhooks

Slack - App Settings

要启用 Webhooks,请转动标题旁边的开关按钮 启用即将到来的 Webhooks

Slack - Activate incoming web hooks

页面下方会发现一个新的部分。滚向下,点击 新 Webhook 添加到 Workspace ** 按钮. 下一页,选择要发送报告的渠道,然后点击 ** 允许

您将被重定向回webhooks的设置页面,您将看到在表中列出的新的webhook。

要将 Flagger 配置为向 Slack 发送日志,您需要通过运行更新其 Helm 版本:

1helm upgrade flagger flagger/flagger \
2--reuse-values \
3--set slack.url=your_hook_URL \
4--set slack.channel=your_channel_name \
5--set slack.user=username

请记住将your_hook_URL替换为您先前注意到的webhook URL、your_channel_name替换为所需频道的名称、username替换为创建webhook的用户的用户名。

由于--reuse-values被传输,Helm 将基于现有版本的新的 Flagger 版本,这意味着现有的设置变量值将不受影响,就像您在本教程的第一步重新配置 Nginx Ingress 控制器时一样。

结果将看起来像这样:

 1[secondary_label Output]
 2Release "flagger" has been upgraded. Happy Helming!
 3NAME: flagger
 4LAST DEPLOYED: ...
 5NAMESPACE: default
 6STATUS: deployed
 7REVISION: 2
 8TEST SUITE: None
 9NOTES:
10Flagger installed

您现在可以尝试通过运行发布一个新的podinfo部署:

1kubectl set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1 -n test

您很快就会看到在 Slack 中出现的消息:

Slack - Flagger Started Testing

Slack 消息描绘了有关 Canary 分析的基本信息,例如截止日期和测试在取消部署之前可能失败的次数。

当此版本部署时,您将看到一个成功消息:

Slack - Flagger Finished Promotion

由于Kanary 需要所有 HTTP 请求的 99% 成功率(它从 Nginx Ingress Controller 读取),您将创建一个新的版本,并在测试过程中从中生成 HTTP 500 错误。

对于新版本,重新部署6.0.3版本,运行:

1kubectl set image deployment/podinfo podinfod=stefanprodan/podinfo:6.0.3 -n test

您将在 Slack 上看到来自 Flagger 的一个新消息,表明已检测到新版本。 为了模拟故障,您将使用podinfo状态API,允许您生成您指定的 HTTP 状态报告。

运行以下命令来创建大量的 HTTP 500 状态:

1watch curl http://app.your_domain/status/500

过了一段时间,你会看到Flagger决定不应用新版本,因为HTTP请求的成功率连续低10次:

Slack - Flagger Rejected a Release

要退出弯曲,请按CTRL+C

现在,Flagger 每当检测到podinfo部署的新修订时都会向 Slack 报告,您也将收到新发布的结果通知,因此您和您的团队将始终关注您的应用程序发布的成功。

若要摧毁您部署的资源,请运行以下命令:

1kubectl delete -f podinfo-ingress.yaml
2kubectl delete -f podinfo-canary.yaml

结论

您现在已经学会了如何使用 Flagger 自动测试向您的 Kubernetes 集群推出的新版本,而不会影响现有部署。

canary analysis的过程可以扩展到先进的Prometheus查询 - 例如,根据HTTP请求延迟进行操作. 您可以在Flagger的 官方文档中了解更多。

Published At
Categories with 技术
comments powered by Disqus