apiVersion: v1 kind: PersistentVolume metadata: name: my-pv spec: storageClassName: manual capacity: storage: 1Gi accessModes: - ReadWriteOnce - ReadOnlyMany persistentVolumeReclaimPolicy: Retain nfs: path: /var/nfs/www server: 172.31.192.65在一般的公司,系統資源應該會由系統管理員負責並分配給程式開發人員,K8s 於是設計了系統管理員先在 K8s cluster 上建立 PersistentVolume (PV),分配了一定的資源,程式開發人員想要使用這些資源,要再建立 PersistentVolumeClaim (PVC) 由 PV 中取得,上面的 yaml 建立了 PV,有 1G 的儲存空間,下面的 yaml 建立一個 PVC,自上述的 PV 中取得 100M 的空間。
上面第 12 行的設定值為 Retain,表示就算 PVC 被刪除、回收,PV 不會被刪除且會保留 PVC 裡的資料,但是狀態由 Bound 變為 Released,要重新使用這個 PV,需手動清除上面的資料再將狀態改為 Available; 如果設定為 Delete 則當 PVC 刪除,PV 也會一併刪除。
第 13~15 行是指定 nfs 的 IP 和分享出來的路徑。
注意看上面的執行結果,建立 PV 後,PV 的 STATUS 是 Available,CLAIM 是空白,當 PVC 建立後,PV 的 STATUS 變成 Bound,CLAIM 變成 default/my-pvc,表示 my-pv 確實綁定到 my-pvc 了! 接著建一個 pod 來使用這個 PVC,在 PVC 的 yaml 檔中,不需指定要用那一個 PV,Kubernetes 會根據 PVC 宣告的內容,找到合適的 PV,因為上面的 PVC 有宣告 storageClassName,Kubernetes 會找到 storageClassName 同名的 PV,配置空間給 PVC。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 100Mi現在實際來執行一下上面兩個 yaml …
注意看上面的執行結果,建立 PV 後,PV 的 STATUS 是 Available,CLAIM 是空白,當 PVC 建立後,PV 的 STATUS 變成 Bound,CLAIM 變成 default/my-pvc,表示 my-pv 確實綁定到 my-pvc 了! 接著建一個 pod 來使用這個 PVC,在 PVC 的 yaml 檔中,不需指定要用那一個 PV,Kubernetes 會根據 PVC 宣告的內容,找到合適的 PV,因為上面的 PVC 有宣告 storageClassName,Kubernetes 會找到 storageClassName 同名的 PV,配置空間給 PVC。
要特別注意的是,PV 和 PVC 是一對一的關係,PVC 不能要求比 PV 更多的空間,但是,如上,當 PVC 要求的比 PV 擁有的少時,PV 擁有的所有資源都會給 PVC,所以,PVC 只要求 100Mi,可是 PV 有 1Gi,PVC 的 CAPACITY 會是 1Gi。
apiVersion: v1 kind: Pod metadata: name: centos-pvc spec: containers: - name: centos7 image: centos:7 command: - "bin/bash" - "-c" - "sleep 10000" volumeMounts: - name: logfolder mountPath: /home/steven/log volumes: - name: logfolder persistentVolumeClaim: claimName: my-pvcmy-pvc 這個 volume 在 pod 中會被 mount 在 /home/steven/log 目錄,可以使用 kubectl exec 進入 pod 中,於該目錄建立一些檔案,然後刪除 pod 再重新建立,再用 kubectl exec 進入新建立的 pod,可以在 /home/steven/log 目錄裡找到剛剛建立的檔案。最後補充說明一下上面的參數。
- accessModes
- RWO (ReadWriteOnce): 僅允許單個 node 掛載讀寫。
- ROX (ReadOnlyMany): 允許多個 node 掛載,但 read only。
- RWX (ReadWriteMany): 允許多個 node 掛載,且可讀寫。