當要使用一部分用戶測試生產中的新部署時,請使用 Canary 部署。因為透過 Canary 部署,可以將更改發布給一小部分用戶,以減輕新版本相關的風險。建立一個範例,該範例是從 googlecodelabs 取得。
$ cat deployments/hello-canary.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-canary
spec:
replicas: 1
template:
metadata:
labels:
app: hello
track: canary
# Use ver 1.0.0 so it matches version on service selector
version: 1.0.0
spec:
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
...
使用 apply
佈署
$ kubectl create -f deployments/hello-canary.yaml
創建 canary 部署之後,應該有兩個部署,hello 和 hello-canary。使用 kubectl
進行驗證
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
auth 1/1 1 1 10m
frontend 1/1 1 1 9m23s
hello 3/3 3 3 9m32s
hello-canary 1/1 1 1 36s
在 hello 服務上,selector
使用 app:hello
選擇器,該 selector
將與 prod
部署和 canary
部署中的 POD
匹配。但是,由於 Canary 部署的 POD 數量較少,因此對較少的用戶可見。
使用 curl 進行驗證
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
運行幾次,應該看到 hello 1.0.0 為某些請求提供了服務,而 2.0.0 為一小部分約 1/4 提供了服務。原理如下圖
可以使用
sessionAffinity: ClientIP
方式讓請求端始終發送到相同版本的應用程式上
滾動更新是理想的選擇,因為它能夠以最小的開銷、性能和最小的停機時間來緩慢的部署應用程序。在某些情況下,只有在完全部署新版本之後,修改負載均衡器以使其指向該新版本是有益的,在這種情況下,必須進行 Blue-green 部署。Kubernetes 透過創建兩個單獨的 Deployment
來實現這一目標。一種用於舊的 blue 版本,另一種用於新的 green 版本,將現有的 hello 部署用於 blue 版本。將透過充當路由器的 Service
來訪問部署,新的 green 版本啟動並運行後,將透過更新 Service
切換到使用該版本。
selector
將匹配現有的 blue 部署。但是它不匹配 green 部署,因為它將使用不同的版本。
kind: Service
apiVersion: v1
metadata:
name: "hello"
spec:
selector:
app: "hello"
version: 1.0.0
ports:
- protocol: "TCP"
port: 80
targetPort: 80
green 應用程式佈署
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-green
spec:
replicas: 3
template:
metadata:
labels:
app: hello
track: stable
version: 2.0.0
spec:
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
resources:
limits:
cpu: 0.2
memory: 10Mi
livenessProbe:
httpGet:
path: /healthz
port: 81
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: 81
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
因為 Service
關係,因此還是指向 blue。
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
更新 Service
,透過 selector
讓它匹配 green
kind: Service
apiVersion: v1
metadata:
name: hello
spec:
selector:
app: hello
version: 2.0.0
ports:
- protocol: TCP
port: 80
targetPort: 80
驗證,變為 green 版本
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}
最近在學英文因此寫文章的品質沒那麼好,請見諒。