【云原生 | Kubernetes 系列】--Gitops持续交付 Argo Rollouts Analysis

1. Argo Rollouts

由一个控制器和一组CRD组成,可为K8s提供高级部署功能

- blue-green
- canary
- canary analysis 结合外部指标系统金丝雀
- experimentation 实验性的结果
- progressive delivery 渐进式交付,精准管控外部流量策略,不用关心后端部署机制

支持Ingress Controller(Nginx和ALB)及ServiceMesh(Istio,Linkerd和SMI)集成,利用它们的流量治理能力实现流量迁移过程.

能够查询和解释来自多种指标系统(prometheus,kubernetes jobs,web,datadog等)的指标来验证blue-green或canary部署结果,并根据结果自动执行升级或回滚

几个相关的CRD

​ rollout,Analysis Template,ClusterAnalysisTemplate和AnalysisRun

基本工作机制

​ 与deployment相似,Argo Rollouts控制器借助于ReplicaSet完成应用的创建,缩放和删除

​ ReplicaSet资源由Rollout的spec.template字段定义

2. Argo Rollouts架构

Rollout Controller借助Analysis Template运行一个AnalysisRun,从而借助指标provider,生成指标分析结果.

支撑在当前Rollout上基于ReplicaSet定义的应用

如果更新的话有Canary ReplicaSet和Stable ReplicaSet子集取决于指标分析结果.

一旦部署了子集,可以借助外部的Ingress或ServiceMesh对流量比例进行分发.

也可以根据完成的进度自己定义流量的比例.

请添加图片描述

3. 部署Argo Rollouts

3.1 部署Argo Rollouts

文档

https://argoproj.github.io/argo-rollouts/installation/

初始化

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

此时会创建一组资源

# kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
customresourcedefinition.apiextensions.k8s.io/analysisruns.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/analysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/clusteranalysistemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/experiments.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/rollouts.argoproj.io created
serviceaccount/argo-rollouts created
clusterrole.rbac.authorization.k8s.io/argo-rollouts created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-admin created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-edit created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-aggregate-to-view created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts created
secret/argo-rollouts-notification-secret created
service/argo-rollouts-metrics created
deployment.apps/argo-rollouts created
# kubectl api-resources --api-group=argoproj.io
NAME                       SHORTNAMES         APIVERSION             NAMESPACED   KIND
analysisruns               ar                 argoproj.io/v1alpha1   true         AnalysisRun
analysistemplates          at                 argoproj.io/v1alpha1   true         AnalysisTemplate
applications               app,apps           argoproj.io/v1alpha1   true         Application
applicationsets            appset,appsets     argoproj.io/v1alpha1   true         ApplicationSet
appprojects                appproj,appprojs   argoproj.io/v1alpha1   true         AppProject
clusteranalysistemplates   cat                argoproj.io/v1alpha1   false        ClusterAnalysisTemplate
experiments                exp                argoproj.io/v1alpha1   true         Experiment
rollouts                   ro                 argoproj.io/v1alpha1   true         Rollout

此时会创建一个新的argo-rollouts namespace

# kubectl get pods -n argo-rollouts 
NAME                             READY   STATUS    RESTARTS   AGE
argo-rollouts-749c98cc69-f4gbc   1/1     Running   0          38s

3.2 部署Dashboard

kubectl apply -f https://github.com/argoproj/argo-rollouts/releases/download/v1.3.1/dashboard-install.yaml -n argo-rollouts
# This is an auto-generated file. DO NOT EDIT
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: argo-rollouts-dashboard
    app.kubernetes.io/name: argo-rollouts-dashboard
    app.kubernetes.io/part-of: argo-rollouts
  name: argo-rollouts-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/component: argo-rollouts-dashboard
    app.kubernetes.io/name: argo-rollouts-dashboard
    app.kubernetes.io/part-of: argo-rollouts
  name: argo-rollouts-dashboard
rules:
- apiGroups:
  - argoproj.io
  resources:
  - rollouts
  - rollouts/status
  - rollouts/finalizers
  verbs:
  - get
  - list
  - watch
  - update
  - patch
- apiGroups:
  - argoproj.io
  resources:
  - analysisruns
  - analysisruns/finalizers
  - experiments
  - experiments/finalizers
  verbs:
  - create
  - get
  - list
  - watch
- apiGroups:
  - argoproj.io
  resources:
  - analysistemplates
  - clusteranalysistemplates
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - deployments
  verbs:
  - get
  - update
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - replicasets
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/component: argo-rollouts-dashboard
    app.kubernetes.io/name: argo-rollouts-dashboard
    app.kubernetes.io/part-of: argo-rollouts
  name: argo-rollouts-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: argo-rollouts-dashboard
subjects:
- kind: ServiceAccount
  name: argo-rollouts-dashboard
  namespace: argo-rollouts
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: argo-rollouts-dashboard
    app.kubernetes.io/name: argo-rollouts-dashboard
    app.kubernetes.io/part-of: argo-rollouts
  name: argo-rollouts-dashboard
spec:
  ports:
  - port: 3100
    protocol: TCP
    targetPort: 3100
  selector:
    app.kubernetes.io/name: argo-rollouts-dashboard
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: argo-rollouts-dashboard
    app.kubernetes.io/name: argo-rollouts-dashboard
    app.kubernetes.io/part-of: argo-rollouts
  name: argo-rollouts-dashboard
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: argo-rollouts-dashboard
  template:
    metadata:
      labels:
        app.kubernetes.io/name: argo-rollouts-dashboard
    spec:
      containers:
      - image: quay.io/argoproj/kubectl-argo-rollouts:v1.3.1
        name: argo-rollouts-dashboard
        ports:
        - containerPort: 3100
      serviceAccountName: argo-rollouts-dashboard

部署dashboard

# kubectl apply -f dashboard-install.yaml -n argo-rollouts
serviceaccount/argo-rollouts-dashboard created
clusterrole.rbac.authorization.k8s.io/argo-rollouts-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/argo-rollouts-dashboard created
service/argo-rollouts-dashboard created
deployment.apps/argo-rollouts-dashboard created

配置service

---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: argo-rollouts-dashboard
  namespace: argo-rollouts
spec:
  host: argo-rollouts-dashboard
  trafficPolicy:
    tls:
      mode: DISABLE
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: argo-rollouts-dashboard-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "argo-rollouts.intra.com"
    - "rollouts.intra.com"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: argo-rollouts-dashboard-virtualservice
  namespace: argo-rollouts
spec:
  hosts:
  - "argo-rollouts.intra.com"
  - "rollouts.intra.com"
  gateways:
  - istio-system/argo-rollouts-dashboard-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: argo-rollouts-dashboard
        port:
          number: 3100
---
# kubectl apply -f 03-argo-rollouts-dashboard-virtualservice.yaml 
destinationrule.networking.istio.io/argo-rollouts-dashboard created
gateway.networking.istio.io/argo-rollouts-dashboard-gateway created
virtualservice.networking.istio.io/argo-rollouts-dashboard-virtualservice created

