使用Istio作流量路由
FEATURE STATE: Kruise Rollout v0.5.0
这里展示了如何配置Kruise Rollout来使用Istio作为流量路由
完整的发布流程
部署deploymet workload-demo
和 service service-demo
apiVersion: v1
kind: Service
metadata:
name: service-demo
spec:
ports:
- port: 80
name: http
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: workload-demo
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
env:
- name: version
value: base
ports:
- containerPort: 80
部署 VirtualService vs-demo
, 配置其路由流量到 service-demo
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-demo
spec:
gateways:
- simple-gateway
hosts:
- "*"
http:
- route:
- destination:
host: service-demo
下发Rollout配置 rollouts-demo
apiVersion: rollouts.kruise.io/v1beta1
kind: Rollout
metadata:
name: rollouts-demo
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: workload-demo
strategy:
canary:
steps:
- replicas: 1
matches:
- headers:
- type: Exact
name: version
value: canary
- traffic: 50%
replicas: 50%
- traffic: 80%
replicas: 80%
trafficRoutings:
- service: mocka
customNetworkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: vs-demo
当您下发了一个deploymet(workload-demo)的新版本时, Kruise Rollout会根据发布策略, 来修改VirtualService的配置, 具体的发布步骤如下:
- 一个新的金丝雀deployment会被创建, 且其副本数为1。带有http头
version=canary
的流量会被Istio路由到金丝雀pod上, 而其他的流量会被路由到稳定版本的pod上去。 - 更新金丝雀deployment的实例数为稳定版deployment实例数的50%, 并且路由50%的流量到金丝雀的pod上。
- 更新金丝雀deployment的实例数为稳定版deployment实例数的80%, 并且路由80%的流量到金丝雀的pod上。
更新deployment workload-demo
通过运行如下命令来, 修改负载的环境变量, 从而触发发布流程
$ kubectl patch deployment workload-demo -p \
'{"spec":{"template":{"spec":{"containers":[{"name":"nginx", "env":[{"name":"version", "value":"canary"}]}]}}}}'
等待片刻, Kruise Rollout就会执行如下的操作:
- 暂停老版本deployment对象的原生发布动作
- 用环境变量
version: canary
来创建一个新的Deployment - 创建一个新的Service
service-demo-canary
用来路由流量到新版本的pod - 更新VirtualService
vs-demo
来修改Istio的流量路由行为
当发布的第一个步骤完成后, 检查VirtualService vs-demo
, 可以看到如下的变化:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
rollouts.kruise.io/original-spec-configuration: '{"spec":{"gateways":["simple-gateway"],"hosts":["*"],"http":[{"route":[{"destination":{"host":"service-demo"}}]}]},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"vs-demo\",\"namespace\":\"default\"},\"spec\":{\"gateways\":[\"simple-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"service-demo\"}}]}]}}\n"}}'
name: vs-demo
spec:
gateways:
- simple-gateway
hosts:
- '*'
http:
# 理由带有http头version=canary的流量到新版本的pod(通过service-demo-canary)
- match:
- headers:
version:
exact: canary
route:
- destination:
host: service-demo-canary
- route:
- destination:
host: service-demo
运行kubectl-kruise rollout approve rollout/rollouts-demo -n default
来开始发布的第二个步骤。 当第二个发布步骤完成后, 检查VirtualService vs-demo
, 可以看到如下的变化
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
rollouts.kruise.io/original-spec-configuration: '{"spec":{"gateways":["simple-gateway"],"hosts":["*"],"http":[{"route":[{"destination":{"host":"service-demo"}}]}]},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"vs-demo\",\"namespace\":\"default\"},\"spec\":{\"gateways\":[\"simple-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"service-demo\"}}]}]}}\n"}}'
name: vs-demo
spec:
gateways:
- simple-gateway
hosts:
- '*'
http:
- route:
- destination:
host: service-demo
weight: 50
- destination:
host: service-demo-canary
weight: 50 # 路由50%的流量到新版本pod
运行kubectl-kruise rollout approve rollout/rollouts-demo -n default
来开始发布的第三个步骤, 当第三个发布步骤完成后, 检查VirtualService vs-demo
, 可以看到如下的变化
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
rollouts.kruise.io/original-spec-configuration: '{"spec":{"gateways":["simple-gateway"],"hosts":["*"],"http":[{"route":[{"destination":{"host":"service-demo"}}]}]},"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1beta1\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"vs-demo\",\"namespace\":\"default\"},\"spec\":{\"gateways\":[\"simple-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"route\":[{\"destination\":{\"host\":\"service-demo\"}}]}]}}\n"}}'
name: vs-demo
spec:
gateways:
- simple-gateway
hosts:
- '*'
http:
- route:
- destination:
host: service-demo
weight: 20
- destination:
host: service-demo-canary
weight: 80 # 路由80%的流量到新版本pod
运行kubectl-kruise rollout approve rollout/rollouts-demo -n default
来完成发布流程, Kruise Rollout会进行如下的收尾工作:
- 删除金丝雀Deployment。
- 删除金丝雀Service
service-demo-canary
。 - 恢复Deployment
workload-demo
的原生发布动作 - 恢复VirtualService
vs-demo
, 去除金丝雀流量路由相关的规则