请求分析和渐进式交付
Argo Rollouts中的分析(Analysis)是用于根据阶段性交付效果的测量结果来推动渐进式交付的机制
◼ 分析机制通过分析模板(AnalysisTemplate CRD)定义,而后在Rollout中调用它
◼ 运行某次特定的交付过程时,Argo Rollouts会将该Rollout调用的AnalysisTemplate实例化为AnalysisRun(CRD)
AnalysisTemplate资源与AnalysisRun CRD
示例说明
◼ 定义了一个名为service-name的参数
◆用于传递要测量的服务的名称
◼ 定义了success-rate指标
◆测试指定服务的请求成功率
◼ 每隔20s查询一次prometheus服务,共执行三次
◼ 成功条件为:第1个指标(下标为0)的结果值大于等于0.95
◼ 遇到3次错误即终止进一步的测试
AnalysisRun CRD
◼ 配置格式与AnalysisTemplaste大致相同,所不同的是,AnalysisRun用于调用并实例化分析模板
结合Prometheus指标进行analysis
一:让ingress-controller能够允许prometheus过来抓指标
修改ingress-nginx-controller
二:部署Prometheus
克隆仓库,进行部署
git clone https://github.com/iKubernetes/k8s-prom.git
[root@ubuntu2004 ~]#cd k8s-prom/
[root@ubuntu2004 k8s-prom]#ls
k8s-prometheus-adapter namespace.yaml podinfo prometheus-ingress
kube-state-metrics node_exporter prometheus README.md
创建名称空间
[root@ubuntu2004 k8s-prom]#cat namespace.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: prom
[root@ubuntu2004 k8s-prom]#kubectl apply -f namespace.yaml
把prometheus目录下的资源进行部署(相关文件内容不在展示,请克隆自行查看)
[root@ubuntu2004 k8s-prom]#kubectl apply -f prometheus/ -n prom
查看prom名称空间下的pod
[root@ubuntu2004 k8s-prom]#kubectl get pods -n prom
三:让prometheus能够在集群外部进行访问,使用ingress把其发布出去
[root@ubuntu2004 k8s-prom]#kubectl apply -f prometheus-ingress -n prom
在桌面系统对域名进行解析,然后打开页面
外部请求都是正确的
再起一终端修改外部请求,如修改请求到错误的Url上
while true; do curl hello.magedu.com/magedu.com; sleep $[$RAMDOM%20]; done
四:拆掉之前的rollouts资源,建立基于prometheus监控,自动执行更新的rollouts资源
[root@ubuntu2004 ~]#cd learning-jenkins-cicd/09-argocd-and-rollout/rollout-demos/
[root@ubuntu2004 rollout-demos]#ls
01-basic-rollouts-demo.yaml 04-rollouts-bluegreen-demo.yaml
02-rollouts-with-ingress-nginx-traffic-shifting.yaml 05-rollouts-bluegreen-with-analysis.yaml
03-rollouts-with-prometheus-analysis.yaml 06-argocd-application-and-rollouts.yaml
拆除
[root@ubuntu2004 rollout-demos]#kubectl delete -f 02-rollouts-with-ingress-nginx-traffic-shifting.yaml
取消所有的外部访问,不取消会产生大量的错误
部署新的示例
[root@ubuntu2004 rollout-demos]#cat 03-rollouts-with-prometheus-analysis.yaml
# CopyRight: MageEdu <[email protected]>
#
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
- name: namespace
metrics:
- name: success-rate
# NOTE: prometheus queries return results in the form of a vector.
# So it is common to access the index 0 of the returned array to obtain the value
successCondition: result[0] >= 0.95
interval: 20s
count: 5
failureLimit: 3
provider:
prometheus:
address: http://prometheus.prom.svc.cluster.local:9090
query: |
sum(irate(nginx_ingress_controller_requests{service=~"{{args.service-name}}",namespace=~"{{args.namespace}}",status!~"[4-5].*"}[1m])) /
sum(irate(nginx_ingress_controller_requests{service=~"{{args.service-name}}",namespace=~"{{args.namespace}}"}[1m]))
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-helloworld-with-traffic-shifting
spec:
replicas: 10
strategy:
canary:
analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: spring-boot-helloworld
- name: namespace
value: default
canaryService: spring-boot-helloworld-canary
stableService: spring-boot-helloworld
trafficRouting:
nginx:
stableIngress: spring-boot-helloworld
steps:
- setCanaryScale:
matchTrafficWeight: true
- setWeight: 5
- pause: {duration: 2m}
- setWeight: 10
- pause: {duration: 1m}
- setWeight: 20
- pause: {duration: 40}
- setWeight: 40
- pause: {duration: 20}
- setWeight: 60
- pause: {duration: 20}
- setWeight: 80
- pause: {duration: 20}
revisionHistoryLimit: 5
selector:
matchLabels:
app: spring-boot-helloworld
template:
metadata:
labels:
app: spring-boot-helloworld
spec:
containers:
- name: spring-boot-helloworld
image: ikubernetes/spring-boot-helloworld:v0.9.2
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 50m
livenessProbe:
httpGet:
path: '/'
port: 80
scheme: HTTP
initialDelaySeconds: 3
readinessProbe:
httpGet:
path: '/'
port: 80
scheme: HTTP
initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: spring-boot-helloworld
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: spring-boot-helloworld
---
apiVersion: v1
kind: Service
metadata:
name: spring-boot-helloworld-canary
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: spring-boot-helloworld
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-boot-helloworld
spec:
ingressClassName: "nginx"
rules:
- host: hello.magedu.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: spring-boot-helloworld
port:
number: 80
---
kubectl apply -f 03-rollouts-with-prometheus-analysis.yaml