Kubernetes中的PV和PVC是啥
K8S引入了一組叫作Persistent Volume Claim(PVC)和Persistent Volume(PV)的API物件,大大降低了使用者宣告和使用持久化Volume的門檻。
在Pod的Volumes中,只要宣告型別是persistentVolumeClaim,指定PVC的名字,當建立這個PVC物件,k8s就自動為它繫結一個符合條件的Volume,這個Volume,從PV來
PVC和PV的設計,類似“介面”和“實現”的思想,開發者只知道使用“介面”PVC,運維人員負責給“介面”繫結具體的實現PV,說白了PVC就是一種特殊的Volume
PVC和PV的實現原理
PVC:描述 Pod想要使用的持久化屬性,比如儲存大小、讀寫許可權等
PV:描述一個具體的Volume屬性,比如Volume的型別、掛載目錄、遠端儲存伺服器地址等
StorageClass:充當PV的模板,自動為PVC建立PV
一、關於PV建立的流程
大多數情況,持久化Volume的實現,依賴於遠端儲存服務,如遠端檔案儲存(NFS、GlusterFS)、遠端塊儲存(公有云提供的遠端磁碟)等。
K8s需要使用這些儲存服務,來為容器準備一個持久化的宿主機目錄,以供以後掛載使用,建立這個目錄分為兩階段:
1.建立一個遠端塊儲存,相當於建立了一個磁碟,稱為Attach
由Volume Controller負責維護,不斷地檢查 每個Pod對應的PV和所在的宿主機的掛載情況。可以理解為建立了一塊NFS磁碟,相當於執行
gcloud compute instances attach-disk < 虛擬機器名字 > --disk < 遠端磁碟名字 >
為了使用這塊磁碟,還需要掛載操作
2.將這個磁碟裝置掛載到宿主機的掛載點,稱為Mount
將遠端磁碟掛載到宿主機上,發生在Pod對應的宿主機上,是kubelet元件一部分,利用goroutine執行,不會阻塞主我看一下
相當於執行
mount -t nfs <NFS 伺服器地址 >:/ /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 型別 >/<Volume 名字 >
通過這個掛載操作,Volume的宿主機目錄就成為了一個遠端NFS目錄的掛載點,以後寫入的所有檔案,都會被儲存在NFS伺服器上
如果是已經有NFS磁碟,第一步可以省略.
同樣,刪除PV的時候,也需要Umount和Dettach兩個階段處理
二、PV、PVC使用示例
1.建立PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: cqh
labels:
cqh: chenqionghe
spec:
capacity:
storage: 100Mi
volumeMode: Filesystem
accessModes: ["ReadWriteMany"]
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data/pv
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: cqh
operator: In
values:
- chenqionghe
建立後檢視
root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
cqh 100Mi RWX Delete Bound default/cqh local-storage 4m
2.建立PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cqh
spec:
storageClassName: local-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Mi
selector:
matchLabels:
cqh: chenqionghe
AccessModes為ReadWriteMany,表示這個Volume是可讀寫的,並且能掛載在多個節點上(官方支援的AccessMode)
執行建立後檢視
root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
cqh Bound cqh 100Mi RWX local-storage 4m
3.建立Pod,使用PVC
apiVersion: v1
kind: Pod
metadata:
name: cqh
spec:
containers:
- name: cqh-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-storage
volumes:
- name: pv-storage
persistentVolumeClaim:
claimName: cqh
建立後檢視
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
cqh 1/1 Running 0 4m 10.244.0.46 vm-0-8-ubuntu <none>
root@VM-0-8-ubuntu:/home/ubuntu/statefulset# kubectl describe po cqh
Name: cqh
Namespace: default
...
Volumes:
pv-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: cqh
ReadOnly: false
default-token-gqfrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-gqfrx
Optional: false
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m default-scheduler Successfully assigned default/cqh to vm-0-8-ubuntu
Normal Pulling 4m kubelet, vm-0-8-ubuntu pulling image "nginx"
Normal Pulled 4m kubelet, vm-0-8-ubuntu Successfully pulled image "nginx"
Normal Created 4m kubelet, vm-0-8-ubuntu Created container
Normal Started 4m kubelet, vm-0-8-ubuntu Started container
總結
- PVC和PV相當於面向物件的介面和實現
- 使用者建立的Pod聲明瞭PVC,K8S會找一個PV配對,如果沒有PV,就去找對應的StorageClass,幫它建立一個PV,然後和PVC完成繫結
- 新建立的PV,要經過Master節點Attach為宿主機建立遠端磁碟,再經過每個節點kubelet元件把Attach的遠端磁碟Mount到宿主機目錄