Linkerd 金丝雀部署与 A/B 测试

简介: Linkerd 金丝雀部署与 A/B 测试

前提条件



Flagger 需要 Kubernetes 集群 v1.16 或更新版本和 Linkerd 2.10 或更新版本。


安装 Linkerd the Prometheus(Linkerd Viz 的一部分):


linkerd install | kubectl apply -f -
linkerd viz install | kubectl apply -f -


在 linkerd 命名空间中安装 Flagger:


kubectl apply -k github.com/fluxcd/flagger//kustomize/linkerd


引导程序



Flagger 采用 Kubernetes deployment 和可选的水平 Pod 自动伸缩 (HPA),然后创建一系列对象(Kubernetes 部署、ClusterIP 服务和 SMI 流量拆分)。这些对象将应用程序暴露在网格内部并驱动 Canary 分析和推广。

创建一个 test 命名空间并启用 Linkerd 代理注入:


kubectl create ns test
kubectl annotate namespace test linkerd.io/inject=enabled


安装负载测试服务以在金丝雀分析期间生成流量:


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


创建部署和水平 pod autoscaler:


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


为 podinfo 部署创建一个 Canary 自定义资源:


apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  # deployment reference
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  # HPA reference (optional)
  autoscalerRef:
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    name: podinfo
  # the maximum time in seconds for the canary deployment
  # to make progress before it is rollback (default 600s)
  progressDeadlineSeconds: 60
  service:
    # ClusterIP port number
    port: 9898
    # container port number or name (optional)
    targetPort: 9898
  analysis:
    # schedule interval (default 60s)
    interval: 30s
    # max number of failed metric checks before rollback
    threshold: 5
    # max traffic percentage routed to canary
    # percentage (0-100)
    maxWeight: 50
    # canary increment step
    # percentage (0-100)
    stepWeight: 5
    # Linkerd Prometheus checks
    metrics:
    - name: request-success-rate
      # minimum req success rate (non 5xx responses)
      # percentage (0-100)
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      # maximum req duration P99
      # milliseconds
      thresholdRange:
        max: 500
      interval: 30s
    # testing (optional)
    webhooks:
      - name: acceptance-test
        type: pre-rollout
        url: http://flagger-loadtester.test/
        timeout: 30s
        metadata:
          type: bash
          cmd: "curl -sd 'test' http://podinfo-canary.test:9898/token | grep token"
      - name: load-test
        type: rollout
        url: http://flagger-loadtester.test/
        metadata:
          cmd: "hey -z 2m -q 10 -c 2 http://podinfo-canary.test:9898/"


将上述资源另存为 podinfo-canary.yaml 然后应用:


kubectl apply -f ./podinfo-canary.yaml


当 Canary 分析开始时,Flagger 将在将流量路由到 Canary 之前调用 pre-rollout webhooks。金丝雀分析将运行五分钟,同时每半分钟验证一次 HTTP 指标和 rollout(推出) hooks。


几秒钟后,Flager 将创建 canary 对象:


# applied
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
ingresses.extensions/podinfo
canary.flagger.app/podinfo
# generated
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
trafficsplits.split.smi-spec.io/podinfo


在 boostrap 之后,podinfo 部署将被缩放到零, 并且到 podinfo.test 的流量将被路由到主 pod。在 Canary 分析过程中,可以使用 podinfo-canary.test 地址直接定位 Canary Pod。


自动金丝雀推进


Flagger 实施了一个控制循环,在测量 HTTP 请求成功率、请求平均持续时间和 Pod 健康状况等关键性能指标的同时,逐渐将流量转移到金丝雀。根据对 KPI 的分析,提升或中止 Canary,并将分析结果发布到 Slack。


image.gif微信图片_20220612144901.png

Flagger 金丝雀阶段


通过更新容器镜像触发金丝雀部署:


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


Flagger 检测到部署修订已更改并开始新的部署:


kubectl -n test describe canary/podinfo
Status:
  Canary Weight:         0
  Failed Checks:         0
  Phase:                 Succeeded
