ubuntu kubernetes中使用NFS創建pv_pvc

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章