使用 GCP Kubernetes Engine 來管理部署

概述

Dev Ops 實踐通常使用多重部署的方法來管理應用部署情境, 像是 “持續部署”, “Blue-Green 部署”, “Canary 部署”, 等等… 本教程主要提供擴充以及管理容器的方法, 所以你可以完成這些使用多重部署的通用情境。


你將會做什麼?

  • Kubectl 工具的練習
  • 建立 deployment yaml 檔案
  • 啟動, 更新, 以及擴充 deployments
  • 更新 deployments 以及 部署風格的練習

事先準備



deployments 介紹

Heterogeneous deployments (多種類部署) 一般來說包含兩個或多個基礎設施或地區以解決特定技術或運作需求。 Heterogeneous deployments 又被稱為 “hybrid”, “multi-cloud”, 或 “public-private”, 取決於部署細節。
在本教程中, heterogeneous deployments 包含地區橫跨單一雲端環境, 多公開雲端環境 (multi-cloud), 或是內部部署以及公開雲端的結合 (hybrid 或 public-private)

單一環境或地區的部署可能會在業務邏輯上或技術上有一些問題

  • 資源耗盡: 在單一環境中, 尤其是內部部署環境, 你可能沒有正式環境需要的計算, 網路, 或儲存資源
  • 被限制的觸及地區: 單一環境的部署需要不同區域的人們存取不同區域的部署, 他們的流量可能會繞了世界一周之後才到達一個中間地區
  • 被限制的可用性: 網路擴充流量模式對應用保持容錯以及適應, 會是一個挑戰
  • 供應商鎖定: 供應商等級的平台以及基礎設施抽象將讓應用移植變得困難
  • 不靈活的資源: 你的資源可能會被限制在一組特定的計算機, 儲存區, 或網路

Heterogeneous 可幫我們解決這些難題, 但他們必須被建構在可程式化以及確定性的程序以及步驟。 一次性的或點對點的部署步驟會造成部署或程序脆弱, 以及容錯能力降低。 點對點程序會丟失資料或丟棄流量。 一個好的部署程序需要是可重複的, 使用已確認可用的方法來管理提供, 設定, 以及維護。

三個 heterogeneous 通用的情境, 分別是 multi-cloud deployments (多雲端部署), fronting on-premises data (前端導向內部資料), 以及 CI/CD (持續整合 / 持續部署) 程序

以下的練習會實作一些 heterogeneous deployments 通用使用情境, 以及透過良好架構的 Kubernetes 方法以及其他的基礎設施資源來達成



設定及要求

在你按下 Start Lab 按鈕之前

詳讀所有的教學。 Labs 是有時間限制的, 而且你不可以停止時間倒數。 倒數計時器在你按下 Start Lab 按鈕後開始倒數, 上面顯示的時間為你還能使用 Cloud 資源的時間。

Qwiklabs 的手把手環境, 讓你可以在真實環境中來操作進行 Qwiklabs 上提供的課程, 而不是在一個模擬或是展示的環境。 我們透過提供你一個全新的、暫時的帳號密碼, 在計時器歸零之前, 你可以用來登入並存取 Google Cloud Platform。

你需要什麼?

要完成這個 lab, 你需要:

  • 一個一般的網路瀏覽器(推薦 Chrome)
  • 完成這個 lab 的時間

備註: 如果你已經有你自己的個人 GCP 帳號或專案,請不要使用在這一個 lab

現在你已經開始你的 lab, 你將會登入 Google Cloud Shell 主控台, 然後開啟命令列工具

如何開始你的 lab, 然後登入 Console?

  • 按下 Start Lab 按鈕。 如果你需要付費, 會有一個彈出視窗來讓你選擇付費的方式。 在左方你會看到一個面板, 上面有暫時的帳號密碼, 你必須使用這些帳號密碼在此次 lab

  • 複製 username, 然後點擊 Open Google Console。 Lab 會開啟另外一個視窗, 顯示選擇帳號的頁面

tip: 開啟一個全新的視窗,然後跟原本的頁面並排

  • 選擇帳號頁面, 點擊 Use Another Account

  • 登入頁面開啟, 貼上之前複製的 username 以及 password, 然後貼上

