Linkerd 金丝雀部署与 A/B 测试
本指南向您展示如何使用 Linkerd 和 Flagger 来自动化金丝雀部署与 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
。
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
来定位您的特定用户群。 这对于需要会话关联的前端应用程序特别有用。
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: always
header
调用服务。
请注意,负载测试现在针对外部地址并使用 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
公众号:黑客下午茶
Linkerd 金丝雀部署与 A/B 测试的更多相关文章
- 蓝绿部署、A/B测试以及灰度发布(金丝雀发布)
过去的10多年里,很多大公司都在使用蓝绿部署,安全.可靠是这种部署方式的特点.蓝绿部署虽然算不上”Sliver Bullet“,但确实很实用.在有关于“微服务”.“DevOps”.“Cloud-nat ...
- Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署
渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚. 这里有一些有趣的项目,使得渐进式交付在 Ku ...
- zookeeper部署及集群测试
zookeeper部署及集群测试 环境 三台测试机 操作系统: centos7 ; hostname: c1 ; ip: 192.168.1.80 操作系统: centos7 ; hostname: ...
- Redis Cluster部署、管理和测试
背景: Redis 3.0之后支持了Cluster,大大增强了Redis水平扩展的能力.Redis Cluster是Redis官方的集群实现方案,在此之前已经有第三方Redis集群解决方案,如Twen ...
- Solidity truffle,部署合约到Ropsten测试链或主链,调用合约(转)
Solidity truffle,部署合约到Ropsten测试链或主链,调用合约 转 https://blog.csdn.net/houyanhua1/article/details/89010896 ...
- FastDFS 的部署、配置与测试的
部署篇:http://soartju.iteye.com/blog/803477 配置篇:http://soartju.iteye.com/blog/803524 测试篇:http://soartju ...
- bluemix部署(一)简单测试,搭建样本flask程序。
1.注册bluemix 这个略 2.登录bluemix 这个也略 3.创建组织 这个确实是和我们的思想不一样.要创建组织.为什么呢?国内的很多服务都没见过组织这个概念.貌似神符合一个中国人是条龙,十个 ...
- Java-idea-创建maven项目,部署项目,部署服务器,简单测试
spring-boot项目创建 1.项目创建 使用Idea,File→Project→Spring initalizr,点击next,进行基本配置.此时 一个spring boot项目创建完成. 之后 ...
- 三十六.MHA集群概述 、 部署MHA集群 测试配置
1.准备MHA集群环境 准备6台虚拟机,并按照本节规划配置好IP参数 在这些虚拟机之间实现SSH免密登录 在相应节点上安装好MHA相关的软件包 使用6台RHEL 7虚拟机,如图-1所示.准备集群环 ...
随机推荐
- 重新整理 .net core 实践篇—————路由和终结点[二十三]
前言 简单整理一下路由和终节点. 正文 路由方式主要有两种: 1.路由模板方式 2.RouteAttribute 方式 路由约束: 1.类型约束 2.范围约束 3.正则表达式 4.是否必选 5.自定义 ...
- 为什么代码规范要求SQL语句不要过多的join?
面试官:有操作过Linux吗? 我:有的呀 面试官:我想查看内存的使用情况该用什么命令 我:free 或者 top 面试官:那你说一下用free命令都可以看到啥信息 我:那,如下图所示 可以看到内存以 ...
- Jenkins+Github+Nginx实现前端项目自动部署
前言 最近在搭建一个自己的网站,网站框架搭好了要把项目放到服务器运行,但是每次更新网站内容就要手动部署一次,实在很麻烦,于是就想搭建一套自动化部署的服务.看了一些案例最后选用现在比较主流的Jenkin ...
- Java进阶 | Proxy动态代理机制详解
一.Jvm加载对象 在说Java动态代理之前,还是要说一下Jvm加载对象的过程,这个依旧是理解动态代理的基础性原理: Java类即源代码程序.java类型文件,经过编译器编译之后就被转换成字节代码.c ...
- 阿里云中quick bi用地图分析数据时维度需转换为地理区域类型
1.到数据集里面点击编辑要做地图分析的数据集 2.找到要分析的地理维度字段,选择转换为对应的类型,这里为市级,所以选择转换为市,其它类似,然后点击右上角保存即可. 3.返回数据集,点击新建仪表板 4. ...
- 从零开始学前端,React框架背后的核心机制和原理JSX
什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...
- 从DVWA靶场学代码审计
DVWA是较为经典的一个传统漏洞的靶场 内置了low,medium,hight,impossible四个安全级别供安全人员去研究相关漏洞.今天就来对impossible这个级别进行代码审计,从中学习一 ...
- keycloak~自定义SPI的注入与扩展
项目结构 自定义SPI注册 1. 直接复制文件方式 docker cp keycloak-service-self-spi.jar keycloak:/opt/ docker cp module-on ...
- nginx用Certbot配置免费SSL证书(ngx_http_ssl_module模块)
一.准备工作 1.先安装nginx https://files.cnblogs.com/files/blogs/676936/nginx-1.18.0.sh #nginx-1.18.0版安装脚本2.在 ...
- 查看JVM中的线程名
实例说明 在Java虚拟机中(JVM):除了用户创建的线程,还有服务于用户线程的其他线程.它们根据不同的用途被分到不同的组中进行管理.本实例将演示JVM中线程的名字及其所在组的名称. 关键技术 线程组 ...