Kubernetes - Storage 學習紀錄

Posted by Kubeguts on 2021-05-23

透過k8s所管理的pods,因為是container的形式,其儲存的資料在未經特別設定之下,是不會永久存放在硬碟中

若需要儲存之,需要設置Storage,透過Volumes方式將Pods的要儲存的檔案系統目錄,映射到實體機器上,才能夠再重新啟動Pod的時候,儲存的資料才能夠繼續保持,不會消失

Volumes : 提供暫時的儲存空間

在K8S中的Storage,都指稱是volumes

  • volumes映射到儲存的目錄位置
  • 必須要有獨特的名字,不能重複
  • 隨著類型不同而有不同的生命週期
  • volume mount表示要指引一個volume到一個實體目錄

Volumes 兩種常用種類 emptyDir & hostPath

emptyDir

  • 設置一個初始化為空的的資料夾,
  • 資料存在節點上,只能被單一的Pod讀取
  • 生命週期與Pod綁定一起,Pod刪除,儲存在Volume的資料也刪除
  • 應用在容器間的檔案共享

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
name: docker-volume
spec:
volumns: # 定義初始化的Volume資料夾為html
- name: html
- emptyDir: {}
containers:
- name: nginx
image: nginx:alpine
# 將這個container mount到volumn名稱為html
# 並只能限制該volumn資料夾為readonly
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true

hostPath

  • 設置一個已經存在於Node的資料夾
  • 可被多個於相同Node底下的Pods存取
  • 生命週期與Node綁定,節點刪除檔案即刪除
  • 是用在節點範圍內的容器間檔案共享

範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: docker-volume
spec:
volumns: # docker-socket
- hostPath:
path: /var/run/docker.sock
type: Socket
containers:
- name: docker
image: docker
command: ["sleep"]
args: ["100000"]
volumeMounts:
- name: docker-socket
path: /var/run/docker.sock
type: Socket

Volumes 其他種類

  • persistentVolumeClaim: 提供Pods一個持久的儲存選項
  • nfs: 為Pod之間共享的Network File System
  • configMap/secret: 提供pod可以存取k8s的資源
  • cloud: 像是aws, azure, gcp的雲端空間

PersistentVolumeClaims (PVC) 與 PersistentVolumes (PV)

PVC與PV都提供給容器們可以永久儲存資料選項,但在K8S的機制中,需要了解配置一個永久儲存機制時,需要釐清PVC與PV這兩個角色是什麼

  1. PersistentVolume

    • 給開發人員使用,不用曉得底層如何實作分配空間的細節
    • 一種可存取Network_Attached Storage (NAS)的資源
    • 由系統管理員所提供
    • 必須由PersistentVolumeClaims才能夠存取儲存資源
  2. PersistentVolumeClaims

    • 給維運人員使用,可得知儲存空間的實現細節
    • 維運人員可以手動或使用StorageClass自動配置
    • 向PersistentVolume提出請求

可以清楚了解到,PV就是預先配置好容量,PVC就是制定要選擇哪個PV

以現實生活的旅館來比喻

  • 一整間旅館就是Storage
  • 每種不同的房型對應的就是各種不同的PV
  • PVC則是入住的方案
    • 每個方案(PVC)對應的就是可以使用的房型們(PV)

pic14

範例

定義PV的範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi # 定義PV的儲存容量
volumeMode: Filesystem
# 定義節點存取的模式
accessModes:
- ReadWriteOnce # 可被一個Node進行Read或Write的動作
- ReadOnlyMany # 可被多個Node進行Read的動作
- ReadWriteMany # 可被多個Node進行Read或Write的動作
# 可定義PV是否刪除後還會存留著
# Retain: Volume可被重複利用
# Recycle: PV刪除後,綁定Volume也跟著刪除
# Delete: Volume相關的Storage內容(例如在AWS EBS, GCE PD, Azure Disk)會跟著被刪除
# 綁定的Storage
nfs:
path: /tmp
server: 172.17.0.2

定義PVC範例

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: front-pvc-5g
namespace: myns
spec:
accessModes:
- ReadWriteOnce
storageClassName: "" # 須設置空字串,否則會使用預設的StorageClass
resources: # 宣告要多少資源
requests:
storage: 5Gi

在Pod中設定要使用PVC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: frontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
# 宣告Volumes,並指定使用的PVC
volumes:
- name: mypd
persistentVolumeClaim:
claimName: front-pvc-5g # 根據PVC的metadata

StorageClasses

StorageClass為一種可產生PV的樣板,可以用來動態配置儲存空間

使得系統管理員不用事先配置PV,就可以透過StorageClass將PVC與自動創建出來的PV做綁定

範例

  1. 創建StorageClass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
# 若PVC沒有被使用,採取的動作,通常用Retain,會保留
# 沒設置的話預設為Delete
recliamPolicy: Retain
# 會使用的Volume Plugin,來幫助產生PV,並與PVC綁定
provisioner: kubernetes.io/no-provisionoer
# 綁定PV與PVC的動作
# WaitForFirstConsumer: 直到有Pod使用某PVC,才會綁定PV到對應的PVC
# Immediate (預設值): 若PVC產生,就會直接產生PV並綁定
volumeBindingMode: WaitForFirstConsumer
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true # 決定是否能夠延展PVC
  1. K8S使用StorageClass Provisioner來自動配置PersistentVolume,並參照到StorageClass

產生的yaml檔案如下,會指名是哪個StorageClass產生的

1
2
3
4
5
6
7
8
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
namespace: myns
spec:
storageClassName: local-storage # 指定StorageClass
...
  1. 且Storage也被K8S創建出來,然後將PV參照到Storage,然後PV在綁定到PVC

  2. 記得要在PersistentVolumeClaim中參照要麻煩哪個StorageClass

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: front-pvc-5g
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
storageClassName: local-storage # 使用創建好的StorageClass名稱
resources:
requests:
storage: 5Gi
  1. 最後將Pod的volume指引到PVC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: frontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: front-pvc-5g

可以看到Pod只要指定PVC就好,StorageClass,就會自動產生PV與PVC的綁定

PVC、PV、StorageClass互動示意圖

上層 (1->4) 為手動配置PV

下層 (A->C) 為配置好StorageClass後,會自動產生PV並掛載至PVC

pic15

參考