此时dashboard已经可以访问了,但此时没有什么内容

请添加图片描述

3.3 部署kubelet argo rollouts插件

 wget https://github.com/argoproj/argo-rollouts/releases/download/v1.3.1/kubectl-argo-rollouts-linux-amd64
 cp kubectl-argo-rollouts-linux-amd64 /usr/bin/kubectl-argo-rollouts
 chmod +x /usr/bin/kubectl-argo-rollouts

4. Rollouts CRD资源规范

Rollout的功能很大程度上和Deployment兼容,支持字段也有不少相同的.

Rollout CRD的spec字段支持使用的字段包括:

字段 含义
replicas 运行的Pod实例数量,默认为1
selector 筛选Pod对象的标签选择器
template ReplicaSet模板对象
revisionHistoryLimit 更新历史中保留的ReplicaSet Revision数量
minReadSeconds 无容器crash的情况下,新的Pod被视为可用的最短时长,默认为0,立即转为Ready
paused 是否置为暂停状态
progressDeadlineSeconds 更新过程中,更新步骤的最大等待时长,默认为600秒
progressDeadlineAbort 未使用analysis或experiment而progressDeadlineSeconds超时的情况下,是否终止更新过程,默认否
restartAt 重启Pod的时刻,其值为UTC时间戳格式
stategy 更新策略,支持canary和bluegreen两种

5. Rollout更新策略之Canary

通过spec.stategy.canary启用

支持的内嵌字段

字段 含义
canaryService 仅在canary的过程中匹配到canary的pod上,结束后就转为stableService接管
stableService 由控制器匹配来自Stable Pods上的Service
canaryMetadata 需要添加到Canary八本的Pods上的元数据,仅存在Canary更新期间,更新完成后即为Stable
stableMetadata 需要添加Stable版本Pods上的元数据
maxSurge 滚动更新中至多临时比期望Pod个数多几个
maxUnavilable 滚动更新至多中临时比期望Pod个数少几个
scaleDownDelayRevisionLimit 在旧RS上启动缩容之前,可运行着的旧RS的数量
abortScaleDownDelaySeconds 启用了trafficRouting时,因更新中止而收缩Canary版本Pod数量之前的延迟时长,默认为30s
scalDownDelay 启用trafficRouting时,缩容前一个ReplicaSet规模的延迟时长,默认为30s
analysis 在滚动更新期间后台运行的analysis
steps Canary更新期间要执行的步骤
trafficRouting 设定Ingress Controller或ServiceMesh如何动态调整配置以完成精细化地流量分割和流量迁移
antiAffinity 定义Canary Pod与旧ReplicaSet Pod之间的反亲和关系.

6. 结合Service进行Canary部署

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-spring-boot-helloworld
spec:
  replicas: 10 			# 一共创建10个pod
  strategy:
    canary:
      steps:
      - setWeight: 10 	# 第一步: 创建10%的pod即1个pods,流量也是10%
      - pause: {
    
    }		# 暂停,直到用户手动激活后续更新
      - setWeight: 20		# 创建20%的pods
      - pause: {
    
    duration: 20}	# 暂停20秒
      - setWeight: 30		# 创建30%的pods
      - pause: {
    
    duration: 20}	# 暂停20秒
      - setWeight: 40		# 创建40%的pods
      - pause: {
    
    duration: 20}	# 暂停20秒
      - setWeight: 60
      - pause: {
    
    duration: 20}
      - setWeight: 80
      - pause: {
    
    duration: 20}
  revisionHistoryLimit: 5	# 保存几个版本的更新历史
  selector:  # 当前rs的标签选择器,用来选择pods
    matchLabels:
      app: spring-boot-helloworld
  template:   # pod模板生成rs控制应用
    metadata:
      labels:
        app: spring-boot-helloworld
    spec:
      containers:
      - name: spring-boot-helloworld
        image: ikubernetes/spring-boot-helloworld:v0.9.5
        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

创建rollout

# kubectl apply -f 01-argo-rollouts-demo.yaml 
rollout.argoproj.io/rollouts-spring-boot-helloworld created
service/spring-boot-helloworld created

查看创建rollouts

# kubectl argo rollouts list rollouts
NAME                             STRATEGY   STATUS        STEP   SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-spring-boot-helloworld  Canary     Healthy       12/12  100         10/10  10       10          10
# kubectl argo rollouts get rollouts rollouts-spring-boot-helloworld 
Name:            rollouts-spring-boot-helloworld
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          12/12
  SetWeight:     100
  ActualWeight:  100
Images:          ikubernetes/spring-boot-helloworld:v0.9.5 (stable)
Replicas:
  Desired:       10
  Current:       10
  Updated:       10
  Ready:         10
  Available:     10

NAME                                                        KIND        STATUS     AGE    INFO
⟳ rollouts-spring-boot-helloworld                           Rollout     ✔ Healthy  7m54s  
└──# revision:1                                                                           
   └──⧉ rollouts-spring-boot-helloworld-96697f77d           ReplicaSet  ✔ Healthy  7m54s  stable
      ├──□ rollouts-spring-boot-helloworld-96697f77d-5xgxp  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-hrg6x  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-l6gld  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-p89ww  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-qqtvw  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-snwsk  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-sslfh  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-z8m8n  Pod         ✔ Running  7m54s  ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-jx4kp  Pod         ✔ Running  76s    ready:1/1
      └──□ rollouts-spring-boot-helloworld-96697f77d-phtqh  Pod         ✔ Running  76s    ready:1/1

手动更新,此时Canary产生一个pod,stable有9个

# kubectl argo rollouts set image rollouts-spring-boot-helloworld spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
rollout "rollouts-spring-boot-helloworld" image updated
# kubectl argo rollouts get rollouts rollouts-spring-boot-helloworld
Name:            rollouts-spring-boot-helloworld
Namespace:       default
Status:          ॥ Paused
Message:         CanaryPauseStep
Strategy:        Canary
  Step:          1/12
  SetWeight:     10
  ActualWeight:  10
Images:          ikubernetes/spring-boot-helloworld:v0.8.1 (canary)
                 ikubernetes/spring-boot-helloworld:v0.9.5 (stable)
Replicas:
  Desired:       10
  Current:       10
  Updated:       1
  Ready:         10
  Available:     10

NAME                                                         KIND        STATUS     AGE    INFO
⟳ rollouts-spring-boot-helloworld                            Rollout     ॥ Paused   13m    
├──# revision:2                                                                            
│  └──⧉ rollouts-spring-boot-helloworld-86d658cd59           ReplicaSet  ✔ Healthy  61s    canary
│     └──□ rollouts-spring-boot-helloworld-86d658cd59-mp8qt  Pod         ✔ Running  61s    ready:1/1
└──# revision:1                                                                            
   └──⧉ rollouts-spring-boot-helloworld-96697f77d            ReplicaSet  ✔ Healthy  13m    stable
      ├──□ rollouts-spring-boot-helloworld-96697f77d-5xgxp   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-hrg6x   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-l6gld   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-p89ww   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-qqtvw   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-snwsk   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-sslfh   Pod         ✔ Running  13m    ready:1/1
      ├──□ rollouts-spring-boot-helloworld-96697f77d-z8m8n   Pod         ✔ Running  13m    ready:1/1
      └──□ rollouts-spring-boot-helloworld-96697f77d-jx4kp   Pod         ✔ Running  6m37s  ready:1/1