Events:
 New revision detected! Scaling up podinfo.test
 Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
 Pre-rollout check acceptance-test passed
 Advance podinfo.test canary weight 5
 Advance podinfo.test canary weight 10
 Advance podinfo.test canary weight 15
 Advance podinfo.test canary weight 20
 Advance podinfo.test canary weight 25
 Waiting for podinfo.test rollout to finish: 1 of 2 updated replicas are available
 Advance podinfo.test canary weight 30
 Advance podinfo.test canary weight 35
 Advance podinfo.test canary weight 40
 Advance podinfo.test canary weight 45
 Advance podinfo.test canary weight 50
 Copying podinfo.test template spec to podinfo-primary.test
 Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
 Promotion completed! Scaling down podinfo.test


请注意,如果您在 Canary 分析期间对部署应用新更改,Flagger 将重新开始分析。

金丝雀部署由以下任何对象的更改触发:


  • Deployment PodSpec(容器镜像container image、命令command、端口ports、环境env、资源resources等)
  • ConfigMaps 作为卷挂载或映射到环境变量
  • Secrets 作为卷挂载或映射到环境变量

您可以通过以下方式监控所有金丝雀:


watch kubectl get canaries --all-namespaces
NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   15       2019-06-30T14:05:07Z
prod        frontend  Succeeded     0        2019-06-30T16:15:07Z
prod        backend   Failed        0        2019-06-30T17:05:07Z


自动回滚


在金丝雀分析期间,您可以生成 HTTP 500 错误和高延迟来测试 Flagger 是否暂停并回滚有故障的版本。

触发另一个金丝雀部署:


kubectl -n test set image deployment/podinfo \
podinfod=stefanprodan/podinfo:3.1.2


使用以下命令执行负载测试器 pod:


kubectl -n test exec -it flagger-loadtester-xx-xx sh


生成 HTTP 500 错误:


watch -n 1 curl http://podinfo-canary.test:9898/status/500


生成延迟:


watch -n 1 curl http://podinfo-canary.test:9898/delay/1


当失败的检查次数达到金丝雀分析阈值时,流量将路由回主服务器,金丝雀缩放为零,并将推出标记为失败。


kubectl -n test describe canary/podinfo
Status:
  Canary Weight:         0
  Failed Checks:         10
  Phase:                 Failed
Events:
 Starting canary analysis for podinfo.test
 Pre-rollout check acceptance-test passed
 Advance podinfo.test canary weight 5
 Advance podinfo.test canary weight 10
 Advance podinfo.test canary weight 15
 Halt podinfo.test advancement success rate 69.17% < 99%
 Halt podinfo.test advancement success rate 61.39% < 99%
 Halt podinfo.test advancement success rate 55.06% < 99%
 Halt podinfo.test advancement request duration 1.20s > 0.5s
 Halt podinfo.test advancement request duration 1.45s > 0.5s
 Rolling back podinfo.test failed checks threshold reached 5
 Canary failed! Scaling down podinfo.test


自定义指标


Canary analysis 可以通过 Prometheus 查询进行扩展。

让我们定义一个未找到错误的检查。编辑 canary analysis 并添加以下指标:


analysis:
    metrics:
    - name: "404s percentage"
      threshold: 3
      query: |
        100 - sum(
            rate(
                response_total{
                    namespace="test",
                    deployment="podinfo",
                    status_code!="404",
                    direction="inbound"
                }[1m]
            )
        )
        /
        sum(
            rate(
                response_total{
                    namespace="test",
                    deployment="podinfo",
                    direction="inbound"
                }[1m]
            )
        )
        * 100


上述配置通过检查 HTTP 404 req/sec 百分比是否低于总流量的 3% 来验证金丝雀版本。如果 404s 率达到 3% 阈值,则分析将中止,金丝雀被标记为失败。

通过更新容器镜像触发金丝雀部署:


kubectl -n test set image deployment/podinfo \
podinfod=stefanprodan/podinfo:3.1.3


生成 404:


watch -n 1 curl http://podinfo-canary:9898/status/404


