在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至此,完成從舊版本到新版本過渡過程中的清理工作。