简介: 作为CNCF[成员](https://landscape.cncf.io/card-mode?category=continuous-integration-delivery&grouping=category&selected=weave-flagger),[Weave Flagger](flagger.app)提供了持续集成和持续交付的各项能力。Flagger将渐进式发布总结为3类: - **灰度发布/金丝雀发布(Canary)**:用于渐进式切流到灰度版本(progressive traffic shifting) - **A/B测试(A/B Testing)**:用于根据请求信息将

作为CNCF成员Weave Flagger提供了持续集成和持续交付的各项能力。Flagger将渐进式发布总结为3类:

  • 灰度发布/金丝雀发布(Canary):用于渐进式切流到灰度版本(progressive traffic shifting)
  • A/B测试(A/B Testing):用于根据请求信息将用户请求路由到A/B版本(HTTP headers and cookies traffic routing)
  • 蓝绿发布(Blue/Green):用于流量切换和流量复制 (traffic switching and mirroring)

本篇将介绍Flagger on ASM的渐进式灰度发布实践。

Setup Flagger

1 部署Flagger

执行如下命令部署flagger(完整脚本参见:demo_canary.sh)。

alias k="kubectl --kubeconfig $USER_CONFIG"
alias h="helm --kubeconfig $USER_CONFIG" cp $MESH_CONFIG kubeconfig
k -n istio-system create secret generic istio-kubeconfig --from-file kubeconfig
k -n istio-system label secret istio-kubeconfig istio/multiCluster=true h repo add flagger https://flagger.app
h repo update
k apply -f $FLAAGER_SRC/artifacts/flagger/crd.yaml
h upgrade -i flagger flagger/flagger --namespace=istio-system \
--set crd.create=false \
--set meshProvider=istio \
--set metricsServer=http://prometheus:9090 \
--set istio.kubeconfig.secretName=istio-kubeconfig \
--set istio.kubeconfig.key=kubeconfig

2 部署Gateway

在灰度发布过程中,Flagger会请求ASM更新用于灰度流量配置的VirtualService,这个VirtualService会使用到命名为public-gateway的Gateway。为此我们创建相关Gateway配置文件public-gateway.yaml如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: public-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

执行如下命令部署Gateway:

kubectl --kubeconfig "$MESH_CONFIG" apply -f resources_canary/public-gateway.yaml

3 部署flagger-loadtester

flagger-loadtester是灰度发布阶段,用于探测灰度POD实例的应用。

执行如下命令部署flagger-loadtester:

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

4 部署PodInfo及其HPA

我们首先使用Flagger发行版自带的HPA配置(这是一个运维级的HPA),待完成完整流程后,我们再使用应用级的HPA。

执行如下命令部署PodInfo及其HPA:

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

渐进式灰度发布

1 部署Canary

Canary是基于Flagger进行灰度发布的核心CRD,详见How it works。我们首先部署如下Canary配置文件podinfo-canary.yaml,完成完整的渐进式灰度流程,然后在此基础上引入应用维度的监控指标,来进一步实现应用有感知的渐进式灰度发布。

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
# deployment reference
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
# the maximum time in seconds for the canary deployment
# to make progress before it is rollback (default 600s)
progressDeadlineSeconds: 60
# HPA reference (optional)
autoscalerRef:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
name: podinfo
service:
# service port number
port: 9898
# container port number or name (optional)
targetPort: 9898
# Istio gateways (optional)
gateways:
- public-gateway.istio-system.svc.cluster.local
# Istio virtual service host names (optional)
hosts:
- '*'
# Istio traffic policy (optional)
trafficPolicy:
tls:
# use ISTIO_MUTUAL when mTLS is enabled
mode: DISABLE
# Istio retry policy (optional)
retries:
attempts: 3
perTryTimeout: 1s
retryOn: "gateway-error,connect-failure,refused-stream"
analysis:
# schedule interval (default 60s)
interval: 1m
# 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: 10
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:9898/token | grep token"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"

执行如下命令部署Canary:

kubectl --kubeconfig "$USER_CONFIG" apply -f resources_canary/podinfo-canary.yaml

部署Canary后,Flagger会将名为podinfo的Deployment复制为podinfo-primary,并将podinfo-primary扩容至HPA定义的最小POD数量。然后逐步将名为podinfo的这个Deployment的POD数量将缩容至0。也就是说,podinfo将作为灰度版本的Deployment,podinfo-primary将作为生产版本的Deployment。

同时,创建3个服务——podinfopodinfo-primarypodinfo-canary,前两者指向podinfo-primary这个Deployment,最后者指向podinfo这个Deployment。

2 升级podinfo

执行如下命令,将灰度Deployment的版本从3.1.0升级到3.1.1

kubectl --kubeconfig "$USER_CONFIG" -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1

3 渐进式灰度发布

此时,Flagger将开始执行如本系列第一篇所述的渐进式灰度发布流程,这里再简述主要流程如下:

  1. 逐步扩容灰度POD、验证
  2. 渐进式切流、验证
  3. 滚动升级生产Deployment、验证
  4. 100%切回生产
  5. 缩容灰度POD至0

我们可以通过如下命令观察这个渐进式切流的过程:

while true; do kubectl --kubeconfig "$USER_CONFIG" -n test describe canary/podinfo; sleep 10s;done

输出的日志信息示意如下:

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 39m flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less then desired generation
Normal Synced 38m (x2 over 39m) flagger all the metrics providers are available!
Normal Synced 38m flagger Initialization done! podinfo.test
Normal Synced 37m flagger New revision detected! Scaling up podinfo.test
Normal Synced 36m flagger Starting canary analysis for podinfo.test
Normal Synced 36m flagger Pre-rollout check acceptance-test passed
Normal Synced 36m flagger Advance podinfo.test canary weight 10
Normal Synced 35m flagger Advance podinfo.test canary weight 20
Normal Synced 34m flagger Advance podinfo.test canary weight 30
Normal Synced 33m flagger Advance podinfo.test canary weight 40
Normal Synced 29m (x4 over 32m) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test

相应的Kiali视图(可选),如下图所示:

到此,我们完成了一个完整的渐进式灰度发布流程。如下是扩展阅读。

灰度中的应用级扩缩容

在完成上述渐进式灰度发布流程的基础上,我们接下来再来看上述Canary配置中,关于HPA的配置。

  autoscalerRef:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
name: podinfo

这个名为podinfo的HPA是Flagger自带的配置,当灰度Deployment的CPU利用率达到99%时扩容。完整配置如下:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: podinfo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
minReplicas: 2
maxReplicas: 4
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
# scale up if usage is above
# 99% of the requested CPU (100m)
averageUtilization: 99

我们在前面一篇中讲述了应用级扩缩容的实践,在此,我们将其应用于灰度发布的过程中。

1 感知应用QPS的HPA

执行如下命令部署感知应用请求数量的HPA,实现在QPS达到10时进行扩容(完整脚本参见:advanced_canary.sh):

kubectl --kubeconfig "$USER_CONFIG" apply -f resources_hpa/requests_total_hpa.yaml

相应地,Canary配置更新为:

  autoscalerRef:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
name: podinfo-total

2 升级podinfo

执行如下命令,将灰度Deployment的版本从3.1.0升级到3.1.1

kubectl --kubeconfig "$USER_CONFIG" -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1

3 验证渐进式灰度发布及HPA

命令观察这个渐进式切流的过程:

while true; do k -n test describe canary/podinfo; sleep 10s;done

在渐进式灰度发布过程中(在出现Advance podinfo.test canary weight 10信息后,见下图),我们使用如下命令,从入口网关发起请求以增加QPS:

INGRESS_GATEWAY=$(kubectl --kubeconfig $USER_CONFIG -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
hey -z 20m -c 2 -q 10 http://$INGRESS_GATEWAY

使用如下命令观察渐进式灰度发布进度:

watch kubectl --kubeconfig $USER_CONFIG get canaries --all-namespaces

使用如下命令观察hpa的副本数变化:

watch kubectl --kubeconfig $USER_CONFIG -n test get hpa/podinfo-total

结果如下图所示,在渐进式灰度发布过程中,当切流到30%的某一时刻,灰度Deployment的副本数为4:

灰度中的应用级监控指标

在完成上述灰度中的应用级扩缩容的基础上,最后我们再来看上述Canary配置中,关于metrics的配置:

  analysis:
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)

1 Flagger内置监控指标

到目前为止,Canary中使用的metrics配置一直是Flagger的两个内置监控指标:请求成功率(request-success-rate)和请求延迟(request-duration)。如下图所示,Flagger中不同平台对内置监控指标的定义,其中,istio使用的是本系列第一篇介绍的Mixerless Telemetry相关的遥测数据。

2 自定义监控指标

为了展示灰度发布过程中,遥测数据为验证灰度环境带来的更多灵活性,我们再次以istio_requests_total为例,创建一个名为not-found-percentageMetricTemplate,统计请求返回404错误码的数量占请求总数的比例。

配置文件metrics-404.yaml如下(完整脚本参见:advanced_canary.sh):

apiVersion: flagger.app/v1beta1
kind: MetricTemplate
metadata:
name: not-found-percentage
namespace: istio-system
spec:
provider:
type: prometheus
address: http://prometheus.istio-system:9090
query: |
100 - sum(
rate(
istio_requests_total{
reporter="destination",
destination_workload_namespace="{{ namespace }}",
destination_workload="{{ target }}",
response_code!="404"
}[{{ interval }}]
)
)
/
sum(
rate(
istio_requests_total{
reporter="destination",
destination_workload_namespace="{{ namespace }}",
destination_workload="{{ target }}"
}[{{ interval }}]
)
) * 100

执行如下命令创建上述MetricTemplate:

k apply -f resources_canary2/metrics-404.yaml

相应地,Canary中metrics的配置更新为:

  analysis:
metrics:
- name: "404s percentage"
templateRef:
name: not-found-percentage
namespace: istio-system
thresholdRange:
max: 5
interval: 1m

3 最后的验证

最后,我们一次执行完整的实验脚本。脚本advanced_canary.sh示意如下:

#!/usr/bin/env sh
SCRIPT_PATH="$(
cd "$(dirname "$0")" >/dev/null 2>&1
pwd -P
)/"
cd "$SCRIPT_PATH" || exit source config
alias k="kubectl --kubeconfig $USER_CONFIG"
alias m="kubectl --kubeconfig $MESH_CONFIG"
alias h="helm --kubeconfig $USER_CONFIG" echo "#### I Bootstrap ####"
echo "1 Create a test namespace with Istio sidecar injection enabled:"
k delete ns test
m delete ns test
k create ns test
m create ns test
m label namespace test istio-injection=enabled echo "2 Create a deployment and a horizontal pod autoscaler:"
k apply -f $FLAAGER_SRC/kustomize/podinfo/deployment.yaml -n test
k apply -f resources_hpa/requests_total_hpa.yaml
k get hpa -n test echo "3 Deploy the load testing service to generate traffic during the canary analysis:"
k apply -k "https://github.com/fluxcd/flagger//kustomize/tester?ref=main" k get pod,svc -n test
echo "......"
sleep 40s echo "4 Create a canary custom resource:"
k apply -f resources_canary2/metrics-404.yaml
k apply -f resources_canary2/podinfo-canary.yaml k get pod,svc -n test
echo "......"
sleep 120s echo "#### III Automated canary promotion ####" echo "1 Trigger a canary deployment by updating the container image:"
k -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1 echo "2 Flagger detects that the deployment revision changed and starts a new rollout:" while true; do k -n test describe canary/podinfo; sleep 10s;done

