在Raw Deployment部署模式下,应用的灰度发布需要基于网关实现。本文以Nginx Ingress Controller网关为例,介绍如何实现推理服务的灰度发布,并最终平稳地完成从v1到v2版本推理服务的升级。
前提条件
已安装Arena客户端。
操作说明
本文将部署两个推理服务,分别为canary的v1版本和v2版本。基于这两个服务来演示两种灰度策略场景,并最终完成版本切换:
基于客户端请求的流量切分。
将带有请求头
foo: bar
的请求定向model-v2-svc
的服务为例,其他请求默认指向model-svc
。基于服务权重的流量切分。
将20%的流量被导向名为
model-v2-svc
的服务,剩余流量继续流向model-svc
。
关于通过Nginx Ingress实现灰度发布的背景信息及原理说明,请参见通过Nginx Ingress实现灰度发布和蓝绿发布。
步骤一:部署并验证推理服务
v1版本
| v2版本
|
步骤二:创建Ingress
创建model-ingress.yaml。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: model-ingress spec: rules: - host: model.example.com # 替换为您实际业务的Host。 http: paths: # 老版本服务。 - path: / backend: service: name: model-svc port: number: 80 pathType: ImplementationSpecific
创建Ingress。
kubectl apply -f model-ingress.yaml
步骤三:创建并验证灰度策略
场景一:基于客户端请求的流量切分场景
创建gray-release-canary.yaml。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gray-release-canary annotations: # 开启Canary。 nginx.ingress.kubernetes.io/canary: "true" # 请求头为foo。 nginx.ingress.kubernetes.io/canary-by-header: "foo" # 请求头foo的值为bar时,请求才会被路由到新版本服务model-v2中。 nginx.ingress.kubernetes.io/canary-by-header-value: "bar" spec: rules: - host: model.example.com http: paths: # 新版本服务。 - path: / backend: service: name: model-v2-svc port: number: 80 pathType: ImplementationSpecific
部署灰度发布策略。
kubectl apply -f gray-release-canary.yaml
验证无特定请求头(默认版本访问)的服务响应。
# 以下代码的Host为Ingress中定义的业务Host。 curl -H "Host: model.example.com" -H "Content-Type: application/json" \ http://$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}'):80/v1/models/canary:predict -X POST \ -d '{"data": "test"}'
预期输出:
{"id":"4d8c110d-c291-4670-ad0a-1a30bf8e314c","model_name":"canary","model_version":null,"outputs":[{"name":"output-0","shape":[1,1],"datatype":"STR","data":["model-v1"]}]}%
输出结果返回了model-v1的结果,表明默认情况下服务能够正确提供model-v1的预测结果。即流量流向了model-v1。
执行以下命令,验证带有
"foo: bar"
请求头(期望访问金丝雀版本)的客户端请求。curl -H "Host: model.example.com" -H "Content-Type: application/json" \ -H "foo: bar" \ http://$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}'):80/v1/models/canary:predict -X POST \ -d '{"data": "test"}'
预期输出:
{"id":"4d3efc12-c8bd-40f8-898f-7983377db7bd","model_name":"canary","model_version":null,"outputs":[{"name":"output-0","shape":[1,1],"datatype":"STR","data":["model-v2"]}]}%
输出结果返回了model-v2的结果,表明带有特定请求头的流量被正确地导向了灰度版本,即灰度发布策略已生效。
场景二:基于服务权重的流量切分场景
创建gray-release-canary.yaml。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gray-release-canary annotations: # 开启Canary。 nginx.ingress.kubernetes.io/canary: "true" # 仅允许20%的流量会被路由到新版本服务model-v2中。 # 默认总值为100。 nginx.ingress.kubernetes.io/canary-weight: "20" spec: rules: - host: model.example.com http: paths: # 新版本服务。 - path: / backend: service: name: model-v2-svc port: number: 80 pathType: ImplementationSpecific
部署灰度发布策略。
kubectl apply -f gray-release-canary.yaml
验证流量的流向。
curl -H "Host: model.example.com" -H "Content-Type: application/json" \ http://$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}'):80/v1/models/canary:predict -X POST \ -d '{"data": "test"}'
重复执行以上命令,您可以观察到大约有20%的流量被路由到新版本(model-v2)的服务上,其他流量则流向稳定版本(model-v1)的服务,两种服务比例大约为1:4。即灰度策略已生效。
步骤四:版本切换
当新版本服务已经稳定并且符合预期后,需要下线老版本的服务 ,仅保留新版本服务在线上运行。
更新model-svc.yaml,将Service指向新版本model-v2服务。
apiVersion: v1 kind: Service metadata: name: model-svc spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: serving.kserve.io/inferenceservice: model-v2 # 将model-v1修改为model-v2。 type: ClusterIP
执行以下命令,重新部署Service。
kubectl apply -f model-svc.yaml
查看路由访问情况。
curl -H "Host: model.example.com" -H "Content-Type: application/json" \ http://$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}'):80/v1/models/canary:predict -X POST \ -d '{"data": "test"}'
预期输出:
{"id":"a13f2089-73ce-41e3-989e-e58457d14fed","model_name":"canary","model_version":null,"outputs":[{"name":"output-0","shape":[1,1],"datatype":"STR","data":["model-v2"]}]}%
重复执行以上命令后,您可以观察到100%的请求(流量)被路由到新版本(model-v2)的服务上。
执行以下命令,删除旧版本服务。
kubectl delete ingress gray-release-canary arena serve delete model-v1 kubectl delete svc model-v2-svc
至此,完成从旧版本到新版本过渡过程中的清理工作。