重要: 必須使用之前於 Connection Details 面板 取得的帳號密碼,不要使用你自己的 Qwiklabs 帳號密碼。 如果你有自己的 GCP 帳號, 請不要用在這裡(避免產生費用)

  • 點擊並通過接下來的頁面:
    • 接受 terms 以及 conditions
    • 不要增加 recovery optoinstwo factor authentication (因為這只是一個臨時帳號)
    • 不要註冊免費體驗

稍待一些時候, GCP 控制台將會在這個視窗開啟。

注意: 按下左上方位於 Google Cloud Platform 隔壁的 Navigation menu, 你可以瀏覽選單, 裡面有一系列的 GCP 產品以及服務


啟動 Google Cloud Shell

Google Cloud Shell 是載有開發工具的虛擬機器。 它提供了5GB的 home 資料夾, 並且運行在 Google Cloud 上。 Google Cloud Shell 讓你可以利用 command-line 存取 GCP 資源

  • GCP 控制台, 右上的工具列,點擊 Open Cloud Shell 按鈕

  • 在打開的對話框裡, 按下 START CLOUD SHELL:

你可以立即按下 START CLOUD SHELL 當對話視窗打開。

連結並提供環境會需要一點時間。 當你連結成功, 這代表你已成功獲得授權, 且此專案已被設為你的專案ID, 例如:

gcloudGoogle Cloud Platform 的 command-line 工具, 他已事先被安裝在 Cloud Shell 並且支援自動補齊

使用這個 command, 你可以列出有效帳戶名稱:

gcloud auth list

輸出:

Credentialed accounts:
- <myaccount>@<mydomain>.com (active)

範例輸出:

Credentialed accounts:
- google1623327_student@qwiklabs.net

你可以使用以下 command 來列出專案 ID

gcloud config list project

輸出:

[core]
project = <project_ID>

範例輸出:

[core]
project = qwiklabs-gcp-44776a13dea667a6

gcloud 的完整文件可以參閱 Google Cloud gcloud Overview


設定 zone

執行以下指令來設定你的 GCP zone, 將 local zone us-central1-a 替換掉

gcloud config set compute/zone us-central1-a

取得本教程範例程式碼

取得建立, 運行容器以及 deployments 的範例程式碼

git clone https://github.com/googlecodelabs/orchestrate-with-kubernetes.git
cd orchestrate-with-kubernetes/kubernetes

建立一個含有 5 台 n1-standard-1 node 的叢集 (會需要幾分鐘時間完成)

gcloud container clusters create bootcamp --num-nodes 5 --scopes "https://www.googleapis.com/auth/projecthosting,storage-rw"


理解 deployment 物件

讓我們從 Deployments 開始。 首先檢視一下 Deployment 物件。 kubectlexplain 指令可以告訴我們有關 Deployment 物件的資訊

kubectl explain deployment

我們可以使用 --resursive 選項來檢視所有的欄位

kubectl explain deployment --recursive

在你進行本教程的過程中, 你可以使用 explain 來更了解 Deployment 物件的結構, 以及每個欄位做什麼事

kubectl explain deployment.metadata.name


建立 deployment

更新 deployments/auth.yaml cs 檔案:

vim deployments/auth.yaml

開始編輯模式

i

將 container 區塊內的 image 變更如下:

...
containers:
- name: auth
image: kelseyhightower/auth:1.0.0
...

儲存 auth.yaml 檔案, 按下 <Esc>, 然後:

:wq

現在讓我們來建立一個簡單的 deployment 。 檢視 deployment 設定檔

cat deployments/auth.yaml

(輸出)

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: auth
spec:
replicas: 1
template:
metadata:
labels:
app: auth
track: stable
spec:
containers:
- name: auth
image: "kelseyhightower/auth:1.0.0"
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
...

注意到 Deployment 是如何建立一個 replica 且使用 auth container 的 version 1.0.0

當你執行 kubectl create 指令來建立 auth deployment 時, 一個符合 Deployment 設定檔的 pod 將會被建立。 這表示說, 我們可以藉由變更 replica 欄位的數量擴縮 Pods 的數量

使用 kubectl create 來建立 deployment 物件

kubectl create -f deployments/auth.yaml