使用如下命令执行完整的实验脚本:

sh progressive_delivery/advanced_canary.sh

实验结果示意如下:


#### I Bootstrap ####
1 Create a test namespace with Istio sidecar injection enabled:
namespace "test" deleted
namespace "test" deleted
namespace/test created
namespace/test created
namespace/test labeled
2 Create a deployment and a horizontal pod autoscaler:
deployment.apps/podinfo created
horizontalpodautoscaler.autoscaling/podinfo-total created
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
podinfo-total Deployment/podinfo <unknown>/10 (avg) 1 5 0 0s
3 Deploy the load testing service to generate traffic during the canary analysis:
service/flagger-loadtester created
deployment.apps/flagger-loadtester created
NAME READY STATUS RESTARTS AGE
pod/flagger-loadtester-76798b5f4c-ftlbn 0/2 Init:0/1 0 1s
pod/podinfo-689f645b78-65n9d 1/1 Running 0 28s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/flagger-loadtester ClusterIP 172.21.15.223 <none> 80/TCP 1s
......
4 Create a canary custom resource:
metrictemplate.flagger.app/not-found-percentage created
canary.flagger.app/podinfo created
NAME READY STATUS RESTARTS AGE
pod/flagger-loadtester-76798b5f4c-ftlbn 2/2 Running 0 41s
pod/podinfo-689f645b78-65n9d 1/1 Running 0 68s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/flagger-loadtester ClusterIP 172.21.15.223 <none> 80/TCP 41s
......
#### III Automated canary promotion ####
1 Trigger a canary deployment by updating the container image:
deployment.apps/podinfo image updated
2 Flagger detects that the deployment revision changed and starts a new rollout: Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 10m flagger podinfo-primary.test not ready: waiting for rollout to finish: observed deployment generation less then desired generation
Normal Synced 9m23s (x2 over 10m) flagger all the metrics providers are available!
Normal Synced 9m23s flagger Initialization done! podinfo.test
Normal Synced 8m23s flagger New revision detected! Scaling up podinfo.test
Normal Synced 7m23s flagger Starting canary analysis for podinfo.test
Normal Synced 7m23s flagger Pre-rollout check acceptance-test passed
Normal Synced 7m23s flagger Advance podinfo.test canary weight 10
Normal Synced 6m23s flagger Advance podinfo.test canary weight 20
Normal Synced 5m23s flagger Advance podinfo.test canary weight 30
Normal Synced 4m23s flagger Advance podinfo.test canary weight 40
Normal Synced 23s (x4 over 3m23s) flagger (combined from similar events): Promotion completed! Scaling down podinfo.test
 
