K8s 1.18.6版本基於 ingress-nginx 實現金絲雀釋出(灰度釋出)
K8s 1.18.6版本基於 ingress-nginx 實現金絲雀釋出(灰度釋出)
環境
軟體 | 版本 |
---|---|
kubernetes | v1.18.6 |
nginx-ingress-controller | 0.32.0 |
Rancher | v2.4.5 |
本次實驗基於 Rancher-v2.4.5 部署了1.18.6版本的k8s叢集,nginx-ingress 版本為0.32.0,理論上 ingress-nginx >= 0.21.0都是可以的。
介紹
金絲雀釋出:又叫灰度釋出,控制產品從A版本平滑的過度到B版本
ingress-nginx:k8s ingress工具,支援金絲雀釋出,可以實現基於權重、請求頭、請求頭的值、cookie轉發流量。
rancher:k8s叢集管理工具,使用UI簡化k8s相關操作
ingress-nginx canary官方說明:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#canary
首先建立兩個nginx應用
- 部署兩個deployment的http應用
apiVersion: apps/v1 kind: Deployment metadata: name: appv1 labels: app: v1 spec: replicas: 1 selector: matchLabels: app: v1 template: metadata: labels: app: v1 spec: containers: - name: nginx image: zerchin/canary:v1 ports: - containerPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: appv2 labels: app: v2 spec: replicas: 1 selector: matchLabels: app: v2 template: metadata: labels: app: v2 spec: containers: - name: nginx image: zerchin/canary:v2 ports: - containerPort: 80
kubectl檢視pod
# kubectl get pod -o wide |grep app
appv1-77655949f8-hx6nm 1/1 Running 0 44m 10.60.0.91 xie-node001 <none> <none>
appv2-7b8659cd88-dgd5c 1/1 Running 0 44m 10.60.0.92 xie-node001 <none> <none>
這兩個應用輸出以下內容
# curl 10.60.0.91 v1 # curl 10.60.0.92 canary-v2
- 分別為應用建立對應的service
apiVersion: v1
kind: Service
metadata:
name: appv1
spec:
selector:
app: v1
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: appv2
spec:
selector:
app: v2
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl檢視service
# kubectl get svc |grep app
appv1 ClusterIP 10.50.42.17 <none> 80/TCP 26m
appv2 ClusterIP 10.50.42.131 <none> 80/TCP 26m
部署一個正常的ingress
現在這個ingress能正常的將訪問路由到appv1上
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app
namespace: default
spec:
rules:
- host: nginx.zerchin.xyz
http:
paths:
- backend:
serviceName: appv1
servicePort: 80
path: /
kubectl檢視ingress
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
app <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 11m
訪問nginx.zerchin.xyz
# curl nginx.zerchin.xyz
v1
基於權重轉發流量
nginx.ingress.kubernetes.io/canary-weight
:隨機整數請求的整數百分比(0-100),應將其路由到canary Ingress中指定的服務。權重0表示此Canary規則不會在Canary入口中將任何請求傳送到服務。權重為100表示所有請求都將傳送到Ingress中指定的替代服務。
新建一個ingress,配置如下
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "30"
name: app-canary
namespace: default
spec:
rules:
- host: nginx.zerchin.xyz
http:
paths:
- backend:
serviceName: appv2
servicePort: 80
path: /
kubectl檢視ingress
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
app <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 11m
app-canary <none> nginx.zerchin.xyz 172.16.0.195,172.16.0.196 80 7m13s
這時候再訪問nginx.zerchin.xyz,會發現其中30%的流量會路由到v2版本上
# for i in `seq 1 10`;do curl nginx.zerchin.xyz;done
canary-v2
canary-v2
v1
v1
canary-v2
v1
v1
v1
v1
v1
基於請求頭轉發流量
nginx.ingress.kubernetes.io/canary-by-header
:用於通知Ingress將請求路由到Canary Ingress中指定的服務的標頭。當請求標頭設定always
為時,它將被路由到Canary。當標頭設定never
為時,它將永遠不會路由到金絲雀。對於任何其他值,標頭將被忽略,並且按優先順序將請求與其他金絲雀規則進行比較。
修改app-canary的ingress配置,修改annotation,如下:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "canary"
測試結果
# curl nginx.zerchin.xyz
v1
# curl -H "canary:always" nginx.zerchin.xyz
canary-v2
基於請求頭和請求頭的值轉發流量
nginx.ingress.kubernetes.io/canary-by-header-value
:匹配的報頭值,用於通知Ingress將請求路由到Canary Ingress中指定的服務。當請求標頭設定為此值時,它將被路由到Canary。對於任何其他標頭值,標頭將被忽略,並按優先順序將請求與其他金絲雀規則進行比較。此註釋必須與nginx.ingress.kubernetes.io/canary-by-header
一起使用。
修改app-canary的ingress配置,修改annotation,如下:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "haha"
測試結果
# curl nginx.zerchin.xyz
v1
# curl -H "canary:haha" nginx.zerchin.xyz
canary-v2
# curl -H "canary:always" nginx.zerchin.xyz
v1
基於cookie轉發流量
nginx.ingress.kubernetes.io/canary-by-cookie
:用於通知Ingress將請求路由到Canary Ingress中指定的服務的cookie。當cookie值設定always
為時,它將被路由到canary。當cookie設定never
為時,它將永遠不會路由到Canary。對於任何其他值,將忽略cookie,並按優先順序將請求與其他canary規則進行比較。
修改app-canary的ingress配置,修改annotation,如下:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: "test"
測試結果
# curl nginx.zerchin.xyz
v1
# curl -b "test=never" nginx.zerchin.xyz
v1
# curl -b "test=always" nginx.zerchin.xyz
canary-v2
# curl -b "test=1" nginx.zerchin.xyz
v1
總結
-
金絲雀釋出規則優先順序:
canary-by-header
->canary-by-cookie
->canary-weight
-
目前,每個ingress規則最多可以應用一個canary ingress