此时有10%的pod部署为新版本,同时更新处于暂停状态,需要手动继续

请添加图片描述

启动一个容器测试下流量分发,可以看到10%的流量会到0.8.1的版本上.这和我们期望是符合的

# kubectl run client --image ikubernetes/admin-box:v1.2 --rm -it --restart=Never --command -- /bin/bash
# for i in {1..10};do curl spring-boot-helloworld/version;sleep 1 ;done
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5

这里需要手动触发下继续更新

root@k8s-master-01:~# kubectl argo rollouts list rollouts
NAME                             STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-spring-boot-helloworld  Canary     Paused        1/12  10          10/10  10       1           10       
root@k8s-master-01:~# kubectl argo rollouts promote rollouts-spring-boot-helloworld
rollout 'rollouts-spring-boot-helloworld' promoted
root@k8s-master-01:~# kubectl argo rollouts list rollouts
NAME                             STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-spring-boot-helloworld  Canary     Progressing   2/12  20          9/10   10       2           9 

请添加图片描述

当80%时流量也会以2:8的比例进行转发

[root@client /]# for i in {1..10};do curl spring-boot-helloworld/version;sleep 1 ;done
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.9.5
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1

7. 借助Istio进行流量进准管理

先给default命名空间打label,让流量受istio管控

kubectl label namespace default istio-injection=enabled
## 获取镜像
docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/istio:grafana
docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/istio:kiali
docker pull docker.io/jaegertracing/all-in-one:1.29
docker pull jimmidyson/configmap-reload:v0.5.0
docker pull prom/prometheus:v2.31.1
docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/istio:grafana harbor.intra.com/istio/grafana:8.3.1
docker tag docker.io/jaegertracing/all-in-one:1.29 harbor.intra.com/istio/all-in-one:1.29
docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/istio:kiali harbor.intra.com/istio/kiali:v1.45
docker tag jimmidyson/configmap-reload:v0.5.0 harbor.intra.com/istio/configmap-reload:v0.5.0
docker tag prom/prometheus:v2.31.1 harbor.intra.com/istio/prometheus:v2.31.1
docker push harbor.intra.com/istio/grafana:8.3.1
docker push harbor.intra.com/istio/all-in-one:1.29
docker push harbor.intra.com/istio/kiali:v1.45
docker push harbor.intra.com/istio/configmap-reload:v0.5.0
docker push harbor.intra.com/istio/prometheus:v2.31.1
sed -i 's#image: "grafana/grafana:8.3.1"#image: "harbor.intra.com/istio/grafana:8.3.1"#g' grafana.yaml
sed -i 's#docker.io/jaegertracing#harbor.intra.com/istio#g' /apps/istio/samples/addons/jaeger.yaml
sed -i 's#quay.io/kiali#harbor.intra.com/istio#g' /apps/istio/samples/addons/kiali.yaml
sed -i 's#jimmidyson/#harbor.intra.com/istio/#g' /apps/istio/samples/addons/prometheus.yaml
sed -i 's#prom/#harbor.intra.com/istio/#g' /apps/istio/samples/addons/prometheus.yaml

## 部署istio的addons
# kubectl apply -f /apps/istio/samples/addons/
serviceaccount/grafana created
configmap/grafana created
service/grafana created
deployment.apps/grafana created
configmap/istio-grafana-dashboards created
configmap/istio-services-grafana-dashboards created
deployment.apps/jaeger created
service/tracing created
service/zipkin created
service/jaeger-collector created
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer unchanged
clusterrole.rbac.authorization.k8s.io/kiali unchanged
clusterrolebinding.rbac.authorization.k8s.io/kiali unchanged
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
serviceaccount/prometheus created
configmap/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus unchanged
clusterrolebinding.rbac.authorization.k8s.io/prometheus unchanged
service/prometheus created
deployment.apps/prometheus created
# kubectl get pods -n istio-system 
NAME                                   READY   STATUS    RESTARTS      AGE
grafana-6f8f6f8947-h6f8m               1/1     Running   0             10s
istio-egressgateway-5c597cdb77-j7jjj   1/1     Running   0             5h25m
istio-ingressgateway-8d7d49b55-q6rf4   1/1     Running   0             5h25m
istiod-54c54679d7-f4n6l                1/1     Running   8 (29h ago)   20d
jaeger-7594596fbf-xkh2c                1/1     Running   0             10m
kiali-7d9474d464-p4k8d                 1/1     Running   0             10m
prometheus-64968bc5fd-6465f            2/2     Running   0             10m

部署sleep容器

# kubectl apply -f /apps/istio/samples/sleep/sleep.yaml 
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
# kubectl get pods
NAME                                        READY   STATUS    RESTARTS       AGE
el-gitlab-event-listener-75497dbb79-nctzm   2/2     Running   1 (111s ago)   113s
el-s2i-listener-7c78cc48c-h9xzs             2/2     Running   1 (105s ago)   107s
sleep-557747455f-74fzr                      2/2     Running   0              27s
# kubectl exec -it sleep-557747455f-74fzr /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ $ 
/ $ 
/ $ 
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-helloworld-with-traffic-shifting
spec:
  replicas: 10 
  strategy:
    canary:
      trafficRouting:		# 结合istio的vs
        istio:
          virtualService: 
            name: helloworld-rollout-vsvc        # vitrualservice name
            routes:
            - primary                 # 路由名称primary,由他管控
          destinationRule:		# 与那些pod进行关联
            name: helloworld-rollout-destrule    # required
            canarySubsetName: canary  # required
            stableSubsetName: stable  # required
      steps:
      - setCanaryScale:
          matchTrafficWeight: true
      - setWeight: 5		# 最少1个pod最少5%的流量
      - pause: {
    
    duration: 1m}
      - setWeight: 10
      - pause: {
    
    duration: 1m}
      - pause: {
    
    duration: 20}
      - 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.8.0
        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: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld-rollout-vsvc
spec:
  #gateways:
  #- istio-rollout-gateway
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary       # referenced in canary.trafficRouting.istio.virtualService.routes
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable  # referenced in canary.trafficRouting.istio.destinationRule.stableSubsetName
      weight: 100
    - destination:
        host: spring-boot-helloworld
        subset: canary  # referenced in canary.trafficRouting.istio.destinationRule.canarySubsetName
      weight: 0
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld-rollout-destrule
spec:
  host: spring-boot-helloworld # 对spring-boot-helloworld服务下的所有pod做了子集分类.
  subsets:
  - name: canary   # referenced in canary.trafficRouting.istio.destinationRule.canarySubsetName
    labels:        # labels will be injected with canary rollouts-pod-template-hash value
      app: spring-boot-helloworld
  - name: stable   # referenced in canary.trafficRouting.istio.destinationRule.stableSubsetName
    labels:        # labels will be injected with stable rollouts-pod-template-hash value
      app: spring-boot-helloworld
