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