本文为阿里云原创内容,未经允许不得转载。

Flagger on ASM——基于Mixerless Telemetry实现渐进式灰度发布系列 3 渐进式灰度发布的更多相关文章

  1. RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录

    RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录 RDIFramework.NET,基于.NET的快速信息化系统开发.整合框架,给用户和开发者最佳的.Net框架 ...

  2. 最简单的基于librtmp的示例:发布(FLV通过RTMP发布)

    ===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...

  3. 基于Azure的软件部署和开发系列沙龙

    活动简介: Azure是一种灵活和支持互操作的平台,它可以被用来创建云中运行的应用或者通过基于云的特性来加强现有应用.它开放式的架构给开发者提供了Web应用.互联设备的应用.个人电脑.服务器.或者提供 ...

  4. 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)

    在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...

  5. 基于Cocos2d-x学习OpenGL ES 2.0系列——使用VBO索引(4)

    在上一篇文章中,我们介绍了uniform和模型-视图-投影变换,相信大家对于OpenGL ES 2.0应该有一点感觉了.在这篇文章中,我们不再画三角形了,改为画四边形.下篇教程,我们就可以画立方体了, ...

  6. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  7. [译]基于ASP.NET Core 3.0的ABP v0.21已发布

    基于ASP.NET Core 3.0的ABP v0.21已发布 在微软发布仅仅一个小时后, 基于ASP.NET Core 3.0的ABP v0.21也紧跟着发布了. v0.21没有新功能.它只是升级到 ...

  8. PGL图学习之基于GNN模型新冠疫苗任务[系列九]

    PGL图学习之基于GNN模型新冠疫苗任务[系列九] 项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5123296?contributio ...

  9. 基于英特尔® 至强 E5 系列处理器的单节点 Caffe 评分和训练

    原文链接 在互联网搜索引擎和医疗成像等诸多领域,深度神经网络 (DNN) 应用的重要性正在不断提升. Pradeep Dubey 在其博文中概述了英特尔® 架构机器学习愿景. 英特尔正在实现 Prad ...

  10. 基于Flash与window平台本地程序通信实现媒体流发布

    0 Web场景下的媒体流发布可以采用Flash原生API实现,但是Flash H264视频压缩参数不可控.音频无法AAC编码,所以一般采用浏览器插件方式,但是浏览器插件有版本兼容问题.不稳定,所以可以 ...

