用過 GCP 建立 Pod 及 Service,也試過寫 yaml,差 Persistent Volumes 就完成基本中的基中 k8s 運用……
對,只是運用,離 production 還有不少距離……
Volumes 跟 Pod 共生死, Persistent Volumes 與 Cluster 共生死,因此,Pod 用 Persistent Volumes 的話,就算 Pod 死,資料也可以續存,只要再建立一隻新 Pod,掛載 Persistent Volumes。
Persistent Volumes 與 Persistent Volumes Claims 關係
Volumes = 暫存
Persistent Volumes = 硬碟
Persistent Volumes Claims = 分割硬碟
會電腦硬件,沒更貼切比喻!
Persistent Volumes
故事是這樣,假設這個地球村,硬碟存在於世界某個角落……
那麼硬碟實際位置放在哪裡?容量有多少?
Persistent Volumes 由你定義,由不同地區組合而成的一個虛擬硬碟,100 GB 在美國,200 GB在香港,700 GB在日本之類,容量定義多少就有多少,實際上由增加實體硬碟而來。
Persistent Volumes 是 Cluster 資源之一,所以刪除 cluster 的話,Persistent Volumes 也會消失。
Persistent Volumes Claims
因為在 Cluster 入面,虛擬硬碟只能有一個,也不是之前說容量要多少有多少 ( 除非錢真的要多少有多少,容量要用錢買 ),所以要分割出儲存空間,在有限容量中,定義出個別用途,例如 mount 一個叫【testdata】的 Path 做 database 儲存測試,一個叫【realdata】的 Path 儲存客戶資料。
Persistent Volumes Claims 會向 Persistent Volumes 提出申請,要求 mount 一個路徑做永續儲存,當 Pod 不幸崩潰,也不致於資料消失。還可以作為 Pod 與 Pod 之間共享資料之用。
———————————簡易的分隔線————————————
選擇 Persistent Volumes︰
GCP 支援很多種 Persistent Volumes 方案,不一定要 Google 自家服務,常用方案如下︰
- GCEPersistentDisk ( Google )
- AzureDisk ( Microsoft )
- AWSElasticBlockStore ( Amazon )
- NFS ( 自我建設 )
用 NFS 不代表不用付鈔,GCP 流量要計錢!另外,也會影響 access modes,有些選擇沒 ReadWriteMany 支援,不能同時多個 Pod 用同一個 PersistentVolumeClaim,即是說 Database 讀寫應用的話,該去想一下 StatefulSet 怎用。
Types of Persistent Volumes
———————————簡易的分隔線————————————
安裝 Google Cloud SDK 及 Components︰
官方教學很詳細,跟著做就完成。
https://cloud.google.com/sdk/?hl=zh-tw
打指令【gcloud components list】列出元件狀態,預設 kubectl 沒有安裝,所以請跟官方教學安裝,可以先設定好 kubectl config 才去安裝。
安裝元件
https://cloud.google.com/sdk/docs/components?hl=zh-tw
——————————— ( 附加資訊 start) ————————————
kubectl config file
假如之前在 Docker 上開過 Kubernetes,需要選擇 context,kubectl 才可連接上 GCP,前提要在網頁版 console GCP 設定好 Cluster,才做以下動作︰
- gcloud auth login
- gcloud init
- gcloud container clusters get-credentials [CLUSTER-NAME] --zone [ZONE] --project [PROJECT-ID]
eg. gcloud container clusters get-credentials tomee-test --zone us-central1-a --project k8s-first-trials
——————————— ( 附加資訊 end ) ————————————
在 GCP 設定 Persistent Volumes︰
如果用 GCEPersistentDisk,在建立 Cluster 同時,會自動設定好 ( 可能是免費方案附贈的 ),所以不用設定。
StorageClass
https://kubernetes.io/docs/concepts/storage/storage-classes/#the-storageclass-resource
———————————簡易的分隔線————————————
在 GKE 上使用 Persistent Volumes︰
![]() |
Windows k8s |
![]() |
Ubuntu k8s |
整個流程如下 ( 強烈建議用 Ubuntu,Windows 出問題,本人無法解決 )︰
- 定義 Persistent Volumes Claims
kubectl apply -f tomee-derby-pvc.yaml - 建立 Pod 及使用 Persistent Volumes Claims
kubectl create -f k8s-copyfile-pod.yaml - 由 local computer 抄資料進 Persistent Volumes
kubectl cp Database k8s-copyfile-pod:/
( Windows 版本有 Bug 抄不進去 / ,在 Linux 這 command 可用
請用 kubectl exec -it k8s-copyfile-pod -c destination-container -- /bin/bash 自已修正路徑 )
kubectl cp webapps k8s-copyfile-pod:/usr/local/tomee/ - 刪除 Pod 及建立 deployment 使用 Persistent Volumes Claims
kubectl delete -f k8s-copyfile-pod.yaml
kubectl create -f k8s-deployment.yaml - 建立 Service 做測試
kubectl apply -f k8s-deploy-demo-service.yaml - 測試結果
【Database】及【webapps】資料可於 Github 下載
需要用到的 yaml 檔案如下︰
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | |
apiVersion: v1 | |
kind: Pod | |
metadata: | |
name: k8s-copyfile-pod | |
spec: | |
containers: | |
- name: destination-container | |
image: integrityknight/tomee-derby:1.0.1 | |
volumeMounts: | |
- name: tomee-derby | |
mountPath: /Database | |
subPath: derby | |
- name: tomee-derby | |
mountPath: /usr/local/tomee/webapps | |
subPath: webapps | |
volumes: | |
- name: tomee-derby | |
persistentVolumeClaim: | |
claimName: tomee-derby-pvc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
apiVersion: "v1" | |
kind: "Service" | |
metadata: | |
name: "k8s-deploy-demo-service" | |
namespace: "default" | |
labels: | |
app: "tomee-derby-demo" | |
spec: | |
ports: | |
- protocol: "TCP" | |
port: 8080 | |
selector: | |
app: "tomee-derby" | |
type: "NodePort" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
name: k8s-deploy-demo | |
labels: | |
app: tomee-derby-demo | |
spec: | |
replicas: 2 | |
selector: | |
matchLabels: | |
app: tomee-derby | |
template: | |
metadata: | |
labels: | |
app: tomee-derby | |
spec: | |
containers: | |
- name: k8s-tomee-derby-demo-container | |
image: integrityknight/tomee-derby:1.0.1 | |
volumeMounts: | |
- name: tomee-derby | |
mountPath: /Database | |
subPath: derby | |
- name: tomee-derby | |
mountPath: /usr/local/tomee/webapps | |
subPath: webapps | |
volumes: | |
- name: tomee-derby | |
persistentVolumeClaim: | |
claimName: tomee-derby-pvc | |
# Creating a Deployment | |
# https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
apiVersion: v1 | |
kind: PersistentVolumeClaim | |
metadata: | |
name: tomee-derby-pvc | |
labels: | |
app: tomee-derby-demo | |
spec: | |
accessModes: | |
- ReadWriteOnce | |
resources: | |
requests: | |
storage: 2Gi |
編寫 Persistent Volumes Claims 注意事項︰
- 一個 Pod 想 blinding 有多個 mount path,要用 subPath
- 一個 Pod 不能有相同 docker image 的 container
- 一個 PV 只能有一個 PVC
- 多個 Pod 可用同一個 PVC
- 如上圖,同顏色為一組,假如多個 pod 要用同一個 pvc,pvc 名稱一定要一樣 ( 紅框部份 )
總結︰
還有問題!如果 delete pod 後,重做一次,測試時會有 error code 500!為甚麼?因為 delete pod 不保證安全關閉,所以會有 database 留下 lck 檔案問題。yaml 不要用 deployment,試試用 stateFulSet 吧!