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的流量管控能力结合起来实现自动化应用发布环境.