---

部署

# kubectl apply -f 02-argo-rollouts-with-istio-traffic-shifting.yaml 
rollout.argoproj.io/rollouts-helloworld-with-traffic-shifting created
service/spring-boot-helloworld created
virtualservice.networking.istio.io/helloworld-rollout-vsvc created
destinationrule.networking.istio.io/helloworld-rollout-destrule created

此时10个pods被创建,每个pods都被注入了一个container sidecar.这样就能被istio管控.流量就被网格所治理.

# kubectl get pods 
NAME                                                         READY   STATUS    RESTARTS        AGE
el-gitlab-event-listener-75497dbb79-nctzm                    2/2     Running   1 (6m2s ago)    6m4s
el-s2i-listener-7c78cc48c-h9xzs                              2/2     Running   1 (5m56s ago)   5m58s
rollouts-helloworld-with-traffic-shifting-7f99964998-4lq2p   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-h6bxx   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-hj65v   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-mfxlc   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-n2vps   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-qrnxd   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-tzpv9   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-vrdjd   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-z7h47   2/2     Running   0               113s
rollouts-helloworld-with-traffic-shifting-7f99964998-zjbdq   2/2     Running   0               113s
sleep-557747455f-74fzr  
2/2     Running   0               4m38s
# kubectl get svc
NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
ehelp-service                       NodePort    10.200.22.255    <none>        8080:30040/TCP                  22d
el-gitlab-event-listener            ClusterIP   10.200.148.23    <none>        8080/TCP,9000/TCP               14d
el-gitlab-event-listener-nodeport   NodePort    10.200.84.202    <none>        8080:30088/TCP,9000:30089/TCP   15d
el-s2i-listener                     ClusterIP   10.200.138.9     <none>        8080/TCP,9000/TCP               14d
kubernetes                          ClusterIP   10.200.0.1       <none>        443/TCP                         210d
sleep                               ClusterIP   10.200.204.186   <none>        80/TCP                          6m7s
spring-boot-helloworld              ClusterIP   10.200.158.73    <none>        80/TCP                          3m22s
# 此时所有流量都在v0.8.0上
/ $ while true;do curl spring-boot-helloworld.default.svc/version;sleep 1;done
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
# kubectl argo rollouts get rollouts rollouts-helloworld-with-traffic-shifting
Name:            rollouts-helloworld-with-traffic-shifting
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          14/14
  SetWeight:     100
  ActualWeight:  100
Images:          ikubernetes/spring-boot-helloworld:v0.8.0 (stable)
Replicas:
  Desired:       10
  Current:       10
  Updated:       10
  Ready:         10
  Available:     10

NAME                                                                   KIND        STATUS     AGE    INFO
⟳ rollouts-helloworld-with-traffic-shifting                            Rollout     ✔ Healthy  7m24s  
└──# revision:1                                                                                      
   └──⧉ rollouts-helloworld-with-traffic-shifting-7f99964998           ReplicaSet  ✔ Healthy  7m23s  stable
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-4lq2p  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-h6bxx  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-hj65v  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-mfxlc  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-n2vps  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-qrnxd  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-tzpv9  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-vrdjd  Pod         ✔ Running  7m23s  ready:2/2
      ├──□ rollouts-helloworld-with-traffic-shifting-7f99964998-z7h47  Pod         ✔ Running  7m23s  ready:2/2
      └──□ rollouts-helloworld-with-traffic-shifting-7f99964998-zjbdq  Pod         ✔ Running  7m23s  ready:2/2

将镜像升级到v0.8.1

# kubectl argo rollouts set image rollouts-helloworld-with-traffic-shifting spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
rollout "rollouts-helloworld-with-traffic-shifting" image updated

此时新pod占比1/10,新版本流量占比5%

/ $ while true;do curl spring-boot-helloworld.default.svc/version;sleep 1;done
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
# kubectl get vs helloworld-rollout-vsvc 
NAME                      GATEWAYS   HOSTS                        AGE
helloworld-rollout-vsvc              ["spring-boot-helloworld"]   14m

每一个step完成都会将流量切换

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {
    
    "apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{
    
    "annotations":{
    
    },"name":"helloworld-rollout-vsvc","namespace":"default"},"spec":{
    
    "hosts":["spring-boot-helloworld"],"http":[{
    
    "name":"primary","route":[{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"stable"},"weight":100},{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"canary"},"weight":0}]}]}}
  creationTimestamp: "2022-11-23T06:34:14Z"
  generation: 10
  name: helloworld-rollout-vsvc
  namespace: default
  resourceVersion: "7132327"
  uid: 7ba7c0f8-45fe-4a8c-a549-39522d3dc835
spec:
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable
      weight: 95
    - destination:
        host: spring-boot-helloworld
        subset: canary
      weight: 5
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {
    
    "apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{
    
    "annotations":{
    
    },"name":"helloworld-rollout-vsvc","namespace":"default"},"spec":{
    
    "hosts":["spring-boot-helloworld"],"http":[{
    
    "name":"primary","route":[{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"stable"},"weight":100},{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"canary"},"weight":0}]}]}}
  creationTimestamp: "2022-11-23T06:34:14Z"
  generation: 11
  name: helloworld-rollout-vsvc
  namespace: default
  resourceVersion: "7132597"
  uid: 7ba7c0f8-45fe-4a8c-a549-39522d3dc835
spec:
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable
      weight: 90
    - destination:
        host: spring-boot-helloworld
        subset: canary
      weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {
    
    "apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{
    
    "annotations":{
    
    },"name":"helloworld-rollout-vsvc","namespace":"default"},"spec":{
    
    "hosts":["spring-boot-helloworld"],"http":[{
    
    "name":"primary","route":[{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"stable"},"weight":100},{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"canary"},"weight":0}]}]}}
  creationTimestamp: "2022-11-23T06:34:14Z"
  generation: 12
  name: helloworld-rollout-vsvc
  namespace: default
  resourceVersion: "7133039"
  uid: 7ba7c0f8-45fe-4a8c-a549-39522d3dc835
spec:
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable
      weight: 80
    - destination:
        host: spring-boot-helloworld
        subset: canary
      weight: 20
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {
    
    "apiVersion":"networking.istio.io/v1beta1","kind":"VirtualService","metadata":{
    
    "annotations":{
    
    },"name":"helloworld-rollout-vsvc","namespace":"default"},"spec":{
    
    "hosts":["spring-boot-helloworld"],"http":[{
    
    "name":"primary","route":[{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"stable"},"weight":100},{
    
    "destination":{
    
    "host":"spring-boot-helloworld","subset":"canary"},"weight":0}]}]}}
  creationTimestamp: "2022-11-23T06:34:14Z"
  generation: 13
  name: helloworld-rollout-vsvc
  namespace: default
  resourceVersion: "7133319"
  uid: 7ba7c0f8-45fe-4a8c-a549-39522d3dc835
