k8s儲存卷,pv和pvc
儲存卷
容器磁碟上的檔案的生命週期是短暫的,這就使得在容器中執行重要應用時會出現一些問題。首先, 當容器崩潰時,kubelet會重啟它,但是容器中的檔案將丟失容器以乾淨的狀態 (映象最初的狀態)重新啟動。其次,在Pod中同時執行多個容器時,這些容器之間通常需要共享檔案。Kubernetes 中的Volume抽象就很好的解決了這些問題。Pod中的容器通過Pause容器共享Volume。
emptyDir儲存卷
當Pod被分配給節點時,首先建立emptyDir卷,並且只要該Pod在該節點上執行,該卷就會存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以讀取和寫入emptyDir卷中的相同檔案,儘管該卷可以掛載到每個容器中的相同或不同路徑上。當出於任何原因從節點中刪除 Pod 時,emptyDir中的資料將被永久刪除。 mkdir shiyan cd /shiyan vim pod4.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx1 image: nginx ports: - name: http containerPort: 80 volumeMounts: #定義容器掛載內容 - name: html #使用儲存卷名稱,如果跟下面volume欄位name值相同,則表示使用volume的這個儲存卷 mountPath: /usr/share/nginx/html/ #掛載至容器中哪個目錄 - name: nginx2 image: nginx volumeMounts: - name: html mountPath: /data/ command: ['/bin/bash','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done'] volumes: - name: html emptyDir: {} kubectl exec -it nginx -c nginx2 sh #-c指定pod裡面的容器名進入
hostPath儲存卷
hostPath卷將 node 節點的檔案系統中的檔案或目錄掛載到叢集中。 hostPath可以實現持久儲存,但是在node節點故障時,也會導致資料的丟失。 在 node01 節點上建立掛載目錄 mkdir -p /data/pod/ echo 'node1.com' > /data/pod/index.html 在 node02 節點上建立掛載目錄 mkdir -p /data/pod/ echo 'node2.com' > /data/pod/index.html 建立 Pod 資源 vim pod5.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx volumeMounts: #定義容器掛載內容 - name: html #使用儲存卷名稱於volume定義 的name相同 mountPath: /usr/share/nginx/html/ #定義容器內的掛載目錄 readOnly: false #讀寫掛載方式,預設為讀寫模式false volumes: - name: html #定義儲存卷名稱 hostPath: #路徑,宿主機儲存路徑 path: /data/pod/ #在宿主機上目錄的路徑 type: DirectoryOrCreate #定義型別,如果宿主機沒有此目錄會自動建立 kubectl get pods -o wide curl 10.244.2.6 #刪除pod重建檔案內容依然存在,直接修改主機內的目錄也可以
nfs共享儲存卷
在新節點(node3)安裝nfs並配置服務 mkdir /data/pod -p chmod 777 /data/pod/ echo 'node3' > /data/pod/index.html vim /etc/exports /data/pod 192.168.150.0/24(rw,no_root_squash) systemctl start rpcbind systemctl start nfs showmount -e Export list for localhost.localdomain: /data/pod 192.168.150.0/24 master節點操作,k8s叢集需要新增主機名對映 vim pod6.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html nfs: #指定掛載型別為nfs path: /data/pod/ server: stor03 #指定nfs伺服器名,只能是主機名不能為IP地址
PVC和 PV
PersistentVolume(PV)是叢集中已由管理員配置的一段網路儲存。叢集中的資源就像一個節點是一個叢集資源。
PV是諸如卷之類的卷外掛,但是具有獨立於使用PV的任何單個pod的生命週期。
該API物件捕獲儲存的實現細節,即NFS、iSCSI或雲提供商特定的儲存系統。
PersistentVolumeclaim(PVC)是使用者儲存的請求。PVC的使用邏輯∶在pod中定義一個儲存卷(該儲存卷型別為PVC),定義的時候直接指定大小,pvc必須與對應的pv建立關係,pvc會根據定義去pv申請,而pv是由儲存空間創建出來的。pv和pvc是kubernetes抽象出來的一種儲存資源。
雖然PersistentVolumeClaims允許使用者使用抽象儲存資源,但是常見的需求是,使用者需要根據不同的需求去建立PV,用於不同的場景。而此時需要叢集管理員提供不同需求的PV,而不僅僅是PV的大小和訪問模式,但又不需要使用者瞭解這些卷的實現細節。對於這樣的需求,此時可以採用StorageClass資源(動態)。
PV是叢集中的資源。 PVC是對這些資源的請求,也是對資源的索引檢查。PV和PVC之間的相互作用遵循這個生命週期∶
Provisioning(配置)---> Binding(繫結)--->Using(使用)---> Releasing(釋放)---> Recycling(回收)
這裡有兩種PV的提供方式∶靜態或者動態
靜態-->直接固定儲存空間∶
叢集管理員建立一些 PV。它們攜帶可供叢集使用者使用的真實儲存的詳細資訊。它們存在於Kubernetes API中,可用於消費。
動態-->通過儲存類進行動態建立儲存空間∶
當管理員建立的靜態 PV 都不匹配使用者的PVC時,叢集可能會嘗試動態地為 PVC 配置卷。此配置基於 storageClasses:PVC必須請求儲存類,並且管理員必須已建立並配置該類才能進行動態配置。要求該類的宣告有效地為自已禁用動態配置。
格式
kubectl explain pv #檢視pv的定義方式 FIELDS: apiVersion kind metadata spec kubectl explain pv.spec #檢視pv定義的規格 spec: nfs(定義儲存型別) path(定義掛載卷路徑) server(定義伺服器名稱) accessModes(定義訪問模型,有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪 問模式) ReadWriteOnce(RWO) 單節點讀寫 ReadOnlyMany(ROX)多節點只讀 ReadWriteMany(RWX)多節點讀寫 persistentVolumeReclaimPolicy: Retain #可以定義回收策略 capacity(定義PV空間的大小) storage(指定大小) kubectl explain pvc #檢視PVC的定義方式 KIND: PersistentVolumeClaim VERSION: v1 FIELDS: apiVersion <string> kind <string> metadata <Object> spec <Object> kubectl explain pvc.spec spec: accessModes(定義訪問模式,必須是P的訪問模式的子集) resources (定義申請資源的大小) requests: storage:
NFS使用PV和PVC
1、單獨一臺機器配置nfs儲存
mkdir -p /data/v{1,2,3,4,5} chmod 777 /data/v{1,2,3,4,5} vim /etc/exports /data/v1 192.168.10.0/24(rw,no_root_squash) /data/v2 192.168.10.0/24(rw,no_root_squash) /data/v3 192.168.10.0/24(rw,no_root_squash) /data/v4 192.168.10.0/24(rw,no_root_squash) /data/v5 192.168.10.0/24(rw,no_root_squash) exportfs -arv showmount -e
2、定義PV
這裡定義5個PV,並且定義掛載的路徑以及訪問模式,還有PV劃分的大小。
vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
labels:
name: pv01
spec:
nfs:
path: /data/v1
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02
labels:
name: pv02
spec:
nfs:
path: /data/v2
server: nfs01
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03
labels:
name: pv03
spec:
nfs:
path: /data/v3
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv04
labels:
name: pv04
spec:
nfs:
path: /data/v4
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv05
labels:
name: pv05
spec:
nfs:
path: /data/v5
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
kubectl create -f pv.yaml
kubectl get pv
3、定義PVC
這裡定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVc申請的大小為2Gi,此時PVC會自動去匹配多路讀寫且大小為2Gi的PV,匹配成功獲取PVC的狀態即為Bound(需要做好node節點和nfs伺服器的對映) vim pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nginxpvc spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 2Gi --- apiVersion: v1 kind: Pod metadata: name: nginx01 spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html persistentVolumeClaim: claimName: nginxpvc
StorageClass
在pv和pvc使用過程中存在的問題,在pvc申請儲存空間時,未必就有現成的py符合pvc申請的需求,上面nfs在做pvc可以成功的因素是因為我們做了指定的需求處理。那麼當PvC申請的儲存空間不一定有滿足PVC要求的PV時,又該如何處理呢為此,Kubernetes為管理員提供了描述儲存"class(類)"的方法(storageClass)。舉個例子,在儲存系統中劃分一個1TB的儲存空間提供給Kubernetes使用,當用戶需要一個10G的pvc時,會立即通過restful傳送請求,從而讓儲存空間建立一個10G的image,之後在我們的叢集中定義成10G的Pv供給給當前的PVC作為掛載使用。在此之前我們的儲存系統必須支援restful介面,比如ceph分散式儲存,而glusterfs則需要藉助第三方介面完成這樣的請求。
kubectl explapin storageclass #storageclass也是k8s上的資源 KIND: StorageClass VERSION: storage.k8s.io/v1 FIELDS: allowVolumeExpansion <boolean> allowedTopologies <[]Object> apiVersion <string> kind <string> metadata <Object> mountOptions <[]string> #掛載選項 parameters <map[string]string> #引數,取決於分配器,可以接受不同的引數。例如引數 type 的值 iol 和引數 iopsPerGB 特定於EBS PV。當引數被省略時,會使用預設值。 provisioner <string>-required- #儲存分配器,用來決定使用哪個卷外掛分配 PV。該欄位必須指定。 reclaimPolicy <string> #回收策略,可以是 Delete 或者 Retain。如果 storageclass 物件被建立時沒有指定 reclaimPolicy,它將 預設為 Delete。 volumeBindingMode <string> #卷的繫結模式