监视 Flagger 日志:


kubectl -n linkerd logs deployment/flagger -f | jq .msg
Starting canary deployment for podinfo.test
Pre-rollout check acceptance-test passed
Advance podinfo.test canary weight 5
Halt podinfo.test advancement 404s percentage 6.20 > 3
Halt podinfo.test advancement 404s percentage 6.45 > 3
Halt podinfo.test advancement 404s percentage 7.22 > 3
Halt podinfo.test advancement 404s percentage 6.50 > 3
Halt podinfo.test advancement 404s percentage 6.34 > 3
Rolling back podinfo.test failed checks threshold reached 5
Canary failed! Scaling down podinfo.test


如果您配置了 Slack,Flager 将发送一条通知,说明金丝雀失败的原因。


Linkerd Ingress


有两个入口控制器与 Flagger 和 Linkerd 兼容:NGINX 和 Gloo。

安装 NGINX:


helm upgrade -i nginx-ingress stable/nginx-ingress \
--namespace ingress-nginx


为 podinfo 创建一个 ingress 定义,将传入标头重写为内部服务名称(Linkerd 需要):


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: podinfo
  namespace: test
  labels:
    app: podinfo
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:9898;
      proxy_hide_header l5d-remote-ip;
      proxy_hide_header l5d-server-id;
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - backend:
              serviceName: podinfo
              servicePort: 9898


使用 ingress controller 时,Linkerd 流量拆分不适用于传入流量,因为 NGINX 在网格之外运行。为了对前端应用程序运行金丝雀分析,Flagger 创建了一个 shadow ingress 并设置了 NGINX 特定的注释(annotations)。


A/B 测试


除了加权路由,Flagger 还可以配置为根据 HTTP 匹配条件将流量路由到金丝雀。在 A/B 测试场景中,您将使用 HTTP headers 或 cookies 来定位您的特定用户群。这对于需要会话关联的前端应用程序特别有用。


image.gif微信图片_20220612145008.png

Flagger Linkerd Ingress


编辑 podinfo 金丝雀分析,将提供者设置为 nginx,添加 ingress 引用,移除 max/step 权重并添加匹配条件和 iterations:


apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  # ingress reference
  provider: nginx
  ingressRef:
    apiVersion: extensions/v1beta1
    kind: Ingress
    name: podinfo
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  autoscalerRef:
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    # container port
    port: 9898
  analysis:
    interval: 1m
    threshold: 10
    iterations: 10
    match:
      # curl -H 'X-Canary: always' http://app.example.com
      - headers:
          x-canary:
            exact: "always"
      # curl -b 'canary=always' http://app.example.com
      - headers:
          cookie:
            exact: "canary"
    # Linkerd Prometheus checks
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      thresholdRange:
        max: 500
      interval: 30s
    webhooks:
      - name: acceptance-test
        type: pre-rollout
        url: http://flagger-loadtester.test/
        timeout: 30s
        metadata:
          type: bash
          cmd: "curl -sd 'test' http://podinfo-canary:9898/token | grep token"
      - name: load-test
        type: rollout
        url: http://flagger-loadtester.test/
        metadata:
          cmd: "hey -z 2m -q 10 -c 2 -H 'Cookie: canary=always' http://app.example.com"


上述配置将运行 10 分钟的分析,目标用户是:canary cookie 设置为 always 或使用 X-Canary: alwaysheader 调用服务。


请注意,负载测试现在针对外部地址并使用 canary cookie。

通过更新容器镜像触发金丝雀部署:


kubectl -n test set image deployment/podinfo \
podinfod=stefanprodan/podinfo:3.1.4


Flagger 检测到部署修订已更改并开始 A/B 测试:


