K8S 經(jīng)典實(shí)戰(zhàn)案例:NFS+StorageClass+PV/PVC+Deployment
本篇文章分享一下在 Kubernetes (K8s) 中搭建 NFS 存儲,并實(shí)現(xiàn) PersistentVolume (PV)、PersistentVolumeClaim (PVC)、動態(tài)存儲卷StorageClass,以及通過 Deployment 使用這些存儲卷的完整流程,可以按照以下步驟進(jìn)行。
實(shí)驗(yàn)步驟:
- 配置 NFS 服務(wù)器
- 創(chuàng)建 StorageClass
- 創(chuàng)建 PV
- 創(chuàng)建 PVC
- 創(chuàng)建 Deployment,并掛載 PVC 到應(yīng)用
掛載驗(yàn)證實(shí)驗(yàn)架構(gòu)圖
圖片
步驟 1: 配置 NFS 服務(wù)器
首先,在 Kubernetes 集群外部的服務(wù)器上,我們需要搭建一個后端存儲:NFS 服務(wù)器。
NFS服務(wù)器IP地址:10.0.0.103
(1) 安裝 NFS 服務(wù)
yum install -y nfs-utils
(2) 創(chuàng)建共享目錄
mkdir -p /data/nfs
(3) 配置 NFS 共享目錄
編輯 /etc/exports 文件以設(shè)置 NFS 共享目錄。
vim /etc/exports
在文件中添加以下行:
/data/nfs *(rw,sync,no_subtree_check)
將 /data/nfs 目錄以讀寫(rw)方式對所有客戶端(*)共享。
(4) 啟動 NFS 服務(wù)
啟動并將NFS服務(wù)設(shè)置開機(jī)自啟
systemctl enable --now nfs-server
(5) 導(dǎo)出共享目錄
使共享目錄立即生效:
exportfs -a
showmount -e
(6) 配置防火墻
如果啟用了防火墻,需要允許 NFS 服務(wù)的相關(guān)端口:
firewall-cmd --per --add-service=nfs
firewall-cmd --per --add-service=mountd
firewall-cmd --per --add-service=rpc-bind
firewall-cmd --reload
步驟 2: 配置StorageClass
在 Kubernetes 中,我們將使用 StorageClass 來動態(tài)配置存儲卷。通過 PVC 綁定現(xiàn)有的 NFS 存儲。
(1) 創(chuàng)建 StorageClass 配置
創(chuàng)建一個名為 nfs-storage-class.yaml 的文件,內(nèi)容如下:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage-class
provisioner: kubernetes.io/no-provisioner # NFS 不需要動態(tài) provisioner
reclaimPolicy: retain # 默認(rèn)值是 Delete
volumeBindingMode: WaitForFirstConsumer # 等待 Pod 使用 PVC 時才綁定 PV,默認(rèn)使用 Immediate 模式:立即綁定
(2) 應(yīng)用 StorageClass 配置
kubectl apply -f nfs-storage-class.yaml
檢查StorageClass狀態(tài)
[root@k8s-master data]# kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storage-class kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 14s
步驟 3: 創(chuàng)建 PV
創(chuàng)建一個 PersistentVolume (PV),將它指向 NFS 共享的目錄。
(1) 創(chuàng)建 PV 配置文件
創(chuàng)建一個 nfs-pv.yaml 文件,內(nèi)容如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi # 定義 PV 的存儲容量
volumeMode: Filesystem
accessModes:
- ReadWriteMany # 允許多個 Pod 同時訪問此 PV
persistentVolumeReclaimPolicy: Retain # 釋放 PVC 后保留 PV 數(shù)據(jù)
storageClassName: nfs-storage-class # 與 StorageClass 名稱一致
nfs:
path: /data/nfs # NFS 共享目錄的路徑
server: 10.0.0.103 # 替換為實(shí)際的 NFS 服務(wù)器 IP
(2) 應(yīng)用 PV 配置
kubectl apply -f nfs-pv.yaml
檢查 PV 的狀態(tài):
[root@k8s-master data]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfs-pv 5Gi RWX Retain Available nfs-storage-class 5s
如果 PV 配置正確,它應(yīng)該處于 Available 狀態(tài)。
步驟 4: 創(chuàng)建PVC
創(chuàng)建一個 PersistentVolumeClaim (PVC),它請求使用 NFS 存儲。
(1) 創(chuàng)建 PVC 配置文件
創(chuàng)建一個 nfs-pvc.yaml 文件,內(nèi)容如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany # 允許多個 Pod 同時訪問
volumeMode: Filesystem
resources:
requests:
storage: 3Gi # 請求的存儲容量,不能大于PV容量
storageClassName: nfs-storage-class # 與 StorageClass 名稱一致
(2) 應(yīng)用 PVC 配置
應(yīng)用 PVC 配置文件:
kubectl apply -f nfs-pvc.yaml
檢查 PVC 的狀態(tài):
[root@k8s-master data]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nfs-pvc Pending nfs-storage-class 4m30s
【溫馨提示】由于在聲明StorageClass時,將volumeBindingMode設(shè)置為WaitForFirstConsumer,等待 Pod 使用 PVC 時才綁定 PV,所以現(xiàn)在的PVC是Pending狀態(tài),沒有綁定對應(yīng)的Pod。
如果volumeBindingMode設(shè)置為Immediate,則會立即綁定,顯示為Bound。
步驟 5: 掛載 PVC
創(chuàng)建一個 Deployment,并將 PVC 掛載到 Pod 中。
(1) 創(chuàng)建 Deployment 配置文件
創(chuàng)建一個名為 nginx-deployment.yaml 的文件,內(nèi)容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1 # 部署 1 個副本(Pod)
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.m.daocloud.io/nginx:1.25
volumeMounts:
- mountPath: /usr/share/nginx/html # 將 PVC 掛載到此目錄
name: nfs-volume
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: nfs-pvc # 掛載 PVC
(2) 應(yīng)用 Deployment 配置
kubectl apply -f nginx-deployment.yaml
(3) 再次檢查PVC狀態(tài)
[root@k8s-master data]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nfs-pvc Bound nfs-pv 5Gi RWX nfs-storage-class 10m
此時可以看到已經(jīng)是Bound狀態(tài),說明已經(jīng)和Pod產(chǎn)生了關(guān)聯(lián)。
(4) 檢查 Pod 狀態(tài)
使用以下命令檢查 Pod 狀態(tài):
[root@k8s-master data]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-645c47fd8b-sjv5m 1/1 Running 0 8m35s
確保 Pod 正在運(yùn)行并沒有錯誤。
【溫馨提示】如果使用NFS作為后端存儲,需要在每個節(jié)點(diǎn)上安裝NFS客戶端,不然Pod無法連接NFS,導(dǎo)致創(chuàng)建Pod失敗。
步驟 6: 驗(yàn)證掛載
驗(yàn)證 Nginx Pod 是否正確掛載了 NFS 存儲。
(1) 進(jìn)入 Pod 檢查掛載
首先,通過 kubectl exec 命令進(jìn)入 Pod,檢查 /usr/share/nginx/html 目錄,看看是否已掛載 NFS 存儲
[root@k8s-master data]# kubectl exec -it nginx-deployment-645c47fd8b-sjv5m -- /bin/bash
root@nginx-deployment-645c47fd8b-sjv5m:/# ls /usr/share/nginx/html
kube-system-es-pv-claim-pvc-ef2cc9a4-d836-49fe-8d30-b9c98238f5b5
root@nginx-deployment-645c47fd8b-sjv5m:/#
如果一切正常,你應(yīng)該能夠看到 NFS 存儲中的內(nèi)容。如果是空的,那就意味著 Nginx Pod 已經(jīng)成功掛載了 NFS 存儲卷。
(2) 測試驗(yàn)證
測試:給index.html文件增加內(nèi)容
root@nginx-deployment-645c47fd8b-sjv5m:/usr/share/nginx/html# echo "hello nginx" > index.html
驗(yàn)證:進(jìn)入后端NFS掛載目錄查看:
[root@harbor ~]# cd /data/nfs
[root@harbor nfs]# ls
index.html kube-system-es-pv-claim-pvc-ef2cc9a4-d836-49fe-8d30-b9c98238f5b5
[root@harbor nfs]# cat index.html
hello nginx
可以看到在Pod里面創(chuàng)建的數(shù)據(jù)已經(jīng)存儲到NFS存儲中。
至此,整個持久化存儲的環(huán)境已經(jīng)搭建完成。