目錄
一、Volume 卷
1.1 卷類型
emptyDir :
hostPath:
persistentVolumeClaim (PVC):
configMap 和 secret:
二、 emptyDir存儲卷
2.1 特點
2.2 用途:
2.3 示例
三、 hostPath存儲卷
3.1 特點
3.2 用途
3.3 示例
四、 nfs共享存儲卷
4.1 特點
4.2?用途
4.3 示例
五、PV和PVC
5.1 PV和PVC之間的相互作用的生命周期
5.2 pv的狀態
5.3 pv從創建到銷毀的過程
5.4 回收策略
六、pv操作
6.1 簡單舉例
6.2 結合舉例
6.3 查看pv的定義方式
6.4 查看pv定義的規格
6.5 查看PVC的定義方式
6.6 查看pvc定義規格
七、NFS使用PV和PVC(靜態)
7.1 NFS主機上配置nfs存儲
7.2master上定義pv
7.3 master上定義pvc
7.4 測試訪問
八、搭建StorageClass + NFS(NFS 的動態 PV 創建)
8.1 stor01節點上安裝nfs,并配置nfs服務
8.2 master創建 Service Account,設置 nfs-client 對 PV,PVC,StorageClass 等的規則
8.3 使用 Deployment 來創建 NFS Provisioner
8.4 創建 StorageClass
8.5 創建 PVC
8.6 查看 NFS 服務器上是否生成對應的目錄
一、Volume 卷
容器磁盤上的文件的生命周期是短暫的,這就使得在容器中運行重要應用時會出現一些問題。首先,當容器崩潰時,kubelet 會重啟它,但是容器中的文件將丟失——容器以干凈的狀態(鏡像最初的狀態)重新啟動。其次,在Pod中同時運行多個容器時,這些容器之間通常需要共享文件。
Kubernetes 中的 Volume 抽象確實解決了容器中文件生命周期短暫的問題。通過 Volume,可以將持久化存儲掛載到 Pod 中的容器,使得即使容器重新啟動或者崩潰,文件依然可用。而共享文件的需求則可以通過將 Volume 掛載到 Pod 中的多個容器來實現,在這種情況下,這些容器可以共享相同的文件系統。
1.1 卷類型
emptyDir :
-
emptyDir 是一種臨時性卷,在同一個 Pod 中的容器之間共享文件。
-
它在 Pod 創建時被創建,并且對于同一個 Pod 中的所有容器都可見。
-
當 Pod 被刪除時,emptyDir 中的數據也會被清除。
-
適用于臨時數據交換或共享,例如緩存空間或某些計算任務的檢查點。
hostPath:
-
hostPath 允許將宿主機文件系統路徑掛載到 Pod 中,容器可以直接讀寫宿主機上的文件。
-
它可以用于需要對宿主機文件系統進行直接操作的場景,但可能會引入安全風險和依賴于特定節點的問題。
persistentVolumeClaim (PVC):
-
persistentVolumeClaim (PVC) 用于請求持久化存儲資源,可以在多個 Pod 之間共享。
-
PVC 是一種抽象,用于請求集群中的持久化存儲資源,例如 NFS、AWS EBS、Azure Disk 等。
-
PVC 可以獨立于 Pod 存在,并且可以通過標簽選擇器與 Pod 動態綁定,從而實現存儲資源的動態分配和回收。
configMap 和 secret:
-
configMap 和 secret 允許將配置文件或機密信息掛載到容器中。
-
configMap 用于存儲配置數據,例如環境變量、配置文件等。
-
secret 用于存儲敏感信息,例如密碼、證書等。
-
這些信息可以作為卷掛載到 Pod 中,或者以環境變量的形式注入到容器中。
通過使用這些不同類型的卷,Kubernetes 用戶可以靈活地管理和利用存儲資源,滿足不同應用場景的需求。
二、 emptyDir存儲卷
emptyDir
存儲卷是 Kubernetes 中的一種卷類型,用于在同一個 Pod 中的容器之間共享文件。
emptyDir
卷在 Pod 被分配給節點時被創建,并且只要 Pod 在該節點上運行,該卷就會一直存在。它最初是空的,因此其名稱為 emptyDir
。Pod 中的所有容器可以讀取和寫入 emptyDir
卷中的相同文件,盡管可以將該卷掛載到每個容器中的相同或不同路徑上。但需要注意的是,當出于任何原因從節點中刪除 Pod 時,emptyDir
中的數據將被永久刪除,因為它是臨時性存儲,其生命周期與 Pod 相關聯。
2.1 特點
-
臨時性存儲:
-
emptyDir
提供的存儲是臨時的,其生命周期與所屬的 Pod 相關。 -
當 Pod 被刪除時,
emptyDir
中的數據也會被清除,因此不適合用于持久化存儲。 -
Pod 內容器之間的共享:
-
emptyDir
在同一個 Pod 中的所有容器之間共享,容器可以讀寫其中的數據。 -
創建時機:
-
emptyDir
在 Pod 創建時被創建,當容器啟動時,可以訪問其中的空目錄。
2.2 用途:
-
適用于需要在同一個 Pod 中的多個容器之間進行臨時數據交換或共享的場景。
-
例如,可以用于容器間的緩存共享、臨時文件存儲等用途。
2.3 示例
mkdir /opt/volumes
cd /opt/volumesvim pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-emptydirnamespace: defaultlabels:app: myapptier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80#定義容器掛載內容volumeMounts:#使用的存儲卷名稱,如果跟下面volume字段name值相同,則表示使用volume的這個存儲卷- name: html#掛載至容器中哪個目錄mountPath: /usr/share/nginx/html/- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: html#在容器內定義掛載存儲名稱和掛載路徑mountPath: /data/command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']#定義存儲卷volumes:#定義存儲卷名稱 - name: html#定義存儲卷類型emptyDir: {}
-
這個YAML文件描述了一個名為
pod-emptydir
的Pod,其中包含兩個容器:myapp
和busybox
。myapp
容器使用名為html
的空目錄卷掛載到/usr/share/nginx/html/
目錄,而busybox
容器也使用相同的卷掛載到/data/
目錄,并在容器內運行一個循環,每兩秒將當前日期追加到/data/index.html
文件中。最后,通過emptyDir
類型定義了一個名為html
的存儲卷,這樣做是為了驗證兩個容器之間掛載的emptyDir
實現共享。 -
這配置的目的是驗證兩個容器之間通過
emptyDir
實現的存儲卷共享。
kubectl apply -f pod-emptydir.yaml #啟動Pod
[root@master01 volumes]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE
pod-emptydir 2/2 Running 0 70s 10.244.2.4 node02 <none> <none>
- 可見
pod-emptydir
Pod 正常運行且兩個容器都處于Ready狀態。
[root@master01 volumes]# curl 10.244.2.4
這表示成功地從Pod pod-emptydir
中獲取到了日期信息。這表明配置正確,busybox
容器將日期寫入到了/data/index.html
文件中,而myapp
容器通過共享的存儲卷可以訪問到這個文件。因此,存儲卷之間的共享通過emptyDir
實現成功。
三、 hostPath存儲卷
HostPath存儲卷是Kubernetes中的一種卷類型,允許將節點上的文件系統路徑掛載到Pod中。這意味著Pod可以訪問主機節點上的文件或目錄,并與主機共享存儲空間。
hostPath卷將 node 節點的文件系統中的文件或目錄掛載到集群中。 hostPath可以實現持久存儲,但是在node節點故障時,也會導致數據的丟失。
3.1 特點
-
直接訪問主機文件系統: HostPath存儲卷允許Pod直接訪問主機節點上的文件系統,提供了對主機存儲的直接訪問權限。
-
讀寫權限: Pod可以對HostPath上的文件進行讀寫操作,這為一些需要在容器內進行文件操作的應用提供了便利。
-
節點依賴性: Pod使用HostPath時,會依賴節點上的具體路徑,這可能導致在不同節點上部署相同Pod時出現問題,因為節點之間的文件系統路徑可能不同。
-
共享資源:多個Pod可以共享同一個HostPath,但要小心避免數據沖突或競爭條件。
3.2 用途
-
主機文件操作: 適用于需要在Pod內進行主機文件系統操作的場景,例如讀取或寫入主機上的特定文件。
-
數據共享: 多個Pod可以共享同一個HostPath,這在一些需要多個Pod之間共享數據的情況下可能很有用。
-
特殊需求: 用于滿足一些特殊需求,例如某些應用需要在容器內直接操作主機上的某些文件。
需要注意的是,由于HostPath存儲卷的使用可能涉及到權限和安全性的考慮,一般情況下建議慎重使用,并確保在生產環境中采取適當的安全措施。
3.3 示例
在 node01 節點上創建掛載目錄
mkdir -p /data/pod/volume1
echo 'node01.test.com' > /data/pod/volume1/index.html
在 node02 節點上創建掛載目錄
mkdir -p /data/pod/volume1
echo 'node02.test.com' > /data/pod/volume1/index.html
在master01上創建 Pod 資源
vim pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-hostpathnamespace: default
spec:containers:- name: myappimage: ikubernetes/myapp:v1#定義容器掛載內容volumeMounts:#使用的存儲卷名稱,如果跟下面volume字段name值相同,則表示使用volume的這個存儲卷- name: html#掛載至容器中哪個目錄mountPath: /usr/share/nginx/html#讀寫掛載方式,默認為讀寫模式falsereadOnly: false#volumes字段定義了paues容器關聯的宿主機或分布式文件系統存儲卷volumes:#存儲卷名稱- name: html#路徑,為宿主機存儲路徑hostPath:#在宿主機上目錄的路徑path: /data/pod/volume1#定義類型,這表示如果宿主機沒有此目錄則會自動創建type: DirectoryOrCreate
- 此YAML配置描述了在默認命名空間中命名為“pod-hostpath”的Kubernetes Pod。它將主機路徑卷掛載到容器中,使主機目錄的內容在容器內的指定路徑可用。如果主機上的目錄不存在,由于"類型: 目錄或創建"屬性,它將被自動創建。
kubectl apply -f pod-hostpath.yaml
- 該命令 "kubectl apply -f pod-hostpath.yaml" 用于將 "pod-hostpath.yaml" 文件中指定的配置應用到 Kubernetes 集群中。它根據提供的配置創建或更新 YAML 文件中定義的資源,例如 Pod。
訪問測試
[root@master01 volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE pod-hostpath 1/1 Running 0 28s 10.244.1.5 node01 <none> <none>
[root@master01 volumes]# curl 10.244.1.5
node02.test.com
刪除pod,再重建,驗證是否依舊可以訪問原來的內容
[root@master01 volumes]# kubectl delete -f pod-hostpath.yaml
pod "pod-hostpath" deleted
[root@master01 volumes]# kubectl apply -f pod-hostpath.yaml
pod/pod-hostpath created
[root@master01 volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-hostpath 1/1 Running 0 14s 10.244.1.6 node01 <none> <none>
[root@master01 volumes]# curl 10.244.1.6
node02.test.com
- 可見數據訪問實現了持久存儲
四、 nfs共享存儲卷
在Kubernetes中,NFS共享存儲卷是一種常見的持久化存儲解決方案,它允許多個Pod在集群中共享同一個NFS服務器上的存儲空間。
-
NFS介紹: NFS(Network File System)是一種基于網絡的文件系統協議,允許在網絡上共享文件系統資源。它使得不同的計算機之間可以像訪問本地文件一樣訪問遠程文件。
-
Kubernetes中的NFS存儲卷: Kubernetes提供了多種方式來使用NFS作為持久化存儲卷。其中一種常見的方法是使用NFS卷插件,例如NFS CSI Driver,它能夠與Kubernetes集成并提供對NFS存儲的訪問。
-
配置NFS存儲卷: 要在Kubernetes中配置NFS存儲卷,首先需要在NFS服務器上設置共享目錄,并確保NFS服務器可以通過網絡訪問。然后,可以通過Kubernetes的PersistentVolume(PV)和PersistentVolumeClaim(PVC)對象來聲明和使用NFS存儲卷。
4.1 特點
-
共享性: NFS存儲卷允許多個Pod在集群中共享同一個NFS服務器上的存儲空間。這使得多個應用程序可以訪問和操作相同的數據,促進了數據共享和協作。
-
持久性: NFS存儲卷提供了持久化的存儲解決方案,數據存儲在NFS服務器上并且在Pod重新啟動或遷移時仍然可用。這對于需要長期保存數據的應用程序和服務非常有用。
-
可擴展性: NFS存儲卷可以輕松地擴展以滿足應用程序的需求。通過在NFS服務器上添加更多的存儲空間或者增加NFS服務器的數量,可以擴展存儲容量和性能。
-
靈活性: 使用NFS存儲卷可以將存儲與Pod分離,從而使得Pod可以在不同的節點上遷移而不會丟失數據。這種靈活性使得在Kubernetes集群中部署和管理應用程序變得更加容易。
4.2?用途
-
簡化管理: NFS存儲卷可以通過Kubernetes的PV和PVC對象進行聲明和管理,而無需手動管理存儲配置。這簡化了存儲管理的流程,并提高了部署和維護的效率。
-
適用范圍廣泛: NFS存儲卷適用于許多不同類型的應用程序和場景,包括數據庫、文件共享、日志存儲等。它提供了一種通用的存儲解決方案,適用于各種不同的業務需求。
4.3 示例
stor01節點上安裝nfs,并配置nfs服務
[root@35 ~]# hostnamectl set-hostname stor01
[root@35 ~]# su
[root@stor01 ~]#mkdir /data/volumes -p
chmod 777 /data/volumesvim /etc/exports
/data/volumes 192.168.41.0/24(rw,no_root_squash)systemctl start rpcbind
systemctl start nfsshowmount -e
這一系列命令用于配置 NFS(Network File System)共享。
-
創建一個名為
/data/volumes
的目錄,并使用-p
參數確保創建路徑中不存在的目錄。 -
使用
chmod 777 /data/volumes
命令將/data/volumes
目錄的權限設置為 777,以確保所有用戶都有完全的讀寫權限。 -
使用
vim /etc/exports
命令編輯 NFS 服務器的導出文件,添加一行配置/data/volumes 192.168.41.0/24(rw,no_root_squash)
,這表示將/data/volumes
目錄導出給位于子網192.168.41.0/24
的主機,允許讀寫訪問,并且禁用了no_root_squash
。 -
使用
systemctl start rpcbind
和systemctl start nfs
命令啟動 RPC 綁定和 NFS 服務。 -
使用
showmount -e
命令檢查 NFS 導出列表,確認/data/volumes
目錄已經成功導出給了192.168.41.0/24
子網的主機。
這些步驟使得在網絡上可以訪問并且共享 /data/volumes
目錄。
在master節點上
vim pod-nfs-vol.yamlkind: Pod # 指定資源類型為 Pod
apiVersion: v1 # 使用 API 版本 v1
metadata:name: pod-vol-nfs # Pod 的名稱為 pod-vol-nfsnamespace: default # Pod 將被創建在 default 命名空間中
spec: # 描述 Pod 的規格(specification)containers:- name: myapp # 容器的名稱為 myappimage: ikubernetes/myapp:v1 # 容器使用的鏡像為 ikubernetes/myapp:v1volumeMounts: # 容器內的卷掛載設置- name: html # 卷的名稱為 htmlmountPath: /usr/share/nginx/html # 容器內掛載卷的路徑volumes: # Pod 級別的卷定義- name: html # 定義一個名為 html 的卷nfs: # 指定卷類型為 NFSpath: /data/volumes # NFS 服務器上共享的路徑server: stor01 # NFS 服務器的主機名或 IP 地址
- 此配置文件通過 NFS 卷將外部存儲掛載到 Pod 中的容器上,使得容器可以訪問 NFS 上的數據。
kubectl apply -f pod-nfs-vol.yaml #創建pod
kubectl get pods -o wide #配置
-
用來創建并查看 Kubernetes Pod 和將
pod-nfs-vol.yaml
文件中定義的 Pod 配置應用到 Kubernetes 集群中,從而創建名為pod-vol-nfs
的 Pod,其中包含一個名為myapp
的容器,并掛載了一個 NFS 類型的卷。 -
用于獲取當前 Kubernetes 集群中的 Pod 列表
如果在yaml文件中server指定的是主機名而不是ip,需要在pod所在主機上添加主機名映射
vim /etc/hosts
192.168.41.35 stor01
在nfs服務器上創建index.html
cd /data/volumes
echo "<h1> nfs stor01</h1>" > index.html
在master節點測試
curl 10.244.1.7
<h1> nfs stor01</h1>kubectl delete -f pod-nfs-vol.yaml #刪除nfs相關pod,再重新創建,可以得到數據的持久化存儲kubectl apply -f pod-nfs-vol.yaml#再次測試
五、PV和PVC
-
PV(Persistent Volume)是描述或定義存儲卷的工具,通常由運維工程師創建。
-
PVC(Persistent Volume Claim)是對PV的請求,用于描述所需的存儲條件。
-
PVC的邏輯是在Pod中定義一個存儲卷(類型為PVC),指定大小并與相應的PV建立關系。PVC 必須與對應的 PV 建立關系,PVC 會根據配置的定義去 PV 申請,而 PPV由存儲空間創建,二者是Kubernetes抽象的存儲資源。
-
在Kubernetes中,PV(持久卷)有兩種供給方式,靜態和動態。靜態PV是由集群管理員手動創建的,攜帶著真實存儲信息,但存在缺陷,因為需要手動為多個用戶配置存儲,可能顯得繁瑣。而動態PV則是當靜態PV無法匹配用戶的PVC(持久卷聲明)時,集群會嘗試動態地供給volume給PVC,更靈活地滿足用戶需求。
-
為了避免手動創建PV的繁瑣,Kubernetes引入了StorageClass,用于自動創建PV模板。創建StorageClass需定義PV屬性和存儲插件,如Ceph。Kubernetes可根據用戶PVC請求,使用對應的StorageClass調用StorageClass 聲明的存儲插件自動創建需要的PV并進行綁定。
PV是集群中的資源。 PVC是對這些資源的請求,也是對資源的索引檢查。
5.1 PV和PVC之間的相互作用的生命周期
-
Provisioning(配置): PV的創建階段,可通過靜態方式直接創建PV,或使用StorageClass進行動態創建。
-
Binding(綁定): 將PV分配給對應的PVC。
-
Using(使用): Pod通過PVC使用Volume,通過準入控制StorageProtection(1.9及以前版本為PVCProtection)可以阻止刪除正在使用的PVC。
-
Releasing(釋放): Pod釋放Volume并刪除PVC。
-
Recycling(回收): 回收PV,可保留PV以備下次使用,或直接從云存儲中刪除。
5.2 pv的狀態
-
Available(可用):PV已經被創建,但尚未被綁定到任何PVC上,因此可以被任何PVC請求使用。
-
Bound(已綁定):PV已經被綁定到一個PVC上,可以被掛載到一個Pod中使用。
-
Released(已釋放):PVC與PV之間的綁定關系已經被刪除,但是PV上的數據還未被清除。此時PV處于Released狀態,可以被重新綁定到另一個PVC上使用。
-
Failed(失敗):PV與底層存儲后端的連接出現問題,或者存儲后端出現了錯誤,導致PV無法使用。此時PV處于Failed狀態。
5.3 pv從創建到銷毀的過程
PV(Persistent Volume)從創建到銷毀的過程通常包括以下幾個步驟:
-
創建(Provisioning):PV可以通過兩種方式創建,一種是靜態創建,另一種是動態創建。靜態創建是指管理員手動創建PV對象并指定其屬性,如存儲類型、大小等。動態創建則是通過StorageClass進行配置,當PVC請求存儲資源時,根據StorageClass的定義動態創建PV。無論是靜態還是動態創建,都會生成一個PV對象。狀態會變成Available,等待被PVC綁定
-
綁定(Binding):PV需要與PVC進行綁定才能被使用。管理員或Kubernetes系統會將某個PV綁定到一個特定的PVC上,使其成為PVC的存儲資源,狀態會變成Bound,就可以被定義了相應PVC的Pod使用。
-
使用(Using):一旦PV被綁定到PVC上,Pod可以通過PVC來使用PV提供的存儲資源。Pod會掛載PVC,從而訪問PV中的數據,。
-
釋放(Releasing):當PVC不再需要PV提供的存儲資源時,管理員或Kubernetes系統會將PV與PVC之間的綁定解除,釋放PV,PV的狀態變成Released。這并不會立即刪除PV中的數據,而是將PV標記為已釋放狀態。
-
回收(Recycling):在PV被釋放后,根據管理員或系統配置的策略,可以選擇回收PV。回收的方式可能包括保留PV以備下次使用,或者直接刪除PV以釋放資源。有三種回收策略,Retain、Delete和Recycle。Retain就是保留現場,K8S集群什么也不做,等待用戶手動去處理PV里的數據,處理完后,再手動刪除PV。Delete策略,K8S會自動刪除該PV及里面的數據。Recycle方式,K8S會將PV里的數據刪除,然后把PV的狀態變成Available,又可以被新的PVC綁定使用。
5.4 回收策略
在Kubernetes中,PV(Persistent Volume)的回收策略定義了在釋放PV時如何處理其底層存儲資源。常見的PV回收策略包括以下幾種:
-
Retain(保留):當PV被釋放后,底層存儲資源不會被刪除,而是保留在系統中。這意味著PV的數據仍然可用,但需要手動處理以釋放存儲資源。
-
Recycle(回收):在這種策略下,PV被釋放后,底層存儲資源會被清空,以便下次使用。然而,這種方式存在安全性和隱私問題,因此已經不推薦使用。
-
Delete(刪除):PV被釋放后,底層存儲資源會被直接刪除。這是一種自動化的清理方式,適用于不再需要PV數據的情況。
六、pv操作
在 Kubernetes 中,PV(PersistentVolume)是集群中的一種資源,用于提供持久化存儲。PV 的操作包括以下幾個方面:
-
創建 PV:可以通過定義 PV 對象的 YAML 文件來創建 PV。在 YAML 文件中指定 PV 的屬性,如容量、訪問模式、存儲類型等。
-
刪除 PV:當 PV 不再需要時,可以通過刪除相應的 PV 對象來釋放資源。刪除 PV 時需要確保相關的 PVC(PersistentVolumeClaim)已經被釋放,否則刪除操作可能會失敗。
-
管理 PV 的狀態:可以通過修改 PV 對象的屬性來管理 PV 的狀態,如修改容量、訪問模式等。需要注意的是,某些屬性(如容量)可能無法在運行時修改,需要在創建 PV 時就確定好。
-
掛載 PV 到 Pod:創建 PV 后,需要將 PV 掛載到 Pod 中以供應用程序使用。可以通過 PVC(PersistentVolumeClaim)來實現 PV 和 Pod 之間的綁定關系。
-
監控 PV 的使用情況:可以通過 Kubernetes 的監控系統或者第三方工具來監控 PV 的使用情況,包括存儲容量、使用率等指標。
這些是在 Kubernetes 中對 PV 進行常見操作的一些例子。 PV 的操作可以通過命令行工具(如 kubectl)、Kubernetes API 或者管理平臺(如 Kubernetes Dashboard)來進行。
6.1 簡單舉例
創建 PV 時,通過以下 YAML 示例可以指定 PV 的基本屬性:
apiVersion: v1
kind: PersistentVolume
metadata:name: example-pv
spec:capacity:storage: 5GivolumeMode: FilesystemaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RetainstorageClassName: standardmountOptions:- hard- nfsvers=4.1nfs:path: /export/dataserver: nfs-server.example.com
-
capacity
定義了 PV 的存儲容量。 -
volumeMode
指定了 PV 的工作模式,可以是Filesystem
或Block
。 -
accessModes
定義了 PV 的訪問模式,包括ReadWriteOnce
、ReadOnlyMany
和ReadWriteMany
。 -
persistentVolumeReclaimPolicy
定義了當 PV 釋放時的回收策略,可以是Retain
、Recycle
或Delete
。 -
storageClassName
指定了 PV 所屬的存儲類。 -
mountOptions
包含了掛載 PV 時使用的掛載選項。 -
nfs
描述了 NFS 類型的 PV 的具體配置,包括 NFS 服務器地址和路徑。
刪除 PV 時,可以使用以下命令:
kubectl delete pv example-pv
管理 PV 狀態時,可以通過修改 PV 對象的 YAML 文件中的字段值來實現。例如,修改 PV 的容量:
apiVersion: v1
kind: PersistentVolume
metadata:name: example-pv
spec:capacity:storage: 10Gi # 修改容量為10Gi...
掛載 PV 到 Pod 時,需要創建一個 PVC,并在 Pod 的 YAML 文件中引用該 PVC。例如:
apiVersion: v1
kind: Pod
metadata:name: example-pod
spec:containers:- name: my-containerimage: nginxvolumeMounts:- name: my-volumemountPath: /mnt/datavolumes:- name: my-volumepersistentVolumeClaim:claimName: example-pvc # 引用 PVC 的名稱
6.2 結合舉例
在 Kubernetes 中,PV 的動態配置是一項重要的功能,它允許集群動態地創建和管理 PV 資源。以下是 PV 的動態配置的一般流程:
- 定義存儲類(StorageClass):首先,需要定義一個存儲類,它描述了動態創建 PV 所需的存儲屬性。以下是一個存儲類的示例:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: standard
provisioner: example.com/nfs
其中,provisioner
指定了用于動態創建 PV 的存儲插件。
- 創建 PVC:接下來,創建一個 PVC,請求所需的存儲資源。PVC 將使用存儲類來確定如何動態地創建 PV。以下是 PVC 的示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvc
spec:accessModes:- ReadWriteOncestorageClassName: standardresources:requests:storage: 5Gi
在這個示例中,storageClassName
指定了使用的存儲類,而 resources
字段指定了 PVC 請求的存儲容量。
-
動態創建 PV:當 PVC 被創建時,存儲類會使用定義的插件動態創建 PV,并將其與 PVC 綁定。
-
掛載 PV 到 Pod:最后,創建 Pod,并通過 PVC 引用 PV,將其掛載到 Pod 中。以下是一個 Pod 的示例:
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers:- name: my-containerimage: nginxvolumeMounts:- mountPath: "/mnt/data"name: my-volumevolumes:- name: my-volumepersistentVolumeClaim:claimName: my-pvc
在這個示例中,persistentVolumeClaim
字段引用了前面創建的 PVC。
這樣,通過存儲類和 PVC 的組合,Kubernetes 可以實現 PV 的動態創建和管理,使存儲資源更加靈活和自動化。
6.3 查看pv的定義方式
kubectl explain pv #查看pv的定義方式
kubectl explain
命令可以用來查看 Kubernetes 資源的定義方式和字段說明。對于 PV(PersistentVolume),以下是其定義方式和字段說明:
-
apiVersion
:表示 Kubernetes API 的版本。對于 PV,它的 API 版本通常為v1
。 -
kind
:表示 Kubernetes 資源的類型。對于 PV,它的類型是PersistentVolume
。 -
metadata
:包含有關 PV 的元數據信息,如名稱、標簽等。由于 PV 是集群級別的資源,因此 PV 的 metadata 中不需要配置命名空間(namespace)。 -
spec
:PV 的規格(specification),定義了 PV 的屬性和配置。PV 的規格包括以下屬性: -
capacity
:定義了 PV 的存儲容量。 -
volumeMode
:指定了 PV 的工作模式,可以是Filesystem
或Block
。 -
accessModes
:定義了 PV 的訪問模式,包括ReadWriteOnce
、ReadOnlyMany
和ReadWriteMany
。 -
persistentVolumeReclaimPolicy
:定義了當 PV 釋放時的回收策略,可以是Retain
、Recycle
或Delete
。 -
storageClassName
:指定了 PV 所屬的存儲類。 -
mountOptions
:包含了掛載 PV 時使用的掛載選項。 -
nfs
、iscsi
、awsElasticBlockStore
等:描述了不同類型 PV 的具體配置。
6.4 查看pv定義的規格
kubectl explain pv.spec
kubectl explain pv.spec
命令用于查看 PV 規格中的 spec
字段的詳細說明。以下是 pv.spec
的說明:
-
spec.nfs
:用于定義 NFS 類型的存儲。 -
path
:指定了掛載卷的路徑。 -
server
:指定了 NFS 服務器的名稱。 -
spec.accessModes
:定義了 PV 的訪問模式,可以有以下三種模式,以列表的方式存在,允許定義多個訪問模式: -
ReadWriteOnce
(RWO):存儲可讀可寫,但只支持被單個 Pod 掛載。 -
ReadOnlyMany
(ROX):存儲可以以只讀的方式被多個 Pod 掛載。 -
ReadWriteMany
(RWX):存儲可以以讀寫的方式被多個 Pod 共享。
這些規格說明了 PV 中存儲類型的配置以及訪問模式的定義方式。PV 的 spec
字段允許定義不同類型的存儲,并配置適當的訪問模式以滿足應用程序對持久化存儲的需求。
-
nfs 支持全部三種;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 網絡上運行 SCSI 協議的一種網絡存儲技術);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。
-
capacity
:用于定義 PV 的存儲容量。在配置中,storage
字段用于指定存儲的大小,以 GiB 或者其他存儲單位為單位。 -
storageClassName
:用于指定 PV 所屬的存儲類。存儲類是用來定義存儲資源的配置和策略,以便于 PV 和 PVC 的匹配。通過指定相同的存儲類,可以確保 PVC 和 PV 之間的匹配。 -
persistentVolumeReclaimPolicy
:定義了 PV 釋放后的回收策略,有以下幾種選項: -
Retain
(保留):當 PV 被釋放時,將 PV 標記為 "released" 狀態,數據依然保存在 PV 上,但 PV 不可用,需要手動處理數據并刪除 PV。 -
Delete
(刪除):當 PV 被釋放時,將刪除與 PV 相關聯的后端存儲資源。需要注意的是,只有某些后端存儲資源(如 AWS EBS、GCE PD、Azure Disk 和 Cinder)支持此選項。 -
Recycle
(回收):當 PV 被釋放時,將刪除 PV 上的數據,相當于執行rm -rf /thevolume/*
。需要注意的是,只有某些后端存儲資源(如 NFS 和 HostPath)支持此選項。
6.5 查看PVC的定義方式
kubectl explain pvc #查看PVC的定義方式
kubectl explain pvc
命令用于查看 PVC(PersistentVolumeClaim)的定義方式和字段說明。以下是 PVC 的基本字段說明:
-
apiVersion
:指示 Kubernetes API 的版本。對于 PVC,通常是v1
。 -
kind
:指明資源類型,在這個情況下是PersistentVolumeClaim
。 -
metadata
:包含關于 PVC 的元數據信息,如名稱、命名空間、標簽等。 -
spec
:定義了 PVC 的規格,包括請求的存儲容量、訪問模式等。PVC 的spec
字段主要包含以下屬性: -
accessModes
:一個 PVC 請求的訪問模式列表,包括ReadWriteOnce
、ReadOnlyMany
和ReadWriteMany
。 -
resources
:請求的資源,通常是存儲資源。在resources
下的requests
字段中可以指定所需的存儲容量。 -
storageClassName
:指定 PVC 要使用的 StorageClass 的名稱。StorageClass 用于動態配備 PV。 -
volumeName
:如果要將 PVC 綁定到特定的 PV,則可以指定 PV 的名稱。通常,這個字段由 Kubernetes 系統自動填充,當動態配備或者預先存在的 PV 與 PVC 匹配時。 -
selector
:允許指定一個標簽選擇器來進一步約束應該綁定到 PVC 的 PV。這可以用于選擇一組特定的 PV。
PVC 是 Kubernetes 中的一種資源,它允許用戶聲明他們所需要的存儲資源。PVC 與 PV 之間的綁定可以是動態的,也可以是靜態的,取決于是否使用 StorageClass 以及如何配置 PVC 和 PV。- volumeMode
:指定所請求的卷是應被格式化為文件系統還是作為原始塊設備提供。可能的值包括 Filesystem
和 Block
。
dataSource
:指定從現有的 PVC 或快照創建新 PVC 的數據源。這允許用戶克隆現有的 PVC 或從快照創建 PVC,實現數據的復制和恢復。
PVC 的定義方式為用戶與存儲資源之間提供了一個抽象層,使得用戶無需關心底層存儲的具體實現細節,只需根據需求聲明所需的存儲容量和訪問模式。Kubernetes 系統將負責滿足這些請求,無論是通過動態地創建新的 PV 來配合 PVC,還是通過匹配現有的、未被其他 PVC 使用的 PV。
PV和PVC中的spec關鍵字段要匹配,比如存儲(storage)大小、訪問模式(accessModes)、存儲類名稱(storageClassName)
6.6 查看pvc定義規格
kubectl explain pvc.spec
-
spec.accessModes
:定義了 PVC 請求的訪問模式,必須是 PV 的訪問模式的子集。可以指定一個或多個訪問模式,以滿足應用程序的需求。支持的訪問模式包括: -
ReadWriteOnce
(RWO):存儲可讀可寫,但只支持被單個 Pod 掛載。 -
ReadOnlyMany
(ROX):存儲可以以只讀的方式被多個 Pod 掛載。 -
ReadWriteMany
(RWX):存儲可以以讀寫的方式被多個 Pod 共享。 -
spec.resources.requests.storage
:用于定義 PVC 請求的存儲容量。在requests
字段下的storage
字段中指定所需的存儲容量,以 GiB 或其他存儲單位為單位。Kubernetes 將嘗試為 PVC 分配至少指定大小的 PV。 -
spec.storageClassName
:指定 PVC 要使用的存儲類的名稱。存儲類定義了 PV 的屬性和配置,以便與 PVC 匹配。當 PVC 沒有明確指定存儲類時,將使用默認的存儲類。指定存儲類的好處在于可以根據應用程序的需求定義不同的存儲策略,例如性能、可靠性和成本等方面。
這些規格允許用戶定義 PVC 所需的存儲容量、訪問模式和存儲類,從而滿足應用程序對持久化存儲的需求。PV 將根據這些規格來為 PVC 提供相應的存儲資源,并與 PVC 進行綁定以供應用程序使用
七、NFS使用PV和PVC(靜態)
官方文檔:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
7.1 NFS主機上配置nfs存儲
mkdir -p /data/volumes/v{1..5}vim /etc/exports
/data/volumes/v1 192.168.41.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.41.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.41.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.41.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.41.0/24(rw,no_root_squash)exportfs -arvshowmount -e
這段解析是關于配置NFS(Network File System)存儲的過程,其中使用了PV(PersistentVolume)和PVC(PersistentVolumeClaim)這兩個 Kubernetes 中的概念。
-
創建了五個目錄
v1
到v5
作為存儲目錄。 -
在
/etc/exports
文件中配置了這些目錄的導出選項,允許192.168.41.0/24
網段的主機以讀寫方式掛載這些目錄,并且禁止了root
用戶權限限制。 -
通過
exportfs -arv
命令重新加載并應用了導出的設置。 -
使用
showmount -e
命令顯示了可導出的目錄列表。
這個配置使得其他主機可以通過 NFS 掛載這些目錄并進行讀寫操作。
7.2master上定義pv
定義5個PV,并且定義掛載的路徑以及訪問模式,還有PV劃分的大小
vim pv-demo.yamlapiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /data/volumes/v1server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 1Gi---apiVersion: v1
kind: PersistentVolume
metadata:name: pv002labels:name: pv002
spec:nfs:path: /data/volumes/v2server: stor01accessModes: ["ReadWriteOnce"]capacity:storage: 2Gi---apiVersion: v1
kind: PersistentVolume
metadata:name: pv003labels:name: pv003
spec:nfs:path: /data/volumes/v3server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 2Gi---apiVersion: v1
kind: PersistentVolume
metadata:name: pv004labels:name: pv004
spec:nfs:path: /data/volumes/v4server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 4Gi---apiVersion: v1
kind: PersistentVolume
metadata:name: pv005labels:name: pv005
spec:nfs:path: /data/volumes/v5server: stor01accessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 5Gi
這是一個 Kubernetes 中用于定義 PersistentVolume(持久卷)的 YAML 文件示例。每個 PersistentVolume 配置都描述了一個持久存儲卷,這些卷可以在 Kubernetes 集群中供應用程序使用。
逐段解析這個文件:
-
apiVersion
: 指定了 Kubernetes API 的版本,這里使用的是v1
版本。 -
kind
: 指定了 Kubernetes 資源的類型,這里是PersistentVolume
,表示持久卷。 -
metadata
: 元數據部分,包含了持久卷的名稱和標簽信息。 -
spec
: 規范部分,定義了持久卷的詳細配置。 -
nfs
: 指定了該持久卷使用 NFS 存儲,包括 NFS 服務器地址和路徑。 -
accessModes
: 指定了持久卷的訪問模式,可以是ReadWriteOnce
(單個節點讀寫)、ReadOnlyMany
(多個節點只讀)或ReadWriteMany
(多個節點讀寫)。 -
capacity
: 指定了持久卷的容量大小。
這個文件中包含了五個不同的持久卷配置,每個持久卷都有唯一的名稱和配置。這些持久卷可以被 Kubernetes 應用程序通過 PersistentVolumeClaim(持久卷聲明)來請求和使用。
kubectl apply -f pv-demo.yaml
kubectl get pv
執行 kubectl apply -f pv-demo.yaml
命令將會根據 pv-demo.yaml
文件中的配置創建 PersistentVolume(持久卷)。然后,kubectl get pv
命令將會列出所有已經存在的 PersistentVolume,以便確認這些持久卷是否已經成功創建并且處于可用狀態。
7.3 master上定義pvc
這里定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVC申請的大小為2Gi,此時PVC會自動去匹配多路讀寫且大小為2Gi的PV,匹配成功獲取PVC的狀態即為Bound
vim pod-vol-pvc.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mypvcnamespace: default
spec:accessModes: ["ReadWriteMany"]resources:requests:storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:name: pod-vol-pvcnamespace: default
spec:containers:- name: myappimage: ikubernetes/myapp:v1volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:claimName: mypvc
這個 YAML 文件定義了兩個 Kubernetes 資源:一個 PersistentVolumeClaim (PVC) 和一個 Pod,它們都配置在默認的命名空間中。
PersistentVolumeClaim (PVC)
-
apiVersion
: 指定了 Kubernetes API 的版本,這里是v1
。 -
kind
: 資源類型,這里是PersistentVolumeClaim
,表示一個存儲卷聲明。 -
metadata
: 包含資源的元數據,這里定義了 PVC 的名稱為mypvc
。 -
spec
: 規格定義部分。 -
accessModes
: 定義了 PVC 的訪問模式,這里是ReadWriteMany
,意味著存儲卷可以被多個節點同時以讀寫方式掛載。 -
resources
: 定義了資源請求。requests
: 指定了存儲資源的請求量,這里是2Gi
。
Pod
-
apiVersion
: 指定 Kubernetes API 的版本,這里也是v1
。 -
kind
: 資源類型,這里是Pod
。 -
metadata
: 包含資源的元數據,這里定義了 Pod 的名稱為pod-vol-pvc
。 -
spec
: 規格定義部分,描述了 Pod 的具體配置。 -
containers
: 容器數組,每個對象定義了一個容器的配置。-
name
: 容器的名稱,這里是myapp
。 -
image
: 容器的鏡像,這里使用的是ikubernetes/myapp:v1
。 -
volumeMounts
: 定義了容器內的掛載點。 -
name
: 卷的引用名稱,這里是html
。 -
mountPath
: 容器內的掛載路徑,這里是/usr/share/nginx/html
。
-
-
volumes
: 定義了 Pod 級別的存儲卷。-
name
: 卷的名稱,與volumeMounts
中的引用名稱相匹配,這里是html
。 -
persistentVolumeClaim
: 指定了卷的來源是一個 PVC。 -
claimName
: 引用 PVC 的名稱,這里是mypvc
。
-
這個配置允許 Pod pod-vol-pvc
通過 PVC mypvc
掛載一個持久卷到容器的 /usr/share/nginx/html
路徑。
kubectl apply -f pod-vol-pvc.yaml
kubectl get pv
kubectl get pvc
7.4 測試訪問
在nfs存儲服務器上創建index.html,并寫入數據,通過訪問Pod進行查看,可以獲取到相應的頁面。
cd /data/volumes/v3/
echo "welcome to use pv3" > index.html
master上測試
kubectl get pods -o wide
curl
八、搭建StorageClass + NFS(NFS 的動態 PV 創建)
搭建 StorageClass + NFS 實現 NFS 的動態 PV 創建需要使用外部存儲卷插件,稱為 Provisioner(存儲分配器)。在此過程中,NFS 使用的是 nfs-client
,作為外部 PV。
Provisioner:用于指定 Volume 插件的類型,包括內置插件(如 kubernetes.io/aws-ebs)和外部插件(如 exte卷插件會使用已經配置好的 NFS 服務器自動創建 rnal-storage 提供的 ceph.com/cephfs)。
-
內置插件:
kubernetes.io/aws-ebs
是用于 AWS Elastic Block Store(EBS)的內置插件。它能夠動態地創建和管理 AWS EBS 存儲。 -
外部插件 :
ceph.com/cephfs
,這是 Ceph 文件系統的外部插件。此外,nfs-client
也是一個外部插件,用于與 NFS 服務器集成,實現動態創建 PV。
在使用外部插件時,通常需要確保已經正確配置并運行相應的存儲系統,以便 Kubernetes 能夠利用它們進行動態 PV 的創建和管理。
步驟如下:
-
配置 NFS 服務器,確保 NFS 服務已正確配置和運行。
-
創建 StorageClass,并將 Provisioner 設置為
nfs-client
,同時指定 NFS 服務器的地址和共享路徑。 -
創建 PVC,使用上述創建的 StorageClass。
-
檢查 PV 是否已自動創建,系統會自動創建 PV 并與 PVC 綁定,實現動態的 NFS PV 創建。
參考鏈接:Kubernetes 存儲類概念
8.1 stor01節點上安裝nfs,并配置nfs服務
mkdir /opt/k8s
chmod 777 /opt/k8s/vim /etc/exports
/opt/k8s 192.168.41.0/24(rw,no_root_squash,sync)systemctl restart nfs
-
創建一個名為
/opt/k8s
的目錄:mkdir /opt/k8s
-
將
/opt/k8s
目錄的權限設置為777:chmod 777 /opt/k8s/
-
使用vim編輯
/etc/exports
文件,添加如下行,允許192.168.41.0/24
網段的主機以讀寫模式掛載/opt/k8s
目錄,并且不進行root權限轉換(norootsquash),并同步寫入(sync): -
重啟NFS服務:
systemctl restart nfs
8.2 master創建 Service Account,設置 nfs-client 對 PV,PVC,StorageClass 等的規則
在Kubernetes(k8s)集群中,創建Service Account是為了管理NFS Provisioner在集群中運行時的權限。NFS Provisioner是用于動態創建Persistent Volumes(PV)和Persistent Volume Claims(PVC)的工具,通常與StorageClass一起使用。
設置nfs-client對PV、PVC和StorageClass的規則是確保NFS Provisioner在使用NFS共享存儲時遵循一定的訪問和權限規則。這可以包括定義NFS服務器地址、共享路徑、訪問權限等配置,以便Kubernetes中的應用程序能夠正確地使用NFS存儲。通過Service Account的設置,可以為NFS Provisioner分配適當的權限,確保其能夠成功管理和提供NFS存儲服務。
vim nfs-client-rbac.yaml# 創建 Service Account 賬戶,用來管理 NFS Provisioner 在 k8s 集群中運行的權限
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner # Service Account 的名稱# 創建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: nfs-client-provisioner-clusterrole # 集群角色的名稱
rules:- apiGroups: [""]resources: ["persistentvolumes"] # 可操作的資源類型verbs: ["get", "list", "watch", "create", "delete"] # 允許的操作- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["list", "watch", "create", "update", "patch"]- apiGroups: [""]resources: ["endpoints"]verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]# 集群角色綁定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: nfs-client-provisioner-clusterrolebinding # 集群角色綁定的名稱
subjects:
- kind: ServiceAccountname: nfs-client-provisioner # 綁定的 Service Account 的名稱namespace: default # 所在的命名空間
roleRef:kind: ClusterRolename: nfs-client-provisioner-clusterrole # 所綁定的集群角色名稱apiGroup: rbac.authorization.k8s.io
這段YAML文件定義了在Kubernetes中創建一個Service Account以及相關的ClusterRole和ClusterRoleBinding來管理NFS Provisioner的權限。
-
ServiceAccount
部分定義了一個名為nfs-client-provisioner
的Service Account,用于代表NFS Provisioner在集群中運行時的身份。 -
ClusterRole
部分定義了一個名為nfs-client-provisioner-clusterrole
的ClusterRole,包含了對于Persistent Volumes(PV)、Persistent Volume Claims(PVC)、StorageClasses等資源的訪問權限規則。這些規則包括獲取、列出、監視、創建和刪除PV、PVC,以及獲取、列出、監視StorageClasses等操作。 -
ClusterRoleBinding
部分定義了一個名為nfs-client-provisioner-clusterrolebinding
的ClusterRoleBinding,將前面定義的ClusterRole綁定到先前定義的Service Account上,以確保該Service Account擁有相應的權限。
通過這些定義,可以確保NFS Provisioner在Kubernetes集群中具有適當的權限,以管理PV、PVC和StorageClasses等資源。
kubectl apply -f nfs-client-rbac.yaml
8.3 使用 Deployment 來創建 NFS Provisioner
使用Kubernetes的Deployment來部署NFS Provisioner(即nfs-client)。NFS Provisioner在Kubernetes中的作用是兩個方面:一是在NFS共享目錄下創建掛載點(volume),二是將Persistent Volumes(PV)與NFS的掛載點建立關聯,使得Kubernetes中的應用程序能夠使用NFS存儲。
通過Deployment創建NFS Provisioner的實例,可以確保其在集群中始終處于運行狀態,并且可以根據需要進行水平擴展。這樣,Kubernetes集群中的應用程序可以方便地訪問和使用NFS存儲,而無需手動管理PV和NFS之間的關聯關系。
由于 1.20 版本啟用了 selfLink,所以 k8s 1.20+ 版本通過 nfs provisioner 動態生成pv會報錯,解決方法如下:
# 修改kube-apiserver.yaml文件,設置kube-apiserver的參數
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false # 添加這一行,開啟RemoveSelfLink特性- --advertise-address=192.168.41.31 # 設置kube-apiserver的廣告地址
......# 應用kube-apiserver.yaml文件的更改
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml# 刪除kube-apiserver的Pod以便更改生效
kubectl delete pods kube-apiserver -n kube-system # 檢查kube-apiserver的Pod是否重新啟動
kubectl get pods -n kube-system | grep apiserver
這段腳本是修改 kube-apiserver.yaml 文件的步驟,其中設置了 kube-apiserver 的參數,添加了 --feature-gates=RemoveSelfLink=false
開啟了 RemoveSelfLink 特性,以及設置了 --advertise-address=192.168.41.31
作為 kube-apiserver 的廣告地址。然后通過 kubectl apply
應用修改,通過 kubectl delete pods
刪除 kube-apiserver 的 Pod 以便更改生效,最后通過 kubectl get pods
檢查 kube-apiserver 的 Pod 是否重新啟動。
創建 NFS Provisioner
# 編輯nfs-client-provisioner.yaml文件,定義NFS Provisioner的Deployment
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: nfs-client-provisioner
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisioner # 指定ServiceAccountcontainers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latest # 使用的NFS Provisioner鏡像imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumes # 掛載路徑env:- name: PROVISIONER_NAMEvalue: nfs-storage # Provisioner的名稱- name: NFS_SERVERvalue: stor01 # NFS服務器地址- name: NFS_PATHvalue: /opt/k8s # NFS共享路徑volumes:- name: nfs-client-rootnfs:server: stor01 # NFS服務器地址path: /opt/k8s # NFS共享路徑
這段 YAML 文件定義了 NFS Provisioner 的 Deployment。其中包括了指定的 Replicas 數量、選擇器、部署策略等。在 Pod 模板中,指定了使用的 ServiceAccount,鏡像來源,以及掛載的路徑等信息。此外,還定義了 NFS 服務器地址和共享路徑。
kubectl apply -f nfs-client-provisioner.yaml
kubectl get pod
8.4 創建 StorageClass
創建 StorageClass,負責建立 PVC 并調用 NFS provisioner 進行預定的工作,并讓 PV 與 PVC 建立關聯
創建 StorageClass 是為了定義存儲的類型以及如何提供存儲服務。當用戶創建 PVC(PersistentVolumeClaim)時,StorageClass 可以指導 Kubernetes 如何動態地提供 PV(PersistentVolume)。關聯 PV 與 PVC 是將 PVC 綁定到滿足其需求的 PV 上,從而實現 PVC 對存儲資源的預定工作。這通常是通過 StorageClass 中定義的配置信息來實現的,例如指定的 Provisioner、參數等。因此,當 PVC 被創建時,Kubernetes 將使用 StorageClass 中定義的規則來選擇并創建 PV,并將它們關聯起來,以滿足 PVC 的要求。
vim nfs-client-storageclass.yaml# 定義一個名為 nfs-client-storageclass 的 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass # StorageClass 的名稱
provisioner: nfs-storage # 使用的 Provisioner 名稱,需與配置文件中的 PROVISIONER_NAME 一致
parameters:archiveOnDelete: "false" # 在刪除 PVC 時是否對數據進行存檔,false 表示直接刪除數據
這個 YAML 文件定義了一個名為 nfs-client-storageclass
的 StorageClass。它指定了 NFS Provisioner 的名稱為 nfs-storage
,這與 Provisioner 配置文件中的環境變量 PROVISIONER_NAME
要保持一致。另外,設置了參數 archiveOnDelete: "false"
,表示在刪除 PersistentVolumeClaim (PVC) 時不會對數據進行存檔,即直接刪除數據。
kubectl apply -f nfs-client-storageclass.yaml
kubectl get storageclass
-
kubectl apply -f nfs-client-storageclass.yaml
: 通過 Kubernetes 的命令行工具kubectl
應用(或創建)nfs-client-storageclass.yaml
文件中定義的資源,這里是一個 StorageClass。 -
kubectl get storageclass
: 通過kubectl
獲取當前 Kubernetes 集群中所有的 StorageClass 列表。這可以用于確認上一步的 StorageClass 是否成功創建。
8.5 創建 PVC
vim test-pvc-pod.yaml# 定義持久卷聲明(PersistentVolumeClaim),用于請求持久卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-nfs-pvc # 持久卷聲明的名稱
spec:accessModes:- ReadWriteMany # 訪問模式設置為讀寫多個節點storageClassName: nfs-client-storageclass # 關聯的存儲類對象resources:requests:storage: 1Gi # 請求的存儲容量為1Gi---
# 定義Pod,用于使用持久卷
apiVersion: v1
kind: Pod
metadata:name: test-storageclass-pod # Pod 的名稱
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"args:- "sleep 3600" # 命令參數,讓容器保持運行狀態volumeMounts:- name: nfs-pvc # 指定掛載的持久卷名稱mountPath: /mnt # 掛載路徑restartPolicy: Never # Pod 的重啟策略volumes:- name: nfs-pvc # 定義一個名為nfs-pvc的卷persistentVolumeClaim:claimName: test-nfs-pvc # 引用之前定義的持久卷聲明的名稱
- 這個 YAML 文件定義了一個 Kubernetes Pod 和一個 PersistentVolumeClaim(持久卷聲明)。Pod 使用了名為
test-nfs-pvc
的持久卷聲明,請求了 1Gi 的存儲空間,并使用了nfs-client-storageclass
存儲類。Pod 中的容器使用了 BusyBox 鏡像,并將持久卷掛載到/mnt
路徑下。 Pod 的重啟策略設置為Never
,這意味著當 Pod 退出時,不會自動重啟。
kubectl apply -f test-pvc-pod.yaml
kubectl get pods
kubectl get pvc
- PVC 通過 StorageClass 自動申請到空間
8.6 查看 NFS 服務器上是否生成對應的目錄
自動創建的 PV 會以 ${namespace}-${pvcName}-${pvName} 的目錄格式放到 NFS 服務器上
ls /opt/k8s/
master進入 Pod 在掛載目錄 /mnt 下寫一個文件,然后查看 NFS 服務器上是否存在該文件
kubectl exec -it test-storageclass-pod sh
#回車
/ # cd /mnt/
#回車
/mnt # echo 'this is test file' > test.txt
#exit 退出
stor01上發現 NFS 服務器上存在,說明驗證成功
cat /opt/k8s/default-test-nfs-pvc-pvc-5550e3f1-3221-42d0-adfd-97bd46eec2f5/test.txt