一、PVC和PV
1.1 PV概念
1.PersistentVolume(PV)是集群中已由管理員配置的一段網絡存儲。集群中的資源就像一個節點是一個集群資源,可以從遠程的NFS或分布式對象存儲系統中創建得來(pv存儲空間大小、訪問方式)
2.Pv是諸如卷之類的卷插件,但是只有獨立於使用Pv的任何單個pod的生命周期。
3.該API對象捕獲存儲的實現細節,即NFS,isCSI或雲提供商特定的存儲系統
4.PV就是從存儲設備中的空間創建出一個存儲資源
1.2 PVC概念
- PersistentVolumeClaim (PVC)是用戶存儲的請求。Pvc的使用邏輯:在pod中定義一個存儲卷(該存儲卷類型為pvc),定義的時候直按指定大小,pvc必須與對應的pv建立關系,pvc會根據定義去pv申請,而pv是由存儲空間創建出來的。pv和pvc是kubernetes抽象出來的一種存儲資源
- 雖然PersistentVolumeClaims允許用戶使用抽象存儲資源,但是常見的需求是,用戶需要根據不同的需求去創建Pv,用於不同的場景。而此時需要集群管理員提供不同需求的Pv,而不僅僅是Pv的大小和訪問模式,但又不需要用戶了解這些卷的實現細節
- 對於這樣的需求,此時可以采用storageclass資源
1.3 PV與PVC之間的關系
PV是集群中的資源。Pvc是對這些資源的請求,也是對資源的索引檢查。PV和Pvc之間的相互作用遵循這個生命周期:Provisioning(配置)---> Binding(綁定)--->Using(使用)--->Releasing(釋放)--->Recycling(回收)
1.4 兩種PV的提供方式
- 這里有兩種PV的提供方式:靜態或者動態
- 靜態-->直接固定存儲空間:
集群管理員創建一些PV。它們攜帶可供集群用戶使用的真實存儲的詳細信息。它們存在於Kubernetes API中,可用於消費 - 動態-->通過存儲類進行動態創建存儲空間:
當管理員創建的靜態PV都不匹配用戶的 PVC時,集群可能會嘗試動態地為 Pvc配置卷。此配置基於StorageClasses: PVC必須請求存儲類,並且管理員必須已創建並配置該類才能進行動態配置。要求該類的聲明有效地為自己禁用動態配置
二、基於nfs創建靜態PV資源和PVC資源
2.1 配置nfs存儲(192.168.80.14)
1. mkdir -p /data/v{1..5}
chmod 777 -R /data/*
2. vim /etc/exports
/data/v1 192.168.10.0/24(rw,no_root_squash,sync)
/data/v2 192.168.10.0/24(rw,no_root_squash,sync)
/data/v3 192.168.10.0/24(rw,no_root_squash,sync)
/data/v4 192.168.10.0/24(rw,no_root_squash,sync)
/data/v5 192.168.10.0/24(rw,no_root_squash,sync)
3. systemctl start rpcbind
systemctl start nfs
4. showmount -e
5. hostnamectl set-hostname nfs01
su
6. echo '11111' > /data/v1/index.html
echo '22222' > /data/v2/index.html
echo '33333' > /data/v3/index.html
echo '44444' > /data/v4/index.html
echo '55555' > /data/v5/index.html
2.2 k8s的master節點定義PV
//這里定義5個Pv,並且定義掛載的路徑以及訪問模式,還有pv划分的大小
vim pv-demo.yaml
==========================================================
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
nfs:
path: /data/v1
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /data/v2
server: nfs01
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /data/v3
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
labels:
name: pv004
spec:
nfs:
path: /data/v4
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /data/v5
server: nfs01
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
==========================================================
kubectl apply -f pv-demo.yaml
kubectl get pv
2.3 定義PVC
//這里定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義Pvc申請的大小為2Gi,此時pvc會自動去匹配多路讀寫且大小為2Gi的Pv,匹配成功獲取PVC的狀態即為Bound
vim pvc-demo.yaml
==========================================================
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pv-pvc
spec:
containers:
- name: myapp
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: mypvc
==========================================================
kubectl apply -f pvc-demo.yaml
kubectl get pv
2.4 測試多路讀寫
1. 我們通過相同的存儲卷,只修改pod的名稱
cp pvc-demo.yaml 1.yaml
cp pvc-demo.yaml 2.yaml
2. 修改pod的名稱后,apply執行創建
kubectl apply -f 1.yaml
kubectl apply -f 2.yaml
3. 查看ip
kubectl get pod -o wide
4. curl進行測試,查看是否共享存儲卷,多路讀寫
三、基於動態storageclass創建pv與pvc
3.1 storageclass的用處
在pv和pvc使用過程中存在的問題,在pvc申請存儲空間時,未必就有現成的pv符合pvc申請的需求,上面nfs在做pvc可以成功的因素是因為我們做了指定的需求處理。當PvC申請的存儲空間不一定有滿足PvC要求的Pv時,Kubernetes為管理員提供了描述存儲"class(類)"的方法(StorageClass)。舉個例子,在存儲系統中划分一個1TB的存儲空間提供給Kubernetes使用,當用戶需要一個10G的PvC時,會立即通過restful發送請求,從而讓存儲空間創建一個10G的image,之后在我們的集群中定義成10c的Pv供給給當前的Pvc作為掛載使用。在此之前我們的存儲系統必須支持restful接口,比如ceph分布式存儲,而glusterfs則需要借助第三方接口完成這樣的請求
3.2 storageclass的yaml格式
kubectl explain storageclass #storageclass也是k8s上的資源
KIND: Storageclass
VERSION: storage.k8s.io/vl
FIELDS:
allowVolumeExpansion <boolean>
allowedTopologies<[]Object>apiversion<string>
kind <string>
metadata <object>
mountOptions <[]string>掛載選項
parameters <map[string]string#參數,取決於分配器,可以接受不同的參數。例如,參數type的值 io1和參數iopsPerGB特定於EBS PV。當參數被省略時,會使用默認值。
provisioner <string-requred-#存儲分配器,用來決定使用哪個卷插件分配 PV。該字段必須指定。
reclaimPolicy <string>#回收策略,可以是 Delete或者 Retain。如果 StorageClass 對象被創建時沒有指定 reclaimPolicy,它將默認為 Delete。
volumeBindingMode<string>#卷的綁定模式
StorageClass 中包含 provisioner、parameters和 reclaimPolicy字段,當 class需要動態分配 PersistentVolume時會使用到。由於storageclass需要一個獨立的存儲系統,此處就不再演示。從其他資料查看定義storageclass的方式如下:
==========================================================
kind: storageClass
apiversion: storage.k8s.io/v1432
metadata :
name : standard
provisioner: kubernetes.iol aws-ebs435 parameters:
type: gp2
reclaimPolicy: Retain
mountoptions:
- debug