spec:
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable
      weight: 60
    - destination:
        host: spring-boot-helloworld
        subset: canary
      weight: 40

全部完成后,流量就变成了100:0.新版本就变成了stable.然后等待下一次的更新

此时就可以看到Revision

请添加图片描述

8. Analysis的Canary

8.1 先打开prometheus的dashboard

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: prometheus
  namespace: istio-system
spec:
  host: prometheus
  trafficPolicy:
    tls:
      mode: DISABLE
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: prometheus-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "prometheus.intra.com"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: prometheus-virtualservice
  namespace: istio-system
spec:
  hosts:
  - "prometheus.intra.com"
  gateways:
  - prometheus-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: prometheus
        port:
          number: 9090
---
kubectl apply -f /apps/istio-in-practise/Traffic-Management-Basics/prometheus/

hosts解析prometheus.intra.com域名后就能通过页面进行访问prometheus

请添加图片描述

8.2 基于监控数据滚动更新

基于AnalysisTemplate实例化AnalysisRun

---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
  - name: service-name		# 参数,给他传哪个service的名字就查哪个service的成功率
  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	# 返回值大于95%的流量都成功(非5xx)
    interval: 20s # 间隔20秒查一次
    #count: 3
    failureLimit: 3		# 如果3次都失败就不再查了
    provider:
      prometheus:	# MetricsProvider访问入口,即addons部署的prometheus的访问入口,这里要确保prometuesu的svc能够访问到
        address: http://prometheus.istio-system.svc.cluster.local:9090
        query: |		# 底下的就是查询语句部分,这个值和之前successCondition设置的值做对比
          sum(irate(
            istio_requests_total{
    
    reporter="source",destination_service=~"{
    
    {
    
    args.service-name}}",response_code!~"5.*"}[1m]
          )) / 
          sum(irate(
            istio_requests_total{
    
    reporter="source",destination_service=~"{
    
    {
    
    args.service-name}}"}[1m]
          ))
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollouts-helloworld-with-analysis
spec:
  replicas: 10 
  strategy:
    canary:
      trafficRouting:
        istio:
          virtualService: 
            name: helloworld-rollout-vsvc
            routes:
            - primary
          destinationRule:
            name: helloworld-rollout-destrule
            canarySubsetName: canary
            stableSubsetName: stable
      analysis:	# 调用之前定义的success-rate
        templates:
        - templateName: success-rate
        args:
        - name: service-name
          # change this value to your service name
          value: spring-boot-helloworld.demo.svc.cluster.local  # 将这个值传给service-name,这里的svc是错误的,我们并没有demo这个命名空间,所以健康检查就会失败,最终导致更新失败.这里要确保服务的svc能够访问到
        startingStep: 2
      steps:
      - setWeight: 5
      - pause: {
    
    duration: 1m}
      - setWeight: 10
      - pause: {
    
    duration: 1m}
      - setWeight: 30
      - pause: {
    
    duration: 1m}
      - setWeight: 60
      - pause: {
    
    duration: 1m}
  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.8.0
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        resources:
          requests:
            memory: 32Mi
            cpu: 50m
        livenessProbe:
          httpGet:
            path: '/'
            port: 80
            scheme: HTTP
        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: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld-rollout-vsvc
spec:
  #gateways:
  #- istio-rollout-gateway
  hosts:
  - spring-boot-helloworld
  http:
  - name: primary
    route:
    - destination:
        host: spring-boot-helloworld
        subset: stable
      weight: 100
    - destination:
        host: spring-boot-helloworld
        subset: canary
      weight: 0
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: helloworld-rollout-destrule
spec:
  host: spring-boot-helloworld
  subsets:
  - name: canary
    labels:
      app: spring-boot-helloworld
  - name: stable
    labels:
      app: spring-boot-helloworld
---

部署服务

# kubectl apply -f 03-argo-rollouts-with-analysis.yaml

部署一个容器访问服务

# # kubectl run --rm -it centos7 --image=centos:7.9.2009 -- bash
# curl spring-boot-helloworld.default.svc.magedu.local/version
Spring Boot Helloworld, Version 0.8.0
# 同时确保prometheus可以被访问
# curl prometheus.istio-system.svc.magedu.local:9090/graph

# 跑个循环,持续访问这个域名
# while true;do curl spring-boot-helloworld.default.svc.magedu.local/version;sleep 0.5;done
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0

此时执行更新会因为错误的健康检查而失败,最终回滚版本

# kubectl argo rollouts list rollouts
NAME                                       STRATEGY   STATUS        STEP   SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-helloworld-with-analysis          Canary     Healthy       8/8    100         10/10  10       10          10       
rollouts-helloworld-with-traffic-shifting  Canary     Healthy       14/14  100         10/10  10       10          10 
# kubectl argo rollouts set image rollouts-helloworld-with-analysis spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
Message:         RolloutAborted: Rollout aborted update to revision 2: Metric "success-rate" assessed Error due to consecutiveErrors (5) > consecutiveErrorLimit (4): "Error Message: Post "http://prometheus.istio-system.svc.cluster.local:9090/api/v1/query": dial tcp: lookup prometheus.istio-system.svc.cluster.local on 10.200.0.2:53: no such host"
Strategy:        Canary
  Step:          0/8
  SetWeight:     0
  ActualWeight:  0
Images:          ikubernetes/spring-boot-helloworld:v0.9.5 (stable)
Replicas:
  Desired:       10
  Current:       10
  Updated:       0
  Ready:         10
  Available:     10

NAME                                                           KIND         STATUS        AGE   INFO
⟳ rollouts-helloworld-with-analysis                            Rollout      ✖ Degraded    21m   
├──# revision:2                                                                                 
│  ├──⧉ rollouts-helloworld-with-analysis-66d7899686           ReplicaSet   • ScaledDown  3m1s  canary,delay:passed
│  └──α rollouts-helloworld-with-analysis-66d7899686-2         AnalysisRun  ⚠ Error       111s  ⚠ 5
└──# revision:1                                                                                 
   └──⧉ rollouts-helloworld-with-analysis-855d65c8f5           ReplicaSet   ✔ Healthy     21m   stable
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-6nzmn  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-mpclh  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-n7gzf  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-qlc2t  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-rlg4d  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-t8qlc  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-tqlzt  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-d8vdr  Pod          ✔ Running     21m   ready:2/2
      ├──□ rollouts-helloworld-with-analysis-855d65c8f5-4gll4  Pod          ✔ Running     14m   ready:2/2
      └──□ rollouts-helloworld-with-analysis-855d65c8f5-rzsn6  Pod          ✔ Running     14m   ready:2/2
# kubectl get analysisTemplates
NAME           AGE
success-rate   22m
# kubectl get analysisRun
NAME                                             STATUS   AGE
rollouts-helloworld-with-analysis-66d7899686-2   Error    3m20s

请添加图片描述