kubectl -n test describe canary/podinfo
Events:
 Starting canary deployment for podinfo.test
 Pre-rollout check acceptance-test passed
 Advance podinfo.test canary iteration 1/10
 Advance podinfo.test canary iteration 2/10
 Advance podinfo.test canary iteration 3/10
 Advance podinfo.test canary iteration 4/10
 Advance podinfo.test canary iteration 5/10
 Advance podinfo.test canary iteration 6/10
 Advance podinfo.test canary iteration 7/10
 Advance podinfo.test canary iteration 8/10
 Advance podinfo.test canary iteration 9/10
 Advance podinfo.test canary iteration 10/10
 Copying podinfo.test template spec to podinfo-primary.test
 Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
 Promotion completed! Scaling down podinfo.test



相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
机器学习/深度学习 编解码 监控
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章详细介绍了如何使用YOLOv8进行目标检测任务,包括环境搭建、数据准备、模型训练、验证测试以及模型转换等完整流程。
30586 59
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
机器学习/深度学习 自然语言处理 API
阿里云零门槛、轻松部署您的专属 DeepSeek模型体验测试
DeepSeek R1是基于Transformer架构的先进大规模深度学习模型,2025年1月20日发布并开源,遵循MIT License。它在自然语言处理等任务上表现出色,高效提取特征,缩短训练时间。阿里云推出的满血版方案解决了服务器压力问题,提供100万免费token,云端部署降低成本,用户可快速启动体验。虽然回答速度有待提升,但整体表现优异,备受关注。
770 8
|
Java 测试技术 应用服务中间件
Spring Boot 如何测试打包部署
本文介绍了 Spring Boot 项目的开发、调试、打包及投产上线的全流程。主要内容包括: 1. **单元测试**:通过添加 `spring-boot-starter-test` 包,使用 `@RunWith(SpringRunner.class)` 和 `@SpringBootTest` 注解进行测试类开发。 2. **集成测试**:支持热部署,通过添加 `spring-boot-devtools` 实现代码修改后自动重启。 3. **投产上线**:提供两种部署方案,一是打包成 jar 包直接运行,二是打包成 war 包部署到 Tomcat 服务器。
653 10
|
JavaScript NoSQL Java
基于SpringBoot+Vue实现的大学生体质测试管理系统设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
机器学习/深度学习 监控 计算机视觉
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
本文介绍了如何使用YOLOv7进行目标检测,包括环境搭建、数据集准备、模型训练、验证、测试以及常见错误的解决方法。YOLOv7以其高效性能和准确率在目标检测领域受到关注,适用于自动驾驶、安防监控等场景。文中提供了源码和论文链接,以及详细的步骤说明,适合深度学习实践者参考。
4436 1
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
敏捷开发 Devops 测试技术
自动化测试中的持续集成与持续部署
在现代软件开发实践中,自动化测试是确保软件质量和快速迭代的关键。本文将探讨自动化测试如何与持续集成(CI)和持续部署(CD)流程相结合,以提高开发效率和软件质量。我们将分析CI/CD管道中自动化测试的最佳实践,以及如何克服实施过程中的挑战。
495 6
|
缓存 自然语言处理 并行计算
基于NVIDIA A30 加速卡推理部署通义千问-72B-Chat测试过程
本文介绍了基于阿里云通义千问72B大模型(Qwen-72B-Chat)的性能基准测试,包括测试环境准备、模型部署、API测试等内容。测试环境配置为32核128G内存的ECS云主机,配备8块NVIDIA A30 GPU加速卡。软件环境包括Ubuntu 22.04、CUDA 12.4.0、PyTorch 2.4.0等。详细介绍了模型下载、部署命令及常见问题解决方法,并展示了API测试结果和性能分析。
7587 1
|
机器学习/深度学习 并行计算 数据可视化
目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用PaddleClas框架完成多标签分类任务,包括数据准备、环境搭建、模型训练、预测、评估等完整流程。
1681 0
目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)
|
机器学习/深度学习 数据采集 算法
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
这篇博客文章介绍了如何使用包含多个网络和多种训练策略的框架来完成多目标分类任务,涵盖了从数据准备到训练、测试和部署的完整流程,并提供了相关代码和配置文件。
782 0
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
|
机器学习/深度学习 XML 并行计算
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用YOLOX完成图像目标检测任务的完整流程,包括数据准备、模型训练、验证和测试。
2010 0
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)