1、NFS PV PVC 介紹
NFS 即網絡文件系統(Network File-System),可以通過網絡讓不同機器、不同系統之間可以實現文件共享。通過 NFS,可以訪問遠程共享目錄,就像訪問本地磁盤一樣。NFS 只是一種文件系統,本身並沒有傳輸功能,是基於 RPC(遠程過程調用)協議實現的,採用 C/S 架構。
PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的兩種API資源,用於抽象存儲細節,用於實現持久化存儲.
PersistentVolume(PV)是集羣中由管理員配置的一段網絡存儲。
是由管理員設置的存儲,它是羣集的一部分。就像節點是集羣中的資源一樣,PV 也是集羣中的資源。 PV 是 Volume 之類的卷插件,但具有獨立於使用 PV 的 Pod 的生命週期。此 API 對象包含存儲實現的細節,即 NFS、iSCSI 或特定於雲供應商的存儲系統
PersistentVolumeClaim(PVC)是由用戶進行存儲的請求。
它與 Pod 相似。Pod 消耗節點資源,PVC 消耗 PV 資源。Pod 可以請求特定級別的資源(CPU 和內存)。PVC聲明可以請求特定的大小和訪問模式(如:讀寫或只讀)
PV支持的類型 https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes
總結:Persistent Volume(持久化卷)簡稱PV, 是一個K8S資源對象,我們可以單獨創建一個PV, 它不和Pod直接發生關係, 而是通過Persistent Volume Claim, 簡稱PVC來實現動態綁定, 我們會在Pod定義裏指定創建好的PVC, 然後PVC會根據Pod的要求去自動綁定合適的PV給Pod使用。
訪問模式(accessModes)
ReadWriteOnce – PV以 read-write 掛載到一個節點
ReadWriteMany – PV以 read-write方式掛載到多個節點
ReadOnlyMany – PV以 read-only方式掛載到多個節點
————————————————
版權聲明:本文爲CSDN博主「dz45693」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/ma_jiang/article/details/114266565
2、安裝 NFS 軟件包
#1安裝nfs服務端 sudo apt install nfs-kernel-server -y #2. 創建目錄 sudo mkdir -p /data/k8s/ #3. 使任何客戶端均可訪問 sudo chown nobody:nogroup /data/k8s/ #sudo chmod 755 /data/k8s/ sudo chmod 777 /data/k8s/ #4. 配置/etc/exports文件, 使任何ip均可訪問(加入以下語句) vi /etc/exports /data/k8s/ *(rw,sync,no_subtree_check) #5. 檢查nfs服務的目錄 sudo exportfs -ra (重新加載配置) sudo showmount -e (查看共享的目錄和允許訪問的ip段) #6. 重啓nfs服務使以上配置生效 sudo systemctl restart nfs-kernel-server #sudo /etc/init.d/nfs-kernel-server restart #查看nfs服務的狀態是否爲active狀態:active(exited)或active(runing) systemctl status nfs-kernel-server #7. 測試nfs服務是否成功啓動 #安裝nfs 客戶端 sudo apt-get install nfs-common #創建掛載目錄 sudo mkdir /data/k8s/ #7.4 在主機上的Linux中測試是否正常 sudo mount -t nfs -o nolock -o tcp 192.168.100.11:/data/k8s/ /data/k8s/(掛載成功,說明nfs服務正常) #錯誤 mount.nfs: access denied by server while mounting
3創建pv(master上)vim mypv.yaml //內容如下
apiVersion: v1 kind: PersistentVolume metadata: name: pv001 spec: capacity: storage: 100M accessModes: - ReadWriteMany nfs: path: /data/k8s/ server: 192.168.100.11
kubectl create -f mypv.yaml
kubectl get pv
狀態爲Available,這是因爲它還沒有綁定到任何的pvc上面,當定義完pvc後,就可以自動綁定了。
4 創建pvc(master上)vim mypvc.yaml //內容如下
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: myclaim spec: accessModes: - ReadWriteMany resources: requests: storage: 8M
kubectl create -f mypvc.yaml
kubectl get pvc
可以看到,pvc狀態爲Bound,它綁定了pv001
經過測試,發現在k8s,PVC 也是namespace隔離的。這裏沒有指定,就是默認的namespace。pvc是命名空間隔離的,pv可以全局共享,不用指定命名空間。pv是全局的,pvc可以指定namespace,在如下位置加入 namespace
metadata: name: myclaim #PVC的名稱 namespace: go
5 定義pod vim pvpod.yaml //內容如下
apiVersion: v1 kind: Pod metadata: name: httpd-pvpod spec: containers: - image: httpd name: httpd-withpvc-pod imagePullPolicy: Always volumeMounts: - mountPath: "/usr/local/apache2/htdocs/" name: httpd-volume volumes: - name: httpd-volume persistentVolumeClaim: claimName: myclaim
kubectl create -f pvpod.yaml
kubectl describe pod httpd-pvpod //查看Volumes那部分裏的ClaimName
6 驗證
#1到NFS的共享目錄下創建一個文件 cd /data/k8s/ echo "Test file" > 1.html #2進入到httpd-pod裏 #kubectl exec -it httpd-pvpod bash kubectl exec -it httpd-pvpod /bin/sh cat /usr/local/apache2/htdocs/1.html #3刪除httpd-pvpod kubectl delete pod httpd-pvpod cat /data/k8s/1.html #4重建httpd-pod kubectl create -f pvpod.yaml #5curl訪問 kubectl get pod httpd-pvpod -o wide //查看其對應的IP
一般刪除步驟爲:先刪pod再刪pvc最後刪pv
kubectl delete pvc xxx -n senyint #但是遇到pv始終處於“Terminating”狀態,而且delete不掉。解決方法:直接刪除k8s中的記錄: kubectl patch pv xxx -p '{"metadata":{"finalizers":null}}' -n senyint #強制刪除 pod kubectl delete pod PODNAME --force --grace-period=0 -n senyint #強制刪除 namespace kubectl delete namespace NAMESPACENAME --force --grace-period=0 -n senyint
備註:
4. 過程問題整理
1) pvc一直處於Pending狀態,使用命令查看詳細信息
kubectl get pvc kubectl describe pvc myclaim #查找原因 #kubectl describe pvc myclaim -n xxx
如果遇到 問題 Normal FailedBinding 118s (x42 over 12m) persistentvolume-controller no persistent volumes available for this claim and no storage class is set【我上面的不會存在該問題】
創建PV、PVC二者後,如果能夠自動綁定,說明NFS系統工作正常。在 PVC 綁定 PV 時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是訪問模式。PVC和PV的綁定,不是簡單的通過Label來進行。而是要綜合storageClassName,accessModes,matchLabels以及storage來進行綁定。根據PVC和PV綁定原理分析,是PV指定了storageClassName: nfs #存儲類名稱,PVC裏面又沒有指定storageClassName導致。
# cat pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-data #pv的名稱 spec: capacity: #容量 storage: 10Gi #pv可用的大小 accessModes: #訪問模式 - ReadWriteOnce #PV以read-write掛載到一個節點 persistentVolumeReclaimPolicy: Recycle #持久捲回收策略 storageClassName: nfs #存儲類名稱 重要:需將來的PVC中定義的一樣 nfs: path: /data/pvdata #NFS的路徑 server: 172.22.22.215 #NFS的IP地址 ---------------- [root@kubernetes-master ~]# vi pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mongo-storage #PVC的名稱 如 nginx-log 一般指出用途 spec: accessModes: - ReadWriteOnce #PVC以read-write掛載到一個節點 storageClassName: nfs resources: requests: storage: 10Gi #PVC允許申請的大小 [root@kubernetes-master ~]#
2) nfs掛載報錯unmatched host
查看nfs日誌
cat /var/log/messages | grep mount
報錯
Feb 4 03:19:26 storage1 dockerd: time=“2020-02-04T03:19:26.861842395+08:00” level=warning msg=“Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update” storage-driver=overlay2
Feb 4 03:22:32 storage1 rpc.mountd[960]: refused mount request from 192.168.13.101 for /data/app/share (/data/app/share): unmatched host
三、PV的動態創建
Kubernetes對象之PersistentVolume,StorageClass和PersistentVolumeClaim
參考URL: https://www.jianshu.com/p/99e610067bc8
k8s使用nfs動態存儲
參考URL: https://www.cnblogs.com/cuishuai/p/9152277.html
有兩種PV提供的方式:靜態和動態。
靜態
集羣管理員創建多個PV,它們攜帶着真實存儲的詳細信息,這些存儲對於集羣用戶是可用的。它們存在於Kubernetes API中,並可用於存儲使用。
動態
當管理員創建的靜態PV都不匹配用戶的PVC時,集羣可能會嘗試專門地供給volume給PVC。這種供給基於StorageClass:PVC必須請求這樣一個等級,而管理員必須已經創建和配置過這樣一個等級,以備發生這種動態供給的情況。請求等級配置爲“”的PVC,有效地禁用了它自身的動態供給功能。
上文中我們通過PersistentVolume描述文件創建了一個PV。這樣的創建方式我們成爲靜態創建。這樣的創建方式有一個弊端,那就是假如我們創建PV時指定大小爲50G,而PVC請求80G的PV,那麼此PVC就無法找到合適的PV來綁定。因此產生了了PV的動態創建。
PV的動態創建依賴於StorageClass對象。我們不需要手動創建任何PV,所有的工作都由StorageClass爲我們完成。
一個例子如下:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: slow provisioner: kubernetes.io/aws-ebs parameters: type: io1 zones: us-east-1d, us-east-1c iopsPerGB: "10"
這個例子使用AWS提供的插件( kubernetes.io/aws-ebs)創建了一個基於AWS底層存儲的StorageClass。這意味着使用這個StorageClass,那麼所有的PV都是AWSElasticBlockStore類型的。
StorageClass的定義包含四個部分:
provisioner:指定 Volume 插件的類型,包括內置插件(如 kubernetes.io/aws-ebs)和外部插件(如 external-storage 提供的 ceph.com/cephfs)。
mountOptions:指定掛載選項,當 PV 不支持指定的選項時會直接失敗。比如 NFS 支持 hard 和 nfsvers=4.1 等選項。
parameters:指定 provisioner 的選項,比如 kubernetes.io/aws-ebs 支持 type、zone、iopsPerGB 等參數。
reclaimPolicy:指定回收策略,同 PV 的回收策略。
手動創建的PV時,我們指定了storageClassName=slow的配置項,然後Pod定義中也通過指定storageClassName=slow,從而完成綁定。而通過StorageClass實現動態PV時,我們只需要指定StorageClass的metadata.name。
回到上文中創建PVC的例子,此時PVC指定了storageClassName=slow。那麼Kubernetes會在集羣中尋找是否存在metadata.name=slow的StorageClass,如果存在,此StorageClass會自動爲此PVC創建一個accessModes = ReadWriteOnce,並且大小爲8GB的PV。
通過StorageClass的使用,使我們從提前構建靜態PV池的工作中解放出來。
參考:
https://www.cnblogs.com/luoahong/p/13570420.html