此时这个rollouts处于降级状态.执行回滚

# kubectl argo rollouts list rollouts
NAME                                       STRATEGY   STATUS        STEP   SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-helloworld-with-analysis          Canary     Degraded      0/8    0           10/10  10       0           10       
rollouts-helloworld-with-traffic-shifting  Canary     Healthy       14/14  100         10/10  10       10          10       
# kubectl argo rollouts undo rollouts-helloworld-with-analysis
rollout 'rollouts-helloworld-with-analysis' undo

此时rollouts就被回滚回去了

# kubectl argo rollouts list rollouts
NAME                                       STRATEGY   STATUS        STEP   SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollouts-helloworld-with-analysis          Canary     Healthy       8/8    100         10/10  10       10          10       
rollouts-helloworld-with-traffic-shifting  Canary     Healthy       14/14  100         10/10  10       10          10   

请添加图片描述

回滚之后Revision就变成了3

Name:            rollouts-helloworld-with-analysis
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          ikubernetes/spring-boot-helloworld:v0.9.5 (stable)
Replicas:
  Desired:       10
  Current:       10
  Updated:       10
  Ready:         10
  Available:     10

NAME                                                           KIND         STATUS        AGE  INFO
⟳ rollouts-helloworld-with-analysis                            Rollout      ✔ Healthy     46m  
├──# revision:3                                                                                
│  └──⧉ rollouts-helloworld-with-analysis-855d65c8f5           ReplicaSet   ✔ Healthy     46m  stable
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-6nzmn  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-mpclh  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-n7gzf  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-qlc2t  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-rlg4d  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-t8qlc  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-tqlzt  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-d8vdr  Pod          ✔ Running     46m  ready:2/2
│     ├──□ rollouts-helloworld-with-analysis-855d65c8f5-4gll4  Pod          ✔ Running     39m  ready:2/2
│     └──□ rollouts-helloworld-with-analysis-855d65c8f5-rzsn6  Pod          ✔ Running     39m  ready:2/2
└──# revision:2                                                                                
   ├──⧉ rollouts-helloworld-with-analysis-66d7899686           ReplicaSet   • ScaledDown  28m  delay:passed
   └──α rollouts-helloworld-with-analysis-66d7899686-2         AnalysisRun  ⚠ Error       26m  ⚠ 5

将错误修改

value: spring-boot-helloworld.default.svc.cluster.local

再次部署服务

# kubectl apply -f 03-argo-rollouts-with-analysis.yaml

再次更新image版本

# kubectl argo rollouts set image rollouts-helloworld-with-analysis spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
rollout "rollouts-helloworld-with-analysis" image updated
NAME                                                           KIND         STATUS         AGE    INFO
⟳ rollouts-helloworld-with-analysis                            Rollout      ◌ Progressing  8m49s  
├──# revision:2                                                                                   
│  ├──⧉ rollouts-helloworld-with-analysis-66d7899686           ReplicaSet   ◌ Progressing  4m47s  canary
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-pt2p7  Pod          ✔ Running      4m47s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-kt4nm  Pod          ✔ Running      2m38s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-z28xx  Pod          ✔ Running      2m38s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-8lqss  Pod          ✔ Running      88s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-p8wgq  Pod          ✔ Running      88s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-qdd6t  Pod          ✔ Running      88s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-sh9c9  Pod          ✔ Running      18s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-2qmqd  Pod          ✔ Running      17s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-bbkfj  Pod          ✔ Running      17s    ready:2/2
│  │  └──□ rollouts-helloworld-with-analysis-66d7899686-dhwlc  Pod          ✔ Running      17s    ready:1/2
│  └──α rollouts-helloworld-with-analysis-66d7899686-2         AnalysisRun  ◌ Running      3m38s  ✔ 11
└──# revision:1                                                                                   
   └──⧉ rollouts-helloworld-with-analysis-5fccd797cf           ReplicaSet   ✔ Healthy      8m48s  stable
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-47zp2  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-5bhqp  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-8r4cv  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-9qpcp  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-9vnvr  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-crmrl  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-hft2p  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-jl59t  Pod          ✔ Running      8m48s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-phkgp  Pod          ✔ Running      8m48s  ready:2/2
      └──□ rollouts-helloworld-with-analysis-5fccd797cf-vmsch  Pod          ✔ Running      8m48s  ready:2/2



NAME                                                           KIND         STATUS         AGE    INFO
⟳ rollouts-helloworld-with-analysis                            Rollout      ✔ Healthy      9m25s  
├──# revision:2                                                                                   
│  ├──⧉ rollouts-helloworld-with-analysis-66d7899686           ReplicaSet   ✔ Healthy      5m23s  stable
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-pt2p7  Pod          ✔ Running      5m23s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-kt4nm  Pod          ✔ Running      3m14s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-z28xx  Pod          ✔ Running      3m14s  ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-8lqss  Pod          ✔ Running      2m4s   ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-p8wgq  Pod          ✔ Running      2m4s   ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-qdd6t  Pod          ✔ Running      2m4s   ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-sh9c9  Pod          ✔ Running      54s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-2qmqd  Pod          ✔ Running      53s    ready:2/2
│  │  ├──□ rollouts-helloworld-with-analysis-66d7899686-bbkfj  Pod          ✔ Running      53s    ready:2/2
│  │  └──□ rollouts-helloworld-with-analysis-66d7899686-dhwlc  Pod          ✔ Running      53s    ready:2/2
│  └──α rollouts-helloworld-with-analysis-66d7899686-2         AnalysisRun  ✔ Successful   4m14s  ✔ 12
└──# revision:1                                                                                   
   └──⧉ rollouts-helloworld-with-analysis-5fccd797cf           ReplicaSet   • ScaledDown   9m24s  
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-47zp2  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-5bhqp  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-8r4cv  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-9qpcp  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-9vnvr  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-crmrl  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-hft2p  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-jl59t  Pod          ◌ Terminating  9m24s  ready:2/2
      ├──□ rollouts-helloworld-with-analysis-5fccd797cf-phkgp  Pod          ◌ Terminating  9m24s  ready:2/2
      └──□ rollouts-helloworld-with-analysis-5fccd797cf-vmsch  Pod          ◌ Terminating  9m24s  ready:2/2

当新版本完成部署后旧的pod会被自动删除

