应用正常的 CI 流程添加请求参数:
CanaryMode【bool,true | false,缺省值 false】 |
使用 Istio 的 DetinationRule + VirtualService
实现流量按权重分配到不同版本应用。
Iteration:发布迭代号,。是一个字段值,使用金丝雀发布时累加该值,从 0 累加。
Retract:动作,弃用金丝雀版本。当金丝雀版本存在不可忽视的问题时撤回金丝雀执行该动作。
Ratify:动作,确认使用金丝雀版本。当金丝雀版本确认可以全面投入使用执行该动作。
使用金丝雀发布的前提条件:
CI 发布除了创建或更新 Deployment,Service 之外,默认创建或更新 istio 的 DestinationRule 资源;
deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-pbd3n69-v{iteration} # 出于兼容历史发布,当iteration为0时,name不附带iteration,iteration大于0时,name将附带iteration
labels:
app: myapp-pbd3n69
version: v{iteration}
spec:
selector:
matchLabels:
app: myapp-pbd3n69
version: v{iteration}
template:
metadata:
labels:
app: myapp-pbd3n69
version: v{iteration}
...
service:
apiVersion: v1
kind: Service
metadata:
name: myapp-pbd3n69
spec:
selector:
app: myapp-pbd3n69
...
destination rule:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp-pbd3n69
spec:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
subsets:
- labels:
version: v{iteration}
name: subset-v{iteration}
virtual service:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: virtual-service-example-com
spec:
hosts:
- example.com
http:
- match:
- uri:
prefix: /xxx
name: myapp-pbd3n69
route:
- destination:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
port:
number: 80
subset: subset-v{iteration}
weight: 100
使用金丝雀发布,涉及到金丝雀版本 Deployment 的创建,DestinationRule 和 VirtualService 的更新:
deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-pbd3n69-v{iteration+1}
labels:
app: myapp-pbd3n69
version: v{iteration+1}
spec:
selector:
matchLabels:
app: myapp-pbd3n69
version: v{iteration+1}
template:
metadata:
labels:
app: myapp-pbd3n69
version: v{iteration+1}
destination rule:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ash-pbd3n69
namespace: test
spec:
host: ash-pbd3n69 # 注意:这里是 Service 的 name
subsets:
- labels:
version: v{iteration}
name: subset-v{iteration}
- labels:
version: v{iteration+1}
name: subset-v{iteration+1}
virtual service:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: virtual-service-example-com
spec:
hosts:
- example.com
http:
- match:
- uri:
prefix: /xxx
name: myapp-pbd3n69
route:
- destination:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
port:
number: 80
subset: subset-v{iteration}
weight: {canaryWeight}
- destination:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
port:
number: 80
subset: subset-v{iteration+1}
weight: {100-canaryWeight}
发布完成后,Iteration+1,应用状态更新为 Canary。在 Canary 状态下,由于存在两个版本的 Deployment,将无法手动应用垂直或水平扩容。
删除金丝雀版本的 Deployment,
DestinationRule 更新
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ash-pbd3n69
namespace: test
spec:
host: ash-pbd3n69 # 注意:这里是 Service 的 name
subsets:
- labels:
version: v{iteration-1}
name: subset-v{iteration-1}
VirtualService 更新
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: virtual-service-example-com
spec:
hosts:
- example.com
http:
- match:
- uri:
prefix: /xxx
name: myapp-pbd3n69
route:
- destination:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
port:
number: 80
subset: subset-v{iteration-1}
weight: 100
Iteration-1
删除之前稳定版本的 Deployment,
DestinationRule 更新
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: ash-pbd3n69
namespace: test
spec:
host: ash-pbd3n69 # 注意:这里是 Service 的 name
subsets:
- labels:
version: v{iteration}
name: subset-v{iteration}
VirtualService 更新
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: virtual-service-example-com
spec:
hosts:
- example.com
http:
- match:
- uri:
prefix: /xxx
name: myapp-pbd3n69
route:
- destination:
host: myapp-pbd3n69 # 注意:这里是 Service 的 name
port:
number: 80
subset: subset-v{iteration}
weight: 100