Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
異地部署 (Heterogeneous deployments) 涉及兩個以上的不同執行個體、基礎建設環境、地區,以解決特定的技術需求。
單一環境部署可能會遇到以下問題:
異地部署最常見的三個情境是複數雲部署、內部資料前端化 (fronting on-premises data) 與持續整合/部署 (CI/CD)。
內容目錄
gcloud config set compute/zone us-central1-a gsutil -m cp -r gs://spls/gsp053/orchestrate-with-kubernetes . cd orchestrate-with-kubernetes/kubernetes gcloud container clusters create bootcamp \ --num-nodes 5 --scopes "https://www.googleapis.com/auth/projecthosting,storage-rw"
kubectl
部署物件利用以下指令查詢 kubectl
有關部署物件的相關說明。
kubectl explain deployment kubectl explain deployment --recursive kubectl explain deployment.metadata.name
編輯 deployments/auth.yaml
。
vi deployments/auth.yaml
將映像檔 image
改為下列值:
... containers: - name: auth image: "kelseyhightower/auth:1.0.0" ...
儲存後,用 cat deployments/auth.yaml
確認是否完全變更。在這個組態中,replica
的值是 1
,代表部署時只會建立一個 Pod,之後如果需要建立多個 Pod 時,可以修改 replica
的值。接著建立部署物件。
kubectl create -f deployments/auth.yaml # 檢視所有部署 kubectl get deployments # 檢視 ReplicaSets kubectl get replicasets kubectl get pods
接著開始透過預先設定好的指令碼,建立各項服務。
kubectl create -f services/auth.yaml kubectl create -f deployments/hello.yaml kubectl create -f services/hello.yaml # 建立 TLS 憑證 kubectl create secret generic tls-certs --from-file tls/ kubectl create configmap nginx-frontend-conf --from-file=nginx/frontend.conf kubectl create -f deployments/frontend.yaml kubectl create -f services/frontend.yaml
接著使用 kubectl get services frontend
取得前端服務的外部 IP。
kubectl get services frontend
利用 curl
檢視 IP 是否能夠存取。
curl -ks https://<外部 IP> # 透過變數的方式取得外部 IP curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`
利用 kubectl scale deployment
來縮放叢集中的複本數。
kubectl scale deployment hello --replicas=5
確認複本是否在運作。
kubectl get pods | grep hello- | wc -l # 結果回傳 5
接著嘗試調整複本數。
kubectl scale deployment hello --replicas=3 kubectl get pods | grep hello- | wc -l # 結果回傳 3
當部署更新時,會先建立新的 ReplicaSet,並增加新 ReplicaSet 中的複本數量、逐漸減少舊 ReplicaSet 的複本數量。
使用 kubectl edit deployment
編輯部署。
kubectl edit deployment hello
更新映像檔至 2.0.0
版。
... containers: image: kelseyhightower/hello:2.0.0 ...
此時透過 kubectl get replicaset
,會看到 hello
的部署建立新的 ReplicaSet,逐漸替換掉舊的 ReplicaSet。
kubectl get replicaset # 檢視滾動更新的歷程紀錄 kubectl rollout history deployment/hello
如果在更新過程中發現問題時,可以先透過 kubectl rollout pause
暫停。並用下列指令檢查 Pods 的部署狀態。
kubectl rollout pause deployment/hello kubectl rollout status deployment/hello kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
kubectl rollout resume deployment/hello
利用 kubectl rollout undo
復原前一次的部署。
kubectl rollout undo deployment/hello
檢查復原歷程 kubectl rollout history
時會看到 REVISION
是第 3 個版本。
kubectl rollout history deployment/hello # 檢查 Pods 使用的映像檔 kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
透過 Canary 部署,可以將部分複本更新,降低新版本全面釋出造成的風險。
首先,先檢視預先準備好的 Canary 部署指令碼,並建立新的 Canary 部署。
cat deployments/hello-canary.yaml kubectl create -f deployments/hello-canary.yaml # 確認部署是否已經建立 kubectl get deployments
再重新執行數次 curl
指令來驗證,其中會注意到有時候回傳的值是 1.0.0
版,有時則是 2.0.0
版。
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
但是從上述的結果來看,每次的存取都會隨機分配。為了讓存取到某一版本的使用者,有一致的體驗,就會牽涉到工作階段親和性 (session affinity)。
在設定組態時,加入 sessionAffinity
屬性,指定 ClientIP
,便能讓同一 IP 的使用者,只會看到同樣版本的結果。
kind: Service apiVersion: v1 metadata: name: "hello" spec: sessionAffinity: ClientIP selector: app: "hello" ports: - protocol: "TCP" port: 80 targetPort: 80
除了滾動式更新外,另一種更新方式,是要等到完全部署完畢後,才將所有的流量路由傳送到新的部署上,此時就會採用 Blue-green 部署。
需要注意的是,Blue-green 部署需要兩倍的部署資源。
首先,先將既有的資源加入 app:hello
的選擇器,會將現有的服務比對成 Blue 版本。
kubectl apply -f services/hello-blue.yaml
建立 Green 版本的部署組態 hello-green.yaml
。
apiVersion: apps/v1 kind: Deployment metadata: name: hello-green spec: replicas: 3 selector: matchLabels: app: hello 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
部署 Green 版本。
kubectl create -f deployments/hello-green.yaml
用 curl
驗證,此時當前的版本還是 1.0.0
。
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
將服務指向新版本。
kubectl apply -f services/hello-green.yaml
再次驗證後,會發現已經更新到 2.0.0
的版本。
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
利用 kubectl apply
,套用原本的組態檔 hello-blue.yaml
,便能回復到前一個版本。
kubectl apply -f services/hello-blue.yaml