Docker 有 yaml,K8s 也有 yaml,兩者都是 yaml,為甚麼完全不同呢?這個就不深究了,但兩者的 yaml 不能共用,已經確認過,所以有必要了解 K8s 是怎樣用 yaml 檔,Docker 那邊忘掉吧。
Kubernetes Object 及 Kubernetes API 不需要太深入研究,稍微知道是甚麼就夠,實戰才是本文重點。
為求方便,這篇用 Google Cloud Shell ( GCS ),不用 Google Cloud SDK 版本,因為 kubectl 之前給 Docker for CE 佔用了,把設定改回來很麻煩,之後的文章,應該會改回用本機 Shell。
Google Cloud 快速入門
https://cloud.google.com/kubernetes-engine/docs/quickstart#choosing_a_shell
yaml 語法
https://javatoybox.blogspot.com/2019/01/kubernetes-yaml.html#try-docker-compose
———————————簡易的分隔線————————————
Kubernetes Object︰
結構圖所示,kubectl 跟 API Server 溝通,怎溝通呢?kubectl 建立 API request ( JSON ) 與 API API Server 溝通,然後生成【Kubernetes Object】。
那麼……用甚麼轉成 JSON 格式呢?那就是 yaml,yaml 可以轉換成 JSON,但 API Server 也是有要求的,在 request 中,一定要包含 apiVersion、kind 及 metadata 三種資料。
上圖嚴格來說並不正確,因為使用 Google Cloud Shell,等於透過 browser 把 command 送過去 Google 那邊的 kubectl 執行,不過算了吧,要做的事情還是一樣 ( kubectl --> API Server --> Kubernetes Object )。
Describing a Kubernetes Object
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#describing-a-kubernetes-object
What is the difference between YAML and JSON? When to prefer one over the other
https://stackoverflow.com/questions/1726802/what-is-the-difference-between-yaml-and-json-when-to-prefer-one-over-the-other
———————————簡易的分隔線————————————
Kubernetes API︰
現在應該知道,為甚麼每個 K8s 的 yaml 都會有 apiVersion 及 kind 作為開頭,但他們的關係是甚麼?
在 Cloud Shell 輸入 command︰
- kubectl version
會有 major 及 minor 等資訊,這代表現在 kubectl client 及 server 版本,這決定 yaml 可以用甚麼 apiVersion,例如以下官方例子,有註解說如何修改 apiVersion 參數,對應不同版本的 kubectl。
https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/#creating-and-exploring-an-nginx-deployment
Kube <major>.<minor>.<patch>
https://github.com/kubernetes/kubernetes/blob/release-1.1/docs/design/versioning.md
Kubernetes API reference
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#pod-v1-core
———————————簡易的分隔線————————————
Container Registry︰
除了 apiVersion、kind 及 metadata 三種資料,而最重要的 image 從何而來?公開 image,從 Docker hub 來,而 private registry,需另外設定,這裡不會詳述,本人鼓勵 Open Source,怎會教人把東西收起來,要學就看官網。
Use Cases
https://kubernetes.io/docs/concepts/containers/images/#use-cases
Quickstart for Container Registry
https://cloud.google.com/container-registry/docs/quickstart
Private registry
https://kubernetes.io/docs/concepts/containers/images/#configuring-nodes-to-authenticate-to-a-private-registry
———————————簡易的分隔線————————————
YAML︰
稍微了解過 Kubernetes Object、Kubernetes API 及 Container Registry,現在到編寫 yaml。
Pod︰
從最基本玩起,首先來個 derby 試一試。
第一行【---】是 Document header,第二到第四行是必要項目。
- apiVersion︰在 Kubernetes API 一節介紹過。
- kind︰對應 apiVersion,定義這個 yaml 檔建立甚麼 Object,例如 Pod、Deployment、Ingress 等等。
- metadata︰給這個 Object 附加資訊。
spec︰specification 簡寫,詳細定義要這 Object 做甚麼。
image︰如果沒特別設定,預設在 Docker Hub 下載 image,可以去 Docker Hub 看看有沒有公開 dockerfile ,有公開的話,最好看一看內容,例如入面有沒有設定 volume,有沒有 CMD 等等。跟據上面 yaml 第九行,在瀏覽器上開啟 https://hub.docker.com/r/integrityknight/derby 應該會去到 Repo 主頁,查一下有沒有重要資訊。
lifecycle︰其實只要第六到第九行就可以,這個定義建立 container 前後,要做甚麼動作,以 database 為例,關閉前應該要 disconnect,這樣才不會有之前的 lock 問題,不過今次沒用 Persistent volumes,重新建立 Pod 時就會還原,所以沒所謂吧?
YAML 1.1 Reference card
https://yaml.org/refcard.html
Pod Templates
https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/#pod-templates
Deployments︰
現在改造 Pod 成 Deployment,用 Deployment 有甚麼好處?
Replication︰
假如有個 Pod 突然死了,會有其他 Pod 會承接,做到無間斷服務,算做 fault tolerance 的一環。
Rolling Update / Rolling Back︰
Deployment
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
———————————簡易的分隔線————————————
改造 Pod 成 Deployment︰
紅框是修改後結果,要把 kind 改成 Deployment,先要改 apiVersion 成 apps/v1,而 labels 給這個 deployment 一個名稱。
replicas︰定義用兩個 Pod 做 Replication。
selector︰重點來了,入面有一個叫 matchLabels 項目,這個設定一定要跟 template 內 labels 一致才會生效!
template︰把之前 Pod 的 spec 都搬進去,再加點 metadata。記謹!yaml 必須層次分明及只能用空白鍵,不能用 Tab,所以抄的時候不要忘記對齊位置。
———————————簡易的分隔線————————————
上傳 yaml 到 GCP︰
開啟 GCS 上傳 yaml 檔案。
檔案在 userhome,打 ls -a 可看到。
———————————簡易的分隔線————————————
使用 YAML 建立 Pod / Deployment︰
之前講解過 yaml 內寫了甚麼,是時候驗證一下是否正確,首先用 pod-demo.yaml 做示範。
上傳完檔案後,使用 yaml 在 GCS 建立 Pods,command 如下︰
- kubectl create -f pod-demo.yaml
- kubectl get pod k8s-derby-demo
- kubectl exec -it k8s-derby-demo /bin/sh
——————————— ( 補充 start ) ————————————
操作 Derby ︰
以前文章有介紹過 Derby,可看參考 連結 回顧。
以 Derby 內建 ij 測試︰
- java org.apache.derby.tools.ij
- connect 'jdbc:derby://localhost:1527/FirstDB';
- SELECT id, actor, product FROM acg_character.profile;
- disconnect;
- exit;
測試 Deployment ︰
Pod 有的東西,deployment 也有,主要測試 Replication 及 Rolling Update / Rolling Back 是否如之前所說那麼神奇。首先,以上傳的 yaml 做 deployment,謹記加 --record,這個會記錄到 rollout history 中,對 Roll back 有幫助,追溯之前做過甚麼︰
- kubectl create -f deployment-demo.yaml --record
- kubectl get pods
Replication︰
假設,在 Database 加一筆資料後,兩邊 Pod 應該會同步更新。故意弄死一隻 Pod,看看會否同步。
在其中一隻 pod 加一筆資料︰
- kubectl exec -it k8s-deployderby-demo-6bc844ccbb-gwvhf /bin/sh
- java org.apache.derby.tools.ij
- connect 'jdbc:derby://localhost:1527/FirstDB';
- SELECT id, actor, product FROM acg_character.profile;
- INSERT INTO acg_character.profile (actor, product) VALUES ('Leon', 'resident evil');
- SELECT id, actor, product FROM acg_character.profile;
- kubectl delete pods k8s-deployderby-demo-6bc844ccbb-gwvhf
進入另一隻 pod 查看結果
- kubectl exec -it k8s-deployderby-demo-6bc844ccbb-bszvm /bin/sh
- java org.apache.derby.tools.ij
- connect 'jdbc:derby://localhost:1527/FirstDB';
- SELECT id, actor, product FROM acg_character.profile;
對不起,沒有更新,這個假設是錯誤,需要把資料及資料庫程式分開, Pod 只提供服務所以只裝資料庫程式,資料要放 Persistent Volumes,通過 Pod 讀寫資料。
再看一次現在 pods,發現會自動再生一個 pod 補上空缺。
- kubectl get pods
——————————— ( 補充 start ) ————————————
Deployment 及 StatefulSets
簡單點說,Deployment 用來處理 stateless 應用,StatefulSets 用來處理 Database 讀寫。例如開放給公眾查詢資料,只用到讀取,可以用 Deployment 做,而公司職員需要輸入資料,用到寫入,這時候該用 StatefulSets 建立 Pod。
StatefulSets in GKE
https://cloud.google.com/kubernetes-engine/docs/concepts/statefulset
——————————— ( 補充 end ) ————————————
Rolling Update / Rolling Back︰
說起 Update 及 Roll back,其實在做甚麼?只是把 image 更新,要 update image 內容的話,需要重新寫過 dockerfile,上傳到 Docker Hub。
Rolling Update︰
command 詳細不說,請對比 yaml 檔。
- kubectl set image deployment.v1.apps/k8s-deployderby-demo k8s-deployderby-demo-container=integrityknight/derby:v10.14.2.0 --record
Rollout history︰
如上圖,有 revision 號碼,這個數字可以用在 Rolling back 上,順帶一提,預設記錄數是十個。
- kubectl rollout history deployment.apps/k8s-deployderby-demo
Rolling Back︰
不多說,看圖。
- kubectl rollout undo deployment.apps/k8s-deployderby-demo --to-revision=1
Updating a Deployment
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment
Rolling Back a Deployment
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment
———————————簡易的分隔線————————————
總結︰
再來個 Persistent Volumes 完成 k8s 系例文章。
下一回【Volumes、Persistent Volumes 及 Persistent Volumes Claims】
沒有留言:
發佈留言
設有留言驗證及審查,檢閱後,才會顯示留言。
本人惰性很高,留言或許會石沉大海。