root@k8s-master-01:~# kubectl get pods
NAME                                                 READY   STATUS    RESTARTS       AGE
centos7                                              2/2     Running   0              5m49s
el-gitlab-event-listener-75497dbb79-kpjmj            2/2     Running   18 (16m ago)   21h
el-s2i-listener-7c78cc48c-tvtpq                      2/2     Running   17 (16m ago)   21h
rollouts-helloworld-with-analysis-5fccd797cf-47zp2   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-5bhqp   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-8r4cv   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-9qpcp   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-9vnvr   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-crmrl   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-hft2p   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-jl59t   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-phkgp   2/2     Running   0              8m
rollouts-helloworld-with-analysis-5fccd797cf-vmsch   2/2     Running   0              8m
rollouts-helloworld-with-analysis-66d7899686-8lqss   2/2     Running   0              40s
rollouts-helloworld-with-analysis-66d7899686-kt4nm   2/2     Running   0              110s
rollouts-helloworld-with-analysis-66d7899686-p8wgq   2/2     Running   0              40s
rollouts-helloworld-with-analysis-66d7899686-pt2p7   2/2     Running   0              3m59s
rollouts-helloworld-with-analysis-66d7899686-qdd6t   2/2     Running   0              40s
rollouts-helloworld-with-analysis-66d7899686-z28xx   2/2     Running   0              110s
sleep-557747455f-mvgbb                               2/2     Running   4 (18m ago)    21h
root@k8s-master-01:~# kubectl get pods
NAME                                                 READY   STATUS    RESTARTS       AGE
centos7                                              2/2     Running   0              7m29s
el-gitlab-event-listener-75497dbb79-kpjmj            2/2     Running   18 (18m ago)   21h
el-s2i-listener-7c78cc48c-tvtpq                      2/2     Running   17 (18m ago)   21h
rollouts-helloworld-with-analysis-66d7899686-2qmqd   2/2     Running   0              69s
rollouts-helloworld-with-analysis-66d7899686-8lqss   2/2     Running   0              2m20s
rollouts-helloworld-with-analysis-66d7899686-bbkfj   2/2     Running   0              69s
rollouts-helloworld-with-analysis-66d7899686-dhwlc   2/2     Running   0              69s
rollouts-helloworld-with-analysis-66d7899686-kt4nm   2/2     Running   0              3m30s
rollouts-helloworld-with-analysis-66d7899686-p8wgq   2/2     Running   0              2m20s
rollouts-helloworld-with-analysis-66d7899686-pt2p7   2/2     Running   0              5m39s
rollouts-helloworld-with-analysis-66d7899686-qdd6t   2/2     Running   0              2m20s
rollouts-helloworld-with-analysis-66d7899686-sh9c9   2/2     Running   0              70s
rollouts-helloworld-with-analysis-66d7899686-z28xx   2/2     Running   0              3m30s
sleep-557747455f-mvgbb                               2/2     Running   4 (20m ago)    21h

请添加图片描述

此时while循环里可以看到版本已经升级到了Version 0.8.1

Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
upstream connect error or disconnect/reset before headers. reset reason: connection terminationupstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: delayed connect error: 111Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1

9. 蓝绿部署

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-helloworld-bluegreen
spec:
  replicas: 3
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: rollout-helloworld-bluegreen
  template:
    metadata:
      labels:
        app: rollout-helloworld-bluegreen
    spec:
      containers:
      - name: spring-boot-helloworld
        image: ikubernetes/spring-boot-helloworld:v0.8.0
        ports:
        - containerPort: 80
  strategy:
    blueGreen: 
      activeService: spring-boot-helloworld	# 稳定版,正常调度流量
      previewService: spring-boot-helloworld-preview # 绿版自动创建,在蓝绿更新之外是不处理流量的
      autoPromotionEnabled: false
---
kind: Service
apiVersion: v1
metadata:
  name: spring-boot-helloworld
spec:
  selector:
    app: rollout-helloworld-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
kind: Service
apiVersion: v1
metadata:
  name: spring-boot-helloworld-preview
spec:
  selector:
    app: rollout-helloworld-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

部署

# kubectl apply -f 05-argo-rollouts-bluegreen-demo.yaml 
rollout.argoproj.io/rollout-helloworld-bluegreen created
service/spring-boot-helloworld created
service/spring-boot-helloworld-preview created

请添加图片描述

# kubectl argo rollouts list rollouts
NAME                          STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollout-helloworld-bluegreen  BlueGreen  Healthy       -     -           3/3    3        3           3 
# kubectl argo rollouts get rollouts rollout-helloworld-bluegreen -w
Name:            rollout-helloworld-bluegreen
Namespace:       default
Status:          ✔ Healthy
Strategy:        BlueGreen
Images:          ikubernetes/spring-boot-helloworld:v0.8.0 (stable, active)
Replicas:
  Desired:       3
  Current:       3
  Updated:       3
  Ready:         3
  Available:     3

NAME                                                      KIND        STATUS     AGE    INFO
⟳ rollout-helloworld-bluegreen                            Rollout     ✔ Healthy  3m15s  
└──# revision:1                                                                         
   └──⧉ rollout-helloworld-bluegreen-75954f68f5           ReplicaSet  ✔ Healthy  2m55s  stable,active
      ├──□ rollout-helloworld-bluegreen-75954f68f5-87m74  Pod         ✔ Running  2m55s  ready:2/2
      ├──□ rollout-helloworld-bluegreen-75954f68f5-dr84b  Pod         ✔ Running  2m55s  ready:2/2
      └──□ rollout-helloworld-bluegreen-75954f68f5-zrcsj  Pod         ✔ Running  2m55s  ready:2/2

更新镜像

# kubectl argo rollouts set image rollout-helloworld-bluegreen spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
rollout "rollout-helloworld-bluegreen" image updated
Name:            rollout-helloworld-bluegreen
Namespace:       default
Status:          ॥ Paused
Message:         BlueGreenPause
Strategy:        BlueGreen
Images:          ikubernetes/spring-boot-helloworld:v0.8.0 (stable, active)
                 ikubernetes/spring-boot-helloworld:v0.8.1 (preview)
Replicas:
  Desired:       3
  Current:       6
  Updated:       3
  Ready:         3
  Available:     3

NAME                                                      KIND        STATUS     AGE    INFO
⟳ rollout-helloworld-bluegreen                            Rollout     ॥ Paused   7m34s  
├──# revision:2                                                                         
│  └──⧉ rollout-helloworld-bluegreen-6bb44b6c8d           ReplicaSet  ✔ Healthy  10s    preview
│     ├──□ rollout-helloworld-bluegreen-6bb44b6c8d-ktjxd  Pod         ✔ Running  10s    ready:2/2
│     ├──□ rollout-helloworld-bluegreen-6bb44b6c8d-pnvlq  Pod         ✔ Running  10s    ready:2/2
│     └──□ rollout-helloworld-bluegreen-6bb44b6c8d-vlbxh  Pod         ✔ Running  10s    ready:2/2
└──# revision:1                                                                         
   └──⧉ rollout-helloworld-bluegreen-75954f68f5           ReplicaSet  ✔ Healthy  7m14s  stable,active
      ├──□ rollout-helloworld-bluegreen-75954f68f5-87m74  Pod         ✔ Running  7m14s  ready:2/2
      ├──□ rollout-helloworld-bluegreen-75954f68f5-dr84b  Pod         ✔ Running  7m14s  ready:2/2
      └──□ rollout-helloworld-bluegreen-75954f68f5-zrcsj  Pod         ✔ Running  7m14s  ready:2/2

请添加图片描述

此时所有流量任然是0.8.0

Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0

继续完成后面的步骤,完成流量的迁移

