Kubernetes中的PV和PVC是啥

  • 2019 年 10 月 17 日
  • 筆記

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

總結

  1. PVC和PV相當於面向對象的接口和實現
  2. 用戶創建的Pod聲明了PVC,K8S會找一個PV配對,如果沒有PV,就去找對應的StorageClass,幫它創建一個PV,然後和PVC完成綁定
  3. 新創建的PV,要經過Master節點Attach為宿主機創建遠程磁盤,再經過每個節點kubelet組件把Attach的遠程磁盤Mount到宿主機目錄