一旦你已經建立 Depolyment, 你可以確認看看它是否有被建立

kubectl get deployments

一旦 deployment 被建立了, Kubernetes 會建立一個相對應的 ReplicaSet 。 我們可以確認對應該 Deployment 的 ReplicaSet 是否有被建立

kubectl get replicasets

我們應會看到一個名為 auth-xxxxxx 的 ReplicaSet

最後, 我們可以檢視 Pods, 它是 Deployment 的一部分。 當 ReplicaSet 被建立, Kubernetes 會建立一個 Pod

kubectl get pods

是時候建立一個 auth deployment 的 service 。 你已經看過 service 的設定檔, 所以在這我們不會探究更多細節。 使用 kubectl create 指令來建立 auth service

kubectl create -f services/auth.yaml

現在, 同樣的步驟, 讓我們建立以及暴露 hello Deployment

kubectl create -f deployments/hello.yaml
kubectl create -f services/hello.yaml

然後再一次, 建立以及暴露 frontend Deployment

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

注意: 你為 frontend 建立了一個 ConfigMap

取得 frontend 的外部 IP 然後使用 curl 與它互動

kubectl get services frontend
curl -ks https://EXTERNAL-IP

然後你會得到一個 hello 的回應
你也可以使用 kubectl 的輸出模板功能搭配 curl, 讓指令變成只需要一行

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`

測試進度
點擊 Check my progress 來確認目前的進度。如果你已經成功建立了 Kubernetes 叢集以及 Auth, Hello, 跟 Frontend deployments, 你將獲得一個評價分數。

擴縮 Deployment

現在我們已建立一個 Deployment, 我們可以擴縮它。 可以藉由更新 spec.replicas 欄位來達成。 你可以再次使用 Kubectl explain 指令來檢視這個欄位的解釋

kubectl explain deployment.spec.replicas

更新 replicas 欄位最簡單的方法就是使用 kubectl scale 指令

kubectl scale deployment hello --replicas=5

注意: 要讓全部的 pods 都啟動且運行約需要幾分鐘
Deployment 建立後, Kubernetes 會自動地更新相對應的 ReplicaSet 以及啟動新的 Pods, 讓 Pods 的總數量等於 5

確認是否有 5 個 hello Pods 運行中:

kubectl get pods | grep hello- | wc -l

現在擴縮回原本的數量

kubectl scale deployment hello --replicas=3

再一次, 確認 Pods 的數量是正確的

kubectl get pods | grep hello- | wc -l

你已經學習了 Kubernetes deployments 以及如何管理 & 擴縮 Pods 群組



rolling update (滾動升級)

Deployments 支援透過滾動升級的機制進行鏡像升級。 當 Deployment 被更新成新的版本, 它會建立一個新的 ReplicaSet, 並且慢慢的增加新版的 replicas 的數量, 同時, 也慢慢地減少舊版的 replicas 數量


觸發滾動升級

執行以下指令來更新 Deployment:

kubectl edit deployment hello

將 containers 區塊內的 image 變更如下:

...
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
...

儲存並離開
一但你成功的儲存編輯器, 更新的 Deployment 會被儲存到你的叢集, 然後 Kubernetes 將會開始滾動升級。
檢視 Kubernetes 新建立的 ReplicaSet

kubectl get replicaset

同時你也可以檢視 rollout 的紀錄

kubectl rollout history deployment/hello

暫停滾動升級

如果在滾動升級的過程中, 你發現一些問題, 你可以停止升級

kubectl rollout pause deployment/hello

確認目前的滾動狀態

kubectl rollout status deployment/hello

你也可以直接透過 Pods 資訊來確認

kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

繼續滾動升級

滾動升級被中斷了, 這表示有一些 Pods 正運行著新版本而有些 Pods 運行舊版本。 我們可以使用以下的 resume 指令來繼續未完成的滾動

kubectl rollout resume deployment/hello

當滾動完成了, 你執行 status 指令時, 應會看到輸出如下:

kubectl rollout status deployment/hello

(輸出)

deployment "hello" successfully rolled out

回滾

假設我們在新版本發現了一個 bug 。 因為新版本有問題, 任何存取新的 Pods 資源的使用者都會遇到這個問題
你會想要回滾之前的版本, 所以你可以看看出了什麼問題, 待修復後再發布一個新的版本
使用 rollout 指令來回滾到之前的版本

kubectl rollout undo deployment/hello

確認回滾歷史

kubectl rollout history deployment/hello

最後, 確認所有的 Pods 都有回滾到之前的版本

kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

帥氣! 你已經學會 Kubernetes 的滾動升級, 以及如何 0 downtime 的更新你的應用



金絲雀部署 (Canary Deployments)

當你想要在正式環境只對一部分的使用者進行新版本的測試, 你可以使用金絲雀部署。 金絲雀部署讓你可以只發布變更到一小部分的使用者, 降低新發布的風險


建立一個金絲雀部署 (canary deployment)

金絲雀部署包含分開的 deployment, 以及一個共同的 service, 這個 service 可以導向穩定, 一般的版本, 以及金絲雀版本

首先, 建立一個新的金絲雀 deployment

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
...

確認有更新到版本 1.0.0 (如果你的版本是指向其他的)
現在建立一個金絲雀 deployment

kubectl create -f deployments/hello-canary.yaml

金絲雀 deployment 被建立後, 你應會有兩個 deployments, hello 以及 hello-canary 。 使用以下的 kubectl 指令來確認:

kubectl get deployments

hello service, selector 使用 app:hello selector, 這將會同時符合 prod deployment 以及 canary deployment 。 然而, 因為 canary deployment 的 pods 數量較少, 所以它對使用者的可見度來說是相對低的。


確認 canary deployment

你可以發請求, 並經由以下指令來確認服務該請求的 hello 版本

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

執行這個指令多次, 你應會看到有一些請求是由 hello 1.0.0 所服務, 而有一小部分 (1/4 = 25%) 的請求是由 2.0.0 所服務

測試進度
點擊 Check my progress 來確認目前的進度。如果你已經建立金絲雀部署, 你將獲得一個評價分數。


在正式環境中的 Canary deployments - session affinity

在本教程中, 每個發往 Nginx 服務的請求都有機率由 canary deployment 所服務。 但如果是你不想要某些使用者是由 canary deployment 來服務呢? 一個使用情境是當你 canary deployment 的 UI 有變動, 而你不想要讓使用者覺得疑惑。 在這個使用情境中, 你想要讓使用者們可以固定的被不同的 deployment 所服務, 不會一直切換來切換去的。

你可以建立一個賦有 session affinity 的 service 。 這個方法會讓使用者總是被同一個版本的 deployment 服務。 在以下的範例中, service 跟之前的沒什麼不同, 但多了一個 sessionAffinity 欄位, 並設定成 ClientIP 。 所有有著相同 IP 的客戶端將會由相同的 hello 版本的應用所服務

kind: Service
apiVersion: v1
metadata:
name: "hello"
spec:
sessionAffinity: ClientIP
selector:
app: "hello"
ports:
- protocol: "TCP"
port: 80
targetPort: 80

因為這個情境比較難測試, 所以我們不必在此測試, 但你可能會想要在正式環境中使用 sessionAffinity



Blue-green deployment

滾動升級是個理想的部署方式, 因為它讓我們可以用最小效能影響, downtime, 以及花費來部署應用。 然而在某些情況中, 待新版本部署完成後, 修改平衡負載指向新版本, 這種方式會是比較有利的。 在這樣的使用情境下, blue-green 部署會是我們需要的方式
Kubernetes 藉由建立兩個分開的 deployments 來達成這個目的; 一個舊的 “blue” 版本的 deployment 以及一個新的 “green” 版本的 deployment 。 使用已存在的 hello 來作為 “blue” 版本。 這個 deployment 將會透過一個角色為路由的 Service 來被存取。 一旦新的 “green” 版本已成功啟動並且運行中, 你可以藉由更新這個 service 來切換使用新版本。

blue-green deployments 有一個主要的缺點, 那就是你必須在叢集中要有至少 2 組以上的資源來運行你的應用。 在你同時部署兩個版本的應用到叢集之前, 務必確認你有足夠的資源。


The service (服務)

使用已存在的 hello service, 但是把它的 selector 更新成 app:hello, version: 1.0.0 。 這個 selector 會符合 “blue” deployment, 但不會符合 “green” deployment 因為它使用不同的版本
首先更新服務:

kubectl apply -f services/hello-blue.yaml

更新使用 Blue-Green deployment

我們將建立一個新版本 “green” deployment 來支援 blue-green deployment 風格。 這個 green deployment 更新了版本標籤以及鏡像路徑。

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

建立 green deployment

kubectl create -f deployments/hello-green.yaml

一但你已經建立好 green deployment, 並且它已經被正確啟動且運行, 確認目前是否還是使用 1.0.0 的版本

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

現在更新服務來指向新的 deployment 版本

kubectl apply -f services/hello-green.yaml

當 service 被更新後, “green” deployment 會立即地被使用。 你可以確認新版本是否一直被使用著

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

Blue-Green 回滾

如果需要的話, 你也可以使用同樣的方式回滾到舊的版本。 儘管 “blue” deployment 還在運行著, 可以直接更新 service 到舊的版本

kubectl apply -f services/hello-blue.yaml

一但你更新了服務, 回滾也就完成了。 再一次, 確認看看目前使用中的是否是正確的版本

curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

你做到了! 你已經學到 blue-green deployment 以及如何立即全部一次切換的部署方法



恭喜

你已經完成本教程!



Q&A

  • 以下的 deployment yaml 檔設定分別代表什麼意思?
    • deployment yaml:
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
      name: auth
      spec:
      replicas: 1
      template:
      metadata:
      labels:
      app: auth
      track: stable
      spec:
      containers:
      - name: auth
      image: "kelseyhightower/auth:1.0.0"
      ports:
      - name: http
      containerPort: 80
      - name: health
      containerPort: 81
    • Answer:
      # apiVersion: 版本, 會隨著版本而變動, 可參考[文件](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#-strong-api-overview-strong-)
      apiVersion: extensions/v1beta1
      # 種類, 可參考[文件](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#-strong-api-overview-strong-)
      kind: Deployment
      # 該 Deployment 的 metadata
      metadata:
      # 該 deployment 的 name
      name: auth
      # 該 deployment 運行的規格
      spec:
      # pod 數量
      replicas: 1
      # pod 樣板
      template:
      # pod 的 metadata
      metadata:
      # label, 可被 selector 挑選, 為 key/value pair
      labels:
      app: auth
      track: stable
      # pod 運行規格
      spec:
      # 定義容器
      containers:
      # 容器名稱
      - name: auth
      # 鏡像名稱
      image: "kelseyhightower/auth:1.0.0"
      # 定義 port
      ports:
      # port 名稱
      - name: http
      # port 號
      containerPort: 80
      # port 名稱
      - name: health
      # port 號
      containerPort: 81
  • 以下的 Kubernetes yaml 設定檔的意思是?

    • yaml 檔
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
      name: auth
      spec:
      replicas: 1
      template:
      metadata:
      labels:
      app: auth
      track: stable
      spec:
      containers:
      - name: auth
      image: "kelseyhightower/auth: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
    • Answer:
      # api 版本
      apiVersion: extensions/v1beta1
      # 種類為 Deployment
      kind: Deployment
      # Deployment 的 metadata
      metadata:
      # Deployment 的 name
      name: auth
      # 該 Deployment 運行的規格
      spec:
      # 該 Deployment 共會啟動幾個 Pod
      replicas: 1
      # 該 Pod 的詳細資料
      template:
      # 該 Pod 的 metadata
      metadata:
      # 該 Pod 的 label, 可透過 selector 被選取
      labels:
      # 自定義的 key/value pair
      app: auth
      track: stable
      # 該 Pod 的規格
      spec:
      # 容器規格
      containers:
      # 容器名稱
      - name: auth
      # 鏡像名稱
      image: "kelseyhightower/auth:2.0.0"
      # 該容器的 port 定義
      ports:
      # port 名稱
      - name: http
      # port 號
      containerPort: 80
      # port 名稱
      - name: health
      # port 號
      containerPort: 81
      # 容器的資源定義
      resources:
      # 限制
      limits:
      cpu: 0.2
      memory: "10Mi"
      # 存活探針
      livenessProbe:
      # 探測類型
      httpGet:
      # 探測路徑
      path: /healthz
      # 探測 port 號
      port: 81
      scheme: HTTP
      # 首次執行探針時需要延遲的時間, 以確保容器內各項工作都已準備就緒, 如果一啟動就探測的話很可能會直接失敗
      initialDelaySeconds: 5
      # 每隔 15 秒探測一次
      periodSeconds: 15
      # 探測時, 如果超過幾秒沒回覆視為失敗
      timeoutSeconds: 5
      # 就緒探針, 如果尚未就緒, service 不會將流量導向該容器
      readinessProbe:
      # 探測方式為 httpGet
      httpGet:
      # 探測 url
      path: /readiness
      # 探測 port 號
      port: 81
      # 使用 http 還是 https
      scheme: HTTP
      # 首次啟動 readinessProbe 時, 等待五秒
      initialDelaySeconds: 5
      # 若超過 1 秒沒有 response, 視為失敗
      timeoutSeconds: 1
  • 請解釋以下 kubernetes yaml file 中的每一條 directive

    • yaml file:
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
      name: frontend
      spec:
      replicas: 1
      template:
      metadata:
      labels:
      app: frontend
      track: stable
      spec:
      containers:
      - name: nginx
      image: "nginx:1.9.14"
      lifecycle:
      preStop:
      exec:
      command: ["/usr/sbin/nginx","-s","quit"]
      volumeMounts:
      - name: "nginx-frontend-conf"
      mountPath: "/etc/nginx/conf.d"
      - name: "tls-certs"
      mountPath: "/etc/tls"
      volumes:
      - name: "tls-certs"
      secret:
      secretName: "tls-certs"
      - name: "nginx-frontend-conf"
      configMap:
      name: "nginx-frontend-conf"
      items:
      - key: "frontend.conf"
      path: "frontend.conf"
    • Answer:
      # API 版本
      apiVersion: extensions/v1beta1
      # 種類為 Deployment
      kind: Deployment
      # 該 Deployment metadata
      metadata:
      # 該 Deployment name 為 frontend
      name: frontend
      # 該 Deployment 運行規格
      spec:
      # 啟動 1 個 pod
      replicas: 1
      # 該 pod 模板
      template:
      # 該 pod metadata
      metadata:
      # label, 可被 selector 選擇
      labels:
      app: frontend
      track: stable
      # 該 pod 運行規格
      spec:
      # 定義容器
      containers:
      # 容器名稱
      - name: nginx
      # 鏡像名稱
      image: "nginx:1.9.14"
      # 定義生命週期
      lifecycle:
      # preStop hook
      preStop:
      # hook handler 為 exec
      exec:
      # 執行指令, 用意為在停止前優雅退出 nginx
      command: ["/usr/sbin/nginx","-s","quit"]
      # 掛載 volume
      volumeMounts:
      # 使用的 volume name
      - name: "nginx-frontend-conf"
      # 掛載於容器內的位置
      mountPath: "/etc/nginx/conf.d"
      # 使用的 volume name
      - name: "tls-certs"
      # 掛載於容器內的位置
      mountPath: "/etc/tls"
      # 定義容器
      volumes:
      # 定義 volume name
      - name: "tls-certs"
      # volume 來源為 secret
      secret:
      # 使用的 secret name
      secretName: "tls-certs"
      # 定義 volume name
      - name: "nginx-frontend-conf"
      # volume 來源為 configMap
      configMap:
      # 使用的 configMap name
      name: "nginx-frontend-conf"
      # 指定該 configMap 內的 key
      items:
      # 取得 nginx-frontend-conf configMap 中的 frontend.conf 的 key
      - key: "frontend.conf"
      # 指定掛載後的位置
      path: "frontend.conf"
  • 請解釋以下 kubernetes yaml file 中的每一條 directive

    • yaml file:
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
      name: hello-canary
      spec:
      replicas: 1
      template:
      metadata:
      labels:
      app: hello
      track: canary
      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
    • Answer:
      # API 版本
      apiVersion: extensions/v1beta1
      # 種類為 Deployment
      kind: Deployment
      # 該 Deployment metadata
      metadata:
      # 該 Deployment name
      name: hello-canary
      # 該 Deployment 運行規格
      spec:
      # 啟動一個 pod
      replicas: 1
      # 該 Pod 範本
      template:
      # 該 pod 的 metadata
      metadata:
      # 定義 labels
      labels:
      app: hello
      track: canary
      version: 2.0.0
      # 該 pod 運行規格
      spec:
      # 定義容器
      containers:
      # 容器 name
      - name: hello
      # 使用鏡像
      image: kelseyhightower/hello:2.0.0
      # 定義 ports
      ports:
      # port name
      - name: http
      # 容器內的 port
      containerPort: 80
      # port name
      - name: health
      # 容器內的 port
      containerPort: 81
      # 定義資源限制
      resources:
      # 定義 limits 類型資源限制
      limits:
      cpu: 0.2
      memory: 10Mi
      # 定義存活探針
      livenessProbe:
      # 使用 httpGet 方式探測
      httpGet:
      # 指定探測的 path
      path: /healthz
      # 指定探測的 port
      port: 81
      # 指定探測的 scheme
      scheme: HTTP
      # 容器啟動後延遲五秒再開始探測
      initialDelaySeconds: 5
      # 每十五秒探測一次
      periodSeconds: 15
      # 超過五秒沒回應, 視為失敗
      timeoutSeconds: 5
      # 定義就緒探針
      readinessProbe:
      # 使用 httpGet 方式探測
      httpGet:
      # 指定探測的 path
      path: /readiness
      # 指定探測的 port
      port: 81
      # 指定探測的 scheme
      scheme: HTTP
      # 容器啟動後延遲五秒再開始探測
      initialDelaySeconds: 5
      # 超過五秒沒回應, 視為失敗
      timeoutSeconds: 1
  • 請解釋以下 kubernetes yaml file 中的每一條 directive

    • yaml file:
      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
    • Answer:
      # API version
      apiVersion: extensions/v1beta1
      # The kind is Deployment
      kind: Deployment
      # The metadata of the Deployment
      metadata:
      # The name of the Deployment
      name: hello-green
      # The spec
      spec:
      # Desired number of pod is 3
      replicas: 3
      # the template of the pod
      template:
      # the metadata of the pod
      metadata:
      # labels, could be selected by selector
      labels:
      app: hello
      track: stable
      version: 2.0.0
      # spec of the pod
      spec:
      # define containers
      containers:
      - name: hello
      image: kelseyhightower/hello:2.0.0
      # define ports
      ports:
      - name: http
      containerPort: 80
      - name: health
      containerPort: 81
      # define constraint resources
      resources:
      limits:
      cpu: 0.2
      memory: 10Mi
      # define liveness probe
      livenessProbe:
      # use httpGet probe
      httpGet:
      path: /healthz
      port: 81
      scheme: HTTP
      # wait for 5 seconds after the container starts before starting to probe
      initialDelaySeconds: 5
      # probe every 15 seconds
      periodSeconds: 15
      # consider it fails if not get responses for 5 seconds
      timeoutSeconds: 5
      # define readiness probe
      readinessProbe:
      httpGet:
      path: /readiness
      port: 81
      scheme: HTTP
      initialDelaySeconds: 5
      timeoutSeconds: 1
  • 請解釋以下 kubernetes yaml file 中的每一條 directive

    • yaml file:
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
      name: hello
      spec:
      replicas: 3
      template:
      metadata:
      labels:
      app: hello
      track: stable
      version: 1.0.0
      spec:
      containers:
      - name: hello
      image: "kelseyhightower/hello:1.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
    • Answer:
      # API 版本
      apiVersion: extensions/v1beta1
      # 種類為 Deployment
      kind: Deployment
      # the metadata of the deployment
      metadata:
      # define the deployment name
      name: hello
      # define the spec of the deployment
      spec:
      # it will start 3 pods
      replicas: 3
      # define the template of the pod
      template:
      # define the metadata of the pod
      metadata:
      # define teh labels, which could be selected by Selector
      labels:
      app: hello
      track: stable
      version: 1.0.0
      # define the spec of the pod
      spec:
      # define containers
      containers:
      # define container name
      - name: hello
      # used image
      image: "kelseyhightower/hello:1.0.0"
      # define ports
      ports:
      # define port name
      - name: http
      # define port inside the container
      containerPort: 80
      # define port name
      - name: health
      # define port inside the container
      containerPort: 81
      # define resources
      resources:
      # define limits resources
      limits:
      cpu: 0.2
      memory: "10Mi"
      # define liveness probe
      livenessProbe:
      # using httpGet probe
      httpGet:
      # define probe path
      path: /healthz
      # define probe port
      port: 81
      # define probe scheme
      scheme: HTTP
      # the liveness probe will start to probe 5 seconds after the container starts
      initialDelaySeconds: 5
      # probe every 15 seconds
      periodSeconds: 15
      # if the probe doesn't receive responses for 5 seconds, it's considered failed
      timeoutSeconds: 5
      # define readiness probe
      readinessProbe:
      # use httpGet probe
      httpGet:
      # specify probe path
      path: /readiness
      # specify probe port
      port: 81
      # specify probe scheme
      scheme: HTTP
      # the readiness probe will start to probe 5 seconds after the container starts
      initialDelaySeconds: 5
      # if the probe doesn't receive responses for 5 seconds, it's considered failed
      timeoutSeconds: 1
  • 請解釋以下 kubernetes yaml file 中的每一條 directive
    • yaml file:
      kind: Service
      apiVersion: v1
      metadata:
      name: "auth"
      spec:
      selector:
      app: "auth"
      ports:
      - protocol: "TCP"
      port: 80
      targetPort: 80
    • Answer:
      # 種類為 Service
      kind: Service
      # API 版本為 v1
      apiVersion: v1
      # 此 Service 的 metadata
      metadata:
      # 此 Service 的 name
      name: "auth"
      # 此 Service 的運行規格
      spec:
      # 可選擇指定 label, 並將流量導向這些 pod
      selector:
      app: "auth"
      # 定義 port
      ports:
      # 使用 TCP protocol
      - protocol: "TCP"
      # service 的 port 為 80
      port: 80
      # 目標對象的 port 為 80
      targetPort: 80
  • 請解釋以下的 kubernetes yaml file 中的每一條 directive
    • yaml file:
      kind: Service
      apiVersion: v1
      metadata:
      name: "monolith"
      spec:
      selector:
      app: "monolith"
      secure: "enabled"
      ports:
      - protocol: "TCP"
      port: 443
      targetPort: 443
      nodePort: 31000
      type: NodePort
    • Answer:
      # 種類為 Service
      kind: Service
      # API 版本為 v1
      apiVersion: v1
      # 該 service 的 metadata
      metadata:
      # 該 service name
      name: "monolith"
      # 該 service 運行規格
      spec:
      # 會將流量導向符合此 label 的 pod
      selector:
      app: "monolith"
      secure: "enabled"
      # 定義 ports
      ports:
      # protocol 為 TCP
      - protocol: "TCP"
      # service 的 port 為 443
      port: 443
      # 目標對象的 port 為 443
      targetPort: 443
      # 定義 node 的 31000 port 將流量導向 service 的 clusterIP
      nodePort: 31000
      # 使用 NodePort
      type: NodePort
  • 請解釋以下的 Kubernetes yaml file 中的每一條 directive
    • yaml file
      kind: Service
      apiVersion: v1
      metadata:
      name: "frontend"
      spec:
      selector:
      app: "frontend"
      ports:
      - protocol: "TCP"
      port: 443
      targetPort: 443
      type: LoadBalancer
    • Answer:
      # kind is service
      kind: Service
      # api version is v1
      apiVersion: v1
      # the metadata of the serivice
      metadata:
      # the name of the service
      name: "frontend"
      # the spec of the service
      spec:
      # those selected by this selector will be the endpoint to which the traffic is redirected
      selector:
      # an arbitrary key / value pair
      app: "frontend"
      # define ports
      ports:
      # define the protocol
      - protocol: "TCP"
      # define service port
      port: 443
      # define target endpoint' ports
      targetPort: 443
      # this option is only for cloud provider
      type: LoadBalancer
Laravel - The Basics - Middleware (官方文件原子化翻譯) Kubernetes - Deployments (官方文件原子化翻譯筆記)

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×