volume 這個概念在 Docker 的時候蠻常使用的,像本地開發的時候會跑 Docker mySQL 就會把資料庫相關就會 local 和 container 對等。 \ 而 k8s 在這塊有很多種的作法,Pod本身預設是放在每台 Node 裡,就是本身的啟動盤。
常見的幾種 Volumn
configMap
算是最常使用到的功能,例如:每個服務的 .env
檔案
一樣先創立 ConfigMap 才能綁定在 Pod 中
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
---
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
- name: PLAYER_INITIAL_LIVES
valueFrom:
configMapKeyRef:
name: game-demo
key: player_initial_lives
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
- name: config
configMap:
name: game-demo
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
emptyDir
每個 emptyDir 在 Pod 分派到 Node 中時會自動生成,當 Pod 被刪除時 emptyDir 中的 data 也會永久刪除
例外原因:若 container cash 的狀態 但是 Pod 還存在,資料其實還在 emptyDir 中
emptyDir 使用時機
- 暫時性儲存空間 : 某些服務運行時需要臨時而無需永久保存的資料夾
- 共用儲存空間 : 同一個 Pod 中所有 container 都可以讀寫 emptyDir
官網有大略介紹很多種 Storage,官網介紹連結
gcePersistentDisk
如果遇到 volume 需要持久化,就要找看看有哪些方式連結 持久化選擇,我自己最常用的公有雲就是 GCP 了,所以我特別介紹一下這個。
# 要先在 gcp 上建立 一個 Storage
# gcloud compute disks create --size=<size> --zone=<zone> <diskName>
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
gcePersistentDisk:
pdName: my-data-disk # GCE PD Name
fsType: ext4
相關的設定方式可以看 GCP 最新相關文檔
持久 Volumn 的使用方式
StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard # 與 PVC storageClassName 必須相同
provisioner: kubernetes.io/gce-pd # 這邊選用的是 GCP 供應商
parameters:
type: pd-standard
fstype: ext4
reclaimPolicy: Retain # 回收機制 - Retain 不使用 StorageClass 時,需手動刪除資料 / Delete (default) 不使用 StorageClass 時,移除資料
allowVolumeExpansion: true # 自動擴展 - (只允許擴不允許縮)
mountOptions:
- debug
volumeBindingMode: Immediate # 卷绑定模式 - WaitForFirstConsumer 延遲 PV 綁定和製備,直到使用該 PVC 的 Pod 被創建 (AWS/GCP/Azure 有支援而已)/ Immediate (default) 建了 PVC 就完成了volumn綁定
PersistentVolumeClaim (持久卷聲明)
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: claim
spec:
accessModes:
- ReadWriteOnce # ReadWriteOnce(RWO)一個Node讀寫, ReadOnlyMany(ROX) 多個Node讀, ReadWriteMany(RWX) 多個Node讀寫
volumeMode: Filesystem # https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#binding-block-volumes
resources:
requests:
storage: 8Gi # 需求空間為 8Gi
storageClassName: standard # 與 SC metadata.name 必須相同 預設是空白,K8s會自動找最適合的 SC
PersistentVolume (持久化卷)
像是上方的 gcePersistentDisk
就是其中的一個選項
我這邊推薦是直接由 PVC 建立 會自己建立一組 PV
結語:
開頭的 configMap
其實在文檔的中的 volumn 就先出現了,下一篇 Configuration 也會重新寫一次相關的資料。
掛載 volumn 其實是一個非常常見到的東西,蠻多監控系統會將Log輸出至持久盤,將資料抓取走這樣,我覺得是一個蠻重要的功能。
我最常使用的公有雲是GCP,在建置GKE時會有啟動盤,就是預設給Node本身的資源,我是比較少動到啟動盤,除了一些configMap
的用途而已。