# kubectl argo rollouts promote rollout-helloworld-bluegreen
rollout 'rollout-helloworld-bluegreen' promoted

当执行完流量全部切换成了0.8.1

Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1

如果此时发现有问题,需要将流量切换回0.8.0

# kubectl argo rollouts undo rollout-helloworld-bluegreen
rollout 'rollout-helloworld-bluegreen' undo

但此时流量任然不会自动迁移

# kubectl argo rollouts promote rollout-helloworld-bluegreen
rollout 'rollout-helloworld-bluegreen' promoted

当再次执行promoted流量又回到了0.8.0

Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0
Spring Boot Helloworld, Version 0.8.0

请添加图片描述

10. Analysis 的bule-green

---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
  - name: service-name
  metrics:
  - name: success-rate
    successCondition: result[0] >= 0.95
    interval: 20s 
    count: 5
    failureLimit: 5
    provider:
      prometheus:
        address: http://prometheus.istio-system.svc.magedu.local:9090
        query: |
          sum(irate(
            istio_requests_total{reporter="source",destination_service=~"{
    
    {args.service-name}}",response_code!~"5.*"}[1m]
          )) / 
          sum(irate(
            istio_requests_total{reporter="source",destination_service=~"{
    
    {args.service-name}}"}[1m]
          ))
---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-helloworld-bluegreen-with-analysis
spec:
  replicas: 3
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: rollout-helloworld-bluegreen
  template:
    metadata:
      labels:
        app: rollout-helloworld-bluegreen
    spec:
      containers:
      - name: spring-boot-helloworld
        image: ikubernetes/spring-boot-helloworld:v0.8.0
        ports:
        - containerPort: 80
  strategy:
    blueGreen: 
      activeService: spring-boot-helloworld
      previewService: spring-boot-helloworld-preview
      prePromotionAnalysis: 
        templates:
        - templateName: success-rate
        args:
        - name: service-name	# 检查新版的
          value: spring-boot-helloworld.default.svc.magedu.local
      postPromotionAnalysis:
        templates:
        - templateName: success-rate
        args:
        - name: service-name	# 检查当前stable版本的
          value: spring-boot-helloworld.default.svc.magedu.local
      autoPromotionEnabled: true
---
kind: Service
apiVersion: v1
metadata:
  name: spring-boot-helloworld
spec:
  selector:
    app: rollout-helloworld-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: spring-boot-helloworld-preview
spec:
  selector:
    app: rollout-helloworld-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

部署

# kubectl apply -f 06-argo-rollouts-bluegreen-with-analysis.yaml 
analysistemplate.argoproj.io/success-rate created
rollout.argoproj.io/rollout-helloworld-bluegreen-with-analysis created
service/spring-boot-helloworld created
service/spring-boot-helloworld-preview created
# kubectl argo rollouts list rollouts
NAME                                        STRATEGY   STATUS        STEP  SET-WEIGHT  READY  DESIRED  UP-TO-DATE  AVAILABLE
rollout-helloworld-bluegreen-with-analysis  BlueGreen  Healthy       -     -           3/3    3        3           3 
# kubectl argo rollouts get rollouts rollout-helloworld-bluegreen-with-analysis -w
Name:            rollout-helloworld-bluegreen-with-analysis
Namespace:       default
Status:          ✔ Healthy
Strategy:        BlueGreen
Images:          ikubernetes/spring-boot-helloworld:v0.8.0 (stable, active)
Replicas:
  Desired:       3
  Current:       3
  Updated:       3
  Ready:         3
  Available:     3

NAME                                                                    KIND        STATUS     AGE  INFO
⟳ rollout-helloworld-bluegreen-with-analysis                            Rollout     ✔ Healthy  96m  
└──# revision:1                                                                                     
   └──⧉ rollout-helloworld-bluegreen-with-analysis-75954f68f5           ReplicaSet  ✔ Healthy  95m  stable,active
      ├──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-brhzq  Pod         ✔ Running  95m  ready:2/2
      ├──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-ddpjr  Pod         ✔ Running  95m  ready:2/2
      └──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-vh6b7  Pod         ✔ Running  95m  ready:2/2

请添加图片描述

更新image到0.8.1版本

# kubectl argo rollouts set image rollout-helloworld-bluegreen-with-analysis spring-boot-helloworld=ikubernetes/spring-boot-helloworld:v0.8.1
rollout "rollout-helloworld-bluegreen-with-analysis" image updated

当健康检查完毕后,就会删除老版本

Name:            rollout-helloworld-bluegreen-with-analysis
Namespace:       default
Status:          ✔ Healthy
Strategy:        BlueGreen
Images:          ikubernetes/spring-boot-helloworld:v0.8.1 (stable, active)
Replicas:
  Desired:       3
  Current:       3
  Updated:       3
  Ready:         3
  Available:     3

NAME                                                                    KIND         STATUS         AGE    INFO
⟳ rollout-helloworld-bluegreen-with-analysis                            Rollout      ✔ Healthy      4m24s  
├──# revision:2                                                                                            
│  ├──⧉ rollout-helloworld-bluegreen-with-analysis-6bb44b6c8d           ReplicaSet   ✔ Healthy      3m17s  stable,active
│  │  ├──□ rollout-helloworld-bluegreen-with-analysis-6bb44b6c8d-4vn5w  Pod          ✔ Running      3m16s  ready:2/2
│  │  ├──□ rollout-helloworld-bluegreen-with-analysis-6bb44b6c8d-cg7sp  Pod          ✔ Running      3m16s  ready:2/2
│  │  └──□ rollout-helloworld-bluegreen-with-analysis-6bb44b6c8d-pxnfx  Pod          ✔ Running      3m16s  ready:2/2
│  └──α rollout-helloworld-bluegreen-with-analysis-6bb44b6c8d-2-post    AnalysisRun  ✔ Successful   112s   ✔ 5
└──# revision:1                                                                                            
   └──⧉ rollout-helloworld-bluegreen-with-analysis-75954f68f5           ReplicaSet   • ScaledDown   4m4s   
      ├──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-c8dkf  Pod          ◌ Terminating  4m4s   ready:2/2
      ├──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-h9brp  Pod          ◌ Terminating  4m4s   ready:2/2
      └──□ rollout-helloworld-bluegreen-with-analysis-75954f68f5-wplv9  Pod          ◌ Terminating  4m4s   ready:2/2

此时curl到的版本也已经变成了Version 0.8.1

Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1
Spring Boot Helloworld, Version 0.8.1

请添加图片描述

rollout主要作用是取代deployment的功能.

在Gitops中应该让Config Repo称为唯一可信源.

定义好配置仓库,将deployment定义的资源都改为rollouts,在rollouts之上按需定义出每一个由rollouts定义出的spec.strategy.可以是canary或bule-green.结合analysisTemplate分析实现自动化渐进的部署.
最终实现用Argocd将新的配置应用到集群上结合istio的流量管控能力结合起来实现自动化应用发布环境.

猜你喜欢

转载自blog.csdn.net/qq_29974229/article/details/128031329