随机推荐

  1. Spring Boot学习日记15

    使用thymeleaf <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.o ...

  2. [深度学习] 计算机视觉低代码工具Supervision库使用指北

    Supervision库是一款出色的Python计算机视觉低代码工具,其设计初衷在于为用户提供一个便捷且高效的接口,用以处理数据集以及直观地展示检测结果.Supervision库的官方开源仓库地址为: ...

  3. 记录--不定高度展开收起动画 css/js 实现

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 不定高度展开收起动画 最近在做需求的时候,遇见了元素高度展开收起的动画需求,一开始是想到了使用 transition: all .3s; ...

  4. Loto实践干货(9) 示波器测 晶振

    我们用LOTO示波器的多个型号,带宽从20M到100M,分别测无源和有源晶振的情况.分别测试了12M,15M,24M,48M,80M晶振的波形.并分析了为什么我们经常测出晶振波形不是方波?为什么有时候 ...

  5. 把分钟数转化成几小时几分钟(100 -> 01:40)

    /// <summary> /// 把分钟数转化成几小时几分钟(100 -> 01:40) /// </summary> /// <param name=" ...

  6. Linux开发相关命令整理

    1. 反转shell 2. ldd 3. objdump 4. ldconfig 5. telnet 6. nc 7. netstat 8. ss 9. tcpdump 10. lsof 11. st ...

  7. KingbaseES数据库配置Hikari数据源

    Hikari是一个高性能的数据库连接池,它是Spring Boot 2.x中的默认数据源. 一.下载驱动 打开下面网址:选择对应平台的jdbc驱动程序. 人大金仓-成为世界卓越的数据库产品与服务提供商 ...

  8. KingbaseES V8R6运维案例之---数据库resetwal后启动失败

    KingbaseES V8R6运维案例之---数据库resetwal后启动失败 案例说明: KingbaseES V8R6集群触发failover切换后,原主库自动recovery失败,现在需要将原主 ...

  9. 腾讯tvp之路

    王清培 腾讯tvp之路

  10. 5 CSS伪类选择器

    5 伪类选择器 anchor伪类:专用于控制链接的显示效果 More Actions:link a:link 选择所有未被访问的链接. :visited a:visited 选择所有已被访问的链接. ...