目錄
默寫
1 如何將pod創建在指定的Node節點上
2 污點的種類(在node上設置)
一 掛載存儲???????
1 emptyDir存儲卷?
2 hostPath存儲卷
①在 node01 節點上創建掛載目錄
② 在 node02 節點上創建掛載目錄
③ 創建 Pod 資源?
④ 在master上檢測一下:curl??
?特點
?作用
3 nfs共享存儲卷
① 在stor01節點上安裝nfs,并配置nfs服務
② master節點操作
③ 在nfs服務器上創建index.html
④ master節點操作
?編輯 ⑤ 刪除nfs相關pod,再重新創建,可以得到數據的持久化存儲
4 掛載存儲總結
二 PVC 和 PV
1 PVC 的使用邏輯:
2 創建 StorageClass
3 PV和PVC之間的相互作用遵循這個生命周期:
4 根據這 5 個階段,PV 的狀態有以下 4 種:
5 一個PV從創建到銷毀的具體流程:
6 回收策略,Retain、Delete和Recycle。
三 回收策略?
nfs 支持全部三種
PV和PVC中的spec關鍵字段要匹配
四 NFS使用PV和PVC---靜態??
1 配置nfs存儲
2 定義PV
3 定義PVC
4 測試訪問
五 搭建 StorageClass + NFS,實現 NFS 的動態 PV 創建
1 在stor01節點上安裝nfs,并配置nfs服務
2 創建 Service Account
3 使用 Deployment 來創建 NFS Provisioner
4 創建 NFS Provisioner?
5 創建 StorageClass,負責建立 PVC 并調用 NFS provisioner 進行預定的工作,并讓 PV 與 PVC 建立關聯
6 創建 PVC 和 Pod 測試?
7 PVC 通過 StorageClass 自動申請到空間?
8 發現 NFS 服務器上存在,說明驗證成功
默寫
1 如何將pod創建在指定的Node節點上
node親和、pod親和、pod反親和:
調度策略? ? ? ? ? ? ? ? ??匹配標簽? ? ? ? ? ? ? ? ? ? ? ? 操作符
nodeAffinity? ? ? ? ? ? ? ?主機? ? ? ? ? ? ?In,NotIn,Exists,DoesNotExist,Gt,Lt
podAffinity? ? ? ? ? ? ? ? ? ?pod? ? ? ? ? ? In,NotIn,Exists,DoesNotExist, ?
podAntiAffinity? ? ? ? ? ? ?pod? ? ? ? ? ? ? ? In,NotIn,Exists,DoesNotExist,
調度目標指定主機Pod與指定Pod同一拓撲域Pod與指定Pod不在同一拓撲域
2 污點的種類(在node上設置)
當前 taint effect 支持如下三個選項:
Noschedule:表示 k8s 將不會將 Pod 調度到具有該污點的 Node 上
PreferNoschedule:表示 k8s 將盡量避免將 Pod 調度到具有該污點的 Node 上
NoExecute:表示 k8s 將不會將 pod 調度到具有該污點的 Node 上,同時會將 Node 上已經存在的? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pod 驅逐出去
一 掛載存儲
容器磁盤上的文件的生命周期是短暫的,這就使得在容器中運行重要應用時會出現一些問題。
首先,當容器崩潰時,kubelet 會重啟它,但是容器中的文件將丟失——容器以干凈的狀態(鏡像最初的狀態)重新啟動。
其次,在Pod中同時運行多個容器時,這些容器之間通常需要共享文件。
Kubernetes 中的Volume抽象就很好的解決了這些問題。Pod中的容器通過Pause容器共享? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Volume。
總結:(用本地磁盤進行掛載,把本地數據掛載虛擬機中做持久化)
查看支持存儲卷類型:
kubectl explain pod.spec.volumes
1 emptyDir存儲卷?
當Pod被分配給節點時,首先創建emptyDir卷,并且只要該Pod在該節點上運行,該卷就會存在。正如卷的名字所述,它最初是空的。
Pod 中的容器可以讀取和寫入emptyDir卷中的相同文件,盡管該卷可以掛載到每個容器中的相同或不同路徑上。當出于任何原因從節點中刪除 Pod 時,emptyDir中的數據將被永久刪除。
總結:依賴于某一個容器,從一個容器掛載到另一個容器
臨時性存儲:
emptyDir 提供的存儲是臨時的,其生命周期與所屬的 Pod 相關。
當 Pod 被刪除時,emptyDir 中的數據也會被清除,因此不適合用于持久化存儲。
Pod 內容器之間的共享:
emptyDir 在同一個 Pod 中的所有容器之間共享,容器可以讀寫其中的數據。
創建時機:
emptyDir 在 Pod 創建時被創建,當容器啟動時,可以訪問其中的空目錄。
用途
適用于需要在同一個 Pod 中的多個容器之間進行臨時數據交換或共享的場景。
例如,可以用于容器間的緩存共享、臨時文件存儲等用途。
理論版
vim pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-emptydirnamespace: defaultlabels: #加兩個標簽app: myapptier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1 #定義鏡像imagePullPolicy: IfNotPresent #拉取策略ports:- 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'] #等待2s就結束
#定義存儲卷volumes:#定義存儲卷名稱 - name: html#定義存儲卷類型emptyDir: {}
實踐版 搭建
apiVersion: v1
kind: Pod
metadata:name: pod-emptydirnamespace: defaultlabels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80volumeMounts:- name: ky35mountPath: /usr/share/nginx/html/- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: ky35mountPath: /data/command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']volumes:- name: ky35emptyDir: {}
kubectl apply -f pod-emptydir.yamlkubectl get pods -o wide
?
kubectl exec -it pod-emptydir -c busybox sh? ? ? ?#進入容器
?概括:定義了2個容器,其中一個容器是輸入日期到index.html中,然后驗證訪問nginx的html是否可以獲取日期。以驗證兩個容器之間掛載的emptyDir實現共享。
總結:
emptypir: 可以實現pod中的容器之間共享數據,但是存儲卷不能持久化數據,且會隨著pod 生命周結束而一起刪除
hostpath: 可以實現持久化存儲,使用node節點的目錄或文件掛載到容器,但是存儲空間會受到弄得節點單機限制,node節點故障數據會丟失,pod跨節點不能共享數據
失敗總結------強制刪除
kubectl delete pod pod-emptydir --force --grace-period=0
2 hostPath存儲卷
hostPath卷將 node 節點的文件系統中的文件或目錄掛載到集群中。
hostPath可以實現持久存儲,但是在node節點故障時,也會導致數據的丟失。
apiVersion: v1
kind: Pod
metadata:name: pod-hostpathnamespace: default
spec:containers:- name: myappimage: soscscs/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
①在 node01 節點上創建掛載目錄
mkdir -p /data/pod/volume1
echo 'node01.kgc.com' > /data/pod/volume1/index.html
② 在 node02 節點上創建掛載目錄
mkdir -p /data/pod/volume1
echo 'node02.kgc.com' > /data/pod/volume1/index.html
③ 創建 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
④ 在master上檢測一下:curl??
kubectl apply -f pod-hostpath.yaml
訪問測試
kubectl get pods -o wide
注意:若啟動不run 就重啟一下
?特點
直接訪問主機文件系統: HostPath存儲卷允許Pod直接訪問主機節點上的文件系統,提供了對主機存儲的直接訪問權限。
讀寫權限: Pod可以對HostPath上的文件進行讀寫操作,這為一些需要在容器內進行文件操作的應用提供了便利。
節點依賴性: Pod使用HostPath時,會依賴節點上的具體路徑,這可能導致在不同節點上部署相同Pod時出現問題,因為節點之間的文件系統路徑可能不同。
共享資源:多個Pod可以共享同一個HostPath,但要小心避免數據沖突或競爭條件
?作用
主機文件操作: 適用于需要在Pod內進行主機文件系統操作的場景,例如讀取或寫入主機上的特? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 定文件。
數據共享: 多個Pod可以共享同一個HostPath,這在一些需要多個Pod之間共享數據的情況下可? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 能很有用。
特殊需求: 用于滿足一些特殊需求,例如某些應用需要在容器內直接操作主機上的某些文件。
需要注意的是,由于HostPath存儲卷的使用可能涉及到權限和安全性的考慮,一般情況下建議慎重使用,并確保在生產環境中采取適當的安全措施
3 nfs共享存儲卷
注意:只是共享存儲,沒有存儲能力,pod可以跨node節點共享數據
NAS存儲設備? + NFS? 才能共享出去
GFS--自動搭? ?ceph---第三方? ?NAS---第三方
云端存儲:oss? ?s3? ?SLB? ?LB? ?CDN? ? AWS
① 在stor01節點上安裝nfs,并配置nfs服務
在stor01節點上安裝nfs,并配置nfs服務
mkdir /data/volumes -p
chmod 777 /data/volumes
vim /etc/exports
/data/volumes 192.168.10.0/24(rw,no_root_squash)systemctl start rpcbind
systemctl start nfsshowmount -e
Export list for stor01:
/data/volumes 192.168.10.0/24
做映射
② master節點操作
kind: Pod
vim pod-nfs-vol.yaml
apiVersion: v1
metadata:name: pod-vol-nfsnamespace: default
spec:containers:- name: myappimage: ikubernetes/myapp:v1volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlnfs:path: /data/volumesserver: stor01
apiVersion: v1
kind: Pod
metadata:name: pod-nfsnamespace: default
spec:containers:- name: myappimage: soscscs/myapp:v1volumeMounts:- name: ky35mountPath: /usr/share/nginx/htmlvolumes:- name: ky35nfs:path: /data/volumesserver: 192.168.11.14
kubectl apply -f pod-nfs-vol.yaml
kubectl get pods -o wide
③ 在nfs服務器上創建index.html
cd /data/volumes
vim index.html
<h1> nfs stor01</h1>
④ master節點操作
⑤ 刪除nfs相關pod,再重新創建,可以得到數據的持久化存儲
kubectl delete -f demo03.yaml?
?kubectl delete -f pod-nfs-vol.yaml ?
失敗總結
特點
共享性: NFS存儲卷允許多個Pod在集群中共享同一個NFS服務器上的存儲空間。這使得多個應? ? ? ? ? ? ? ? ? ?用程序可以訪問和操作相同的數據,促進了數據共享和協作。
持久性: NFS存儲卷提供了持久化的存儲解決方案,數據存儲在NFS服務器上并且在Pod重新啟? ? ? ? ? ? ? ? ? ? 動或遷移時仍然可用。這對于需要長期保存數據的應用程序和服務非常有用。
可擴展性: NFS存儲卷可以輕松地擴展以滿足應用程序的需求。通過在NFS服務器上添加更多的? ? ? ? ? ? ? ? ? ? ? ? ? 存儲空間或者增加NFS服務器的數量,可以擴展存儲容量和性能。
靈活性: 使用NFS存儲卷可以將存儲與Pod分離,從而使得Pod可以在不同的節點上遷移而不會丟? ? ? ? ? ? ? ? ? 失數據。這種靈活性使得在Kubernetes集群中部署和管理應用程序變得更加容易。
用途
簡化管理: NFS存儲卷可以通過Kubernetes的PV和PVC對象進行聲明和管理,而無需手動管理存? ? ? ? ? ? ? ? ? ? ? 儲配置。這簡化了存儲管理的流程,并提高了部署和維護的效率。
適用范圍廣泛: NFS存儲卷適用于許多不同類型的應用程序和場景,包括數據庫、文件共享、日? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 志存儲等。它提供了一種通用的存儲解決方案,適用于各種不同的業務需求。
4 掛載存儲總結
emptypir :可以實現Pod中的容器之間共享數據,但是存儲卷不能持久化數據,且會隨著pod 生命周結束而一起刪除
hostpath:可以實現持久化存儲,使用node節點的目錄或文件掛載到容器,但是存儲空間會受到弄得節點單機限制,node節點故障數據會丟失,poa跨節點不能共享數據
nfs:可以實現持久化存儲,使用nfs將存儲設別空間掛載到容器中,pod可以跨node節點共享數據
二 PVC 和 PV
PV 全稱叫做 Persistent Volume,持久化存儲卷。它是用來描述或者說用來定義一個存儲卷的,這個通常都是由運維工程師來定義。
PVC 的全稱是 Persistent Volume Claim,是持久化存儲的請求。它是用來描述希望使用什么樣的或者說是滿足什么條件的 PV 存儲。
1 PVC 的使用邏輯:
在 Pod 中定義一個存儲卷(該存儲卷類型為 PVC),定義的時候直接指定大小,PVC 必須與對應的 PV 建立關系,PVC 會根據配置的定義去 PV 申請,而 PV 是由存儲空間創建出來的。PV 和 PVC 是 Kubernetes 抽象出來的一種存儲資源。
上面介紹的PV和PVC模式是需要運維人員先創建好PV,然后開發人員定義好PVC進行一對一的Bond,但是如果PVC請求成千上萬,那么就需要創建成千上萬的PV,對于運維人員來說維護成本很高,Kubernetes提供一種自動創建PV的機制,叫StorageClass,它的作用就是創建PV的模板。
2 創建 StorageClass
需要定義 PV 的屬性,比如存儲類型、大小等;另外創建這種 PV 需要用到的存儲插件,比如 Ceph 等。 有了這兩部分信息,Kubernetes 就能夠根據用戶提交的 PVC,找到對應的 StorageClass,然后 Kubernetes 就會調用 StorageClass 聲明的存儲插件,自動創建需要的 PV 并進行綁定。
- 存儲: 存儲工程師運維
- PV: k8s 管理員運維
- PVC: ?用戶維護
PV是集群中的資源,?PVC是對這些資源的請求,也是對資源的索引檢查。?
3 PV和PVC之間的相互作用遵循這個生命周期:
Provisioning(配置)---> Binding(綁定)---> Using(使用)---> Releasing(釋放) --->? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Recycling(回收)
Provisioning:即 PV 的創建,可以直接創建 PV(靜態方式),也可以使用 StorageClass 動態? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 創建
Binding:將 PV 分配給 PVC
Using:Pod 通過 PVC 使用該 Volume,并可以通過準入控制StorageProtection(1.9及以前版本? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 為PVCProtection) 阻止刪除正在使用的 PVC
Releasing:Pod 釋放 Volume 并刪除 PVC
Reclaiming:回收 PV,可以保留 PV 以便下次使用,也可以直接從云存儲中刪除
4 根據這 5 個階段,PV 的狀態有以下 4 種:
- Available(可用):表示可用狀態,還未被任何 PVC 綁定
- Bound(已綁定):表示 PV 已經綁定到 PVC
- Released(已釋放):表示 PVC 被刪掉,但是資源尚未被集群回收
- Failed(失敗):表示該 PV 的自動回收失敗
5 一個PV從創建到銷毀的具體流程:
1 一個PV創建完后狀態會變成Available,等待被PVC綁定。
2 一旦被PVC邦定,PV的狀態會變成Bound,就可以被定義了相應PVC的Pod使用。
3 Pod使用完后會釋放PV,PV的狀態變成Released。
4 變成Released的PV會根據定義的回收策略做相應的回收工作。
6 回收策略,Retain、Delete和Recycle。
Retain就是保留現場,K8S集群什么也不做,等待用戶手動去處理PV里的數據,處理完后,再手? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?動刪除PV。
Delete策略,K8S會自動刪除該PV及里面的數據。
Recycle方式,K8S會將PV里的數據刪除,然后把PV的狀態變成Available,又可以被新的PVC綁? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?定使用。
三 回收策略?
kubectl explain pv.spec ? ?#查看pv定義的規格
kubectl explain pv #查看pv的定義方式
FIELDS:apiVersion: v1kind: PersistentVolumemetadata: #由于 PV 是集群級別的資源,即 PV 可以跨 namespace 使用,所以 PV 的 metadata 中不用配置 namespacename: speckubectl explain pv.spec #查看pv定義的規格
spce:nfs:(定義存儲類型)path:(定義掛載卷路徑)server:(定義服(定義訪問模型,務器名稱)accessModes:有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪問模式) * * *- ReadWriteOnce #(RWO)存儲可讀可寫,但只支持被單個 Pod 掛載- ReadOnlyMany #(ROX)存儲可以以只讀的方式被多個 Pod 掛載- ReadWriteMany #(RWX)存儲可以以讀寫的方式被多個 Pod 共享 注:官網
#nfs 支持全部三種;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 網絡上運行 SCSI 協議的一種網絡存儲技術);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。capacity:(定義存儲能力,一般用于設置存儲空間)storage: 2Gi (指定大小)storageClassName: (自定義存儲類名稱,此配置用于綁定具有相同類別的PVC和PV)persistentVolumeReclaimPolicy: Retain #回收策略(Retain/Delete/Recycle) * * *
#Retain(保留):當刪除與之綁定的PVC時候,這個PV被標記為released(PVC與PV解綁但還沒有執行回收策略)且之前的數據依然保存在該PV上,但是該PV不可用,需要手動來處理這些數據并刪除該PV。
#Delete(刪除):刪除與PV相連的后端存儲資源(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
#Recycle(回收):刪除數據,效果相當于執行了 rm -rf /thevolume/* (只有 NFS 和 HostPath 支持)kubectl explain pvc #查看PVC的定義方式
KIND: PersistentVolumeClaim
VERSION: v1
FIELDS:apiVersion <string>kind <string> metadata <Object>spec <Object>
nfs 支持全部三種
iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 網絡上運行 SCSI 協議的一種網絡存儲技術);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。
- capacity:? ?(定義存儲能力,一般用于設置存儲空間)
- ?storage:? ?2Gi (指定大小)
- ? storageClassName: (自定義存儲類名稱,此配置用于綁定具有相同類別的PVC和PV)
? persistentVolumeReclaimPolicy:? ?Retain ? ?#回收策略(Retain/Delete/Recycle)
Retain(保留):當刪除與之綁定的PVC時候,這個PV被標記為released(PVC與PV解綁但還沒有執行回收策略)且之前的數據依然保存在該PV上,但是該PV不可用,需要手動來處理這些數據并刪除該PV。Delete(刪除):刪除與PV相連的后端存儲資源(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)Recycle(回收):刪除數據,效果相當于執行了 rm -rf /thevolume/* (只有 NFS 和 HostPath 支持)
kubectl explain pv.spec ? ?#查看pv定義的規格
PV和PVC中的spec關鍵字段要匹配
比如存儲(storage)大小、訪問模式(accessModes)、存儲類名稱(storageClassName)
kubectl explain pvc.spec
spec:accessModes: (定義訪問模式,必須是PV的訪問模式的子集)resources:requests:storage: (定義申請資源的大小)storageClassName: (定義存儲類名稱,此配置用于綁定具有相同類別的PVC和PV)
四 NFS使用PV和PVC---靜態??
結論:只能創建一些簡單的,
官方文檔:
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
1 配置nfs存儲
mkdir v{1,2,3,4,5}
vim /etc/exports
/data/volumes/v1 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.10.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.10.0/24(rw,no_root_squash)exportfs -arv
showmount -e
2 定義PV
這里定義5個PV,并且定義掛載的路徑以及訪問模式,還有PV劃分的大小。
vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /data/volumes/v1server:stor01 accessModes: ["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
?
?
術語解析?
配置文件解析PersistentVolumeClaim (PVC)apiVersion: 指定了 Kubernetes API 的版本,這里是 v1。
kind: 資源類型,這里是 PersistentVolumeClaim,表示一個存儲卷聲明。
metadata: 包含資源的元數據,這里定義了 PVC 的名稱為 mypvc。
spec: 規格定義部分。
accessModes: 定義了 PVC 的訪問模式,這里是 ReadWriteMany,意味著存儲卷可以被多個節點同時以讀寫方式掛載。
resources: 定義了資源請求。
requests: 指定了存儲資源的請求量,這里是 2Gi。
PodapiVersion: 指定 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。
3 定義PVC
這里定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVC申請的大小為2Gi,此時PVC會自動去匹配多路讀寫且大小為2Gi的PV,匹配成功獲取PVC的狀態即為Bound?
apiVersion: 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
?
4 測試訪問
在存儲服務器上創建index.html,并寫入數據,通過訪問Pod進行查看,可以獲取到相應的頁面。
cd /data/volumes/v3/
echo "welcome to use pv3" > index.html
?術語解析
PersistentVolumeClaim (PVC)apiVersion: 指定了 Kubernetes API 的版本,這里是 v1。
kind: 資源類型,這里是 PersistentVolumeClaim,表示一個存儲卷聲明。
metadata: 包含資源的元數據,這里定義了 PVC 的名稱為 mypvc。
spec: 規格定義部分。
accessModes: 定義了 PVC 的訪問模式,這里是 ReadWriteMany,意味著存儲卷可以被多個節點同時以讀寫方式掛載。
resources: 定義了資源請求。
requests: 指定了存儲資源的請求量,這里是 2Gi。
PodapiVersion: 指定 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。
步驟
靜態創建PV的步驟:準備好存儲設備和共享目錄
準備創建PV資源的配置文件,定義訪問模式(ReadWriteOnce、ReadOnlyMany、ReadWriteMany、ReadWriteMany)、存儲空間大小、回收策略(Retain、Recycle、Delete)、存儲設備類型、storageClassName等
準備創建PVC資源的配置文件,定義訪問模式(必要條件,必須是PV支持的訪問模式)、存儲空間大小(默認就近選擇大于等于指定大小的PV)、storageClassName等來綁定PV
創建Pod資源掛載PVC存儲卷,定義卷類型為persistentVolumeClaim,并在容器配置中定義存儲卷掛載點路徑
五 搭建 StorageClass + NFS,實現 NFS 的動態 PV 創建
成千上萬數據存儲就需要用動態資源去創建
Kubernetes 本身支持的動態 PV 創建不包括 NFS,所以需要使用外部存儲卷插件分配PV。
https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
卷插件稱為 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。
1 在stor01節點上安裝nfs,并配置nfs服務
mkdir /opt/k8s
chmod 777 /opt/k8s/vim /etc/exports
/opt/k8s 192.168.10.0/24(rw,no_root_squash,sync)systemctl restart nfs
2 創建 Service Account,
用來管理 NFS Provisioner 在 k8s 集群中運行的權限,設置 nfs-client 對 PV,PVC,StorageClass 等的規則
vim nfs-client-rbac.yaml
創建 Service Account 賬戶,用來管理 NFS Provisioner 在 k8s 集群中運行的權限
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner
---
#創建集群角色
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-provisionernamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-clusterroleapiGroup: rbac.authorization.k8s.io
3 使用 Deployment 來創建 NFS Provisioner
NFS Provisione(即 nfs-client),有兩個功能:一個是在 NFS 共享目錄下創建掛載點(volume),另一個則是將 PV 與 NFS 的掛載點建立關聯。
由于 1.20 版本啟用了 selfLink,所以 k8s 1.20+ 版本通過 nfs provisioner 動態生成pv會報錯,解決方法如下:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false #添加這一行- --advertise-address=192.168.10.19
......kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver
4 創建 NFS Provisioner?
注意:需要在兩個節點加載鏡像才行
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 #指定Service Account賬戶containers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-storage #配置provisioner的Name,確保該名稱與StorageClass資源中的provisioner名稱保持一致- name: NFS_SERVERvalue: stor01 #配置綁定的nfs服務器- name: NFS_PATHvalue: /opt/k8s #配置綁定的nfs服務器目錄volumes: #申明nfs數據卷- name: nfs-client-rootnfs:server: stor01path: /opt/k8s
注意:一直在創建中 是因為另外兩個節點要加載鏡像?
5 創建 StorageClass,負責建立 PVC 并調用 NFS provisioner 進行預定的工作,并讓 PV 與 PVC 建立關聯
vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
provisioner: nfs-storage #這里的名稱要和provisioner配置文件中的環境變量PROVISIONER_NAME保持一致
parameters:archiveOnDelete: "false" #false表示在刪除PVC時不會對數據進行存檔,即刪除數據
kubectl apply -f nfs-client-storageclass.yaml: 通過 Kubernetes 的命令行工具 kubectl 應用(或創建)nfs-client-storageclass.yaml 文件中定義的資源,這里是一個 StorageClass。
kubectl get storageclass: 通過 kubectl 獲取當前 Kubernetes 集群中所有的 StorageClass 列表。這可以用于確認上一步的 StorageClass 是否成功創建。
6 創建 PVC 和 Pod 測試?
vim test-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-nfs-pvc
spec:accessModes:- ReadWriteManystorageClassName: nfs-client-provisioner #關聯StorageClass對象resources:requests:storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:name: test-storageclass-pod
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand:- "/bin/sh"- "-c"args:- "sleep 3600"volumeMounts:- name: nfs-pvcmountPath: /mntrestartPolicy: Nevervolumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-nfs-pvc #與PVC名稱保持一致
7 PVC 通過 StorageClass 自動申請到空間?
kubectl get pvc
查看 NFS 服務器上是否生成對應的目錄,自動創建的 PV 會以 ${namespace}-${pvcName}-${pvName} 的目錄格式放到 NFS 服務器上
ls /opt/k8s/
default-test-nfs-pvc-pvc-11670f39-782d-41b8-a842-eabe1859a456//進入 Pod 在掛載目錄 /mnt 下寫一個文件,然后查看 NFS 服務器上是否存在該文件
kubectl exec -it test-storageclass-pod sh
/ # cd /mnt/
/mnt # echo 'this is test file' > test.txt//發現 NFS 服務器上存在,說明驗證成功
cat /opt/k8s/test.txt