Keburnetes 存儲卷 volumes

K8S 的 存儲卷 volumes


emptyDir

可實現Pod中的容器之間共享目錄數據,但emptyDir存儲卷沒有持久化數據的能力,存儲卷會隨著Pod生命周期結束而一起刪除

(一個pod中創建了docker1 docker2兩個容器,他們都掛載這個emptyDir,就能實現pod內容器間數據互通)

hostPath

Node節點(宿主機)上的目錄/文件掛載到Pod容器的指定目錄中,有持久化數據的能力,但只能在單個Node節點上持久化數據,不能實現跨Node節點的Pod共享數據

(pod1在node1上生成,則掛載node1的宿主機卷,若重啟后又調度到node2,則掛載node2的宿主機卷。pod只是單純的掛載所在宿主機的目錄)

NFS

使用NFS服務將存儲卷掛載到Pod容器的指定目錄中,有持久化數據的能力,且也能實現跨Node節點的Pod共享數據

(由于NFS是網絡文件系統,pod1 pod2掛載同一個NFS,最終的文件都會寫入到NFS服務器中,實現跨pod資源共享)

PV PVC
PV:K8S在指定存儲設備空間中邏輯劃分創建的可持久化的存儲資源對象
PVC:是對PV資源對象的請求和綁定,也是Pod能掛載使用的一種存儲卷類型

?

容器磁盤上的文件的生命周期是短暫的,這就使得在容器中運行重要應用時會出現一些問題。首先,當容器崩潰時,kubelet 會重啟它,但是容器中的文件將丟失——容器以干凈的狀態(鏡像最初的狀態)重新啟動。其次,在Pod中同時運行多個容器時,這些容器之間通常需要共享文件。Kubernetes 中的Volume抽象就很好的解決了這些問題。Pod中的容器通過Pause容器共享Volume。

EmptyDir存儲卷

當Pod被分配給節點時,首先創建emptyDir卷,并且只要該Pod在該節點上運行,該卷就會存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以讀取和寫入emptyDir卷中的相同文件,盡管該卷可以掛載到每個容器中的相同或不同路徑上。當出于任何原因從節點中刪除 Pod 時,emptyDir中的數據將被永久刪除。

mkdir /opt/volumes
cd /opt/volumesvim pod-emptydir.yamlapiVersion: v1
kind: Pod
metadata:name: pod-emptydirnamespace: defaultlabels:app: myapptier: frontend
spec:containers:- name: myapp     #容器1 掛載同一個emptyDir 與容器2實現共享image: nginximagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80volumeMounts: #容器掛載數據卷- name: htmldir #使用的存儲卷名稱,如果跟下面volume字段name值相同,則表示使用volume的這個存儲卷mountPath: /usr/share/nginx/html/ #掛載至容器中哪個目錄(這里是nginx的網頁文件夾。容器2進行emptyDir寫入后 容器1即可共享使用)- name: busybox    #容器2 掛載同一個emptyDir 與容器1實現共享image: busybox:latestimagePullPolicy: IfNotPresentvolumeMounts: #在容器內定義掛載存儲名稱和掛載路徑- name: htmldir #與下面定義的存儲卷name需要相同mountPath: /data/ #容器2將emptyDir掛載到/data/。雖然與容器1掛載的目錄不同,但是本質上都是寫入的emptyDir存儲設備。掛載點不同并不影響emptyDir內的文件結構,容器2的/data/與容器1的/usr/share/nginx/html/看到的是一樣的文件command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done'] #容器2的默認執行命令。這里是為了向掛載的emptyDir內寫入index.html文件內容,實驗emptyDir的容器文件共享。(容器2寫入網頁文件,容器1 nginx即可使用網頁文件)#定義存儲卷 與containers容器同一級。在containers定義掛載這個存儲卷volumes:- name: htmldir #定義存儲卷名稱emptyDir: {} #定義存儲卷類型
kubectl apply -f pod-emptydir.yaml

kubectl get pods -o wideNAME ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ?NODE ? ? NOMINATED NODE ? READINESS GATES
pod-emptydir ? 2/2 ? ? Running ? 0 ? ? ? ? ?36s ? 10.244.2.19 ? node02 ? <none> ? ? ? ? ? <none>

//在上面定義了2個容器,其中一個容器是輸入日期到index.html中,然后驗證訪問nginx的html是否可以獲取日期。以驗證兩個容器之間掛載的emptyDir實現共享。

curl 10.244.2.19Thu May 27 18:17:11 UTC 2021
Thu May 27 18:17:13 UTC 2021
Thu May 27 18:17:15 UTC 2021
Thu May 27 18:17:17 UTC 2021
Thu May 27 18:17:19 UTC 2021
Thu May 27 18:17:21 UTC 2021
Thu May 27 18:17:23 UTC 2021

HostPath存儲卷

hostPath卷將 node 節點的文件系統中的文件或目錄掛載到集群中。
hostPath可以實現持久存儲,但是在node節點故障時,也會導致數據的丟失。

?//在 node01 節點上創建掛載目錄(測試hostpath掛載方式,因為hostpath只是pod簡單掛載宿主機的目錄,并不能做到多宿主機的數據互通。即為在pod生成在node1上就掛載node1的目錄,生成在node2就掛載node2的目錄。)

mkdir -p /data/pod/volume1
echo 'node01.xue.com' > /data/pod/volume1/index.html

//在 node02 節點上創建掛載目錄(測試hostpath掛載方式,因為hostpath只是pod簡單掛載宿主機的目錄,并不能做到多宿主機的數據互通。即為在pod生成在node1上就掛載node1的目錄,pod生成在node2就掛載node2的目錄。)

mkdir -p /data/pod/volume1
echo 'node02.xue.com' > /data/pod/volume1/index.html

//創建 Pod 資源

vim pod-hostpath.yamlapiVersion: v1
kind: Pod
metadata:name: pod-hostpathnamespace: default
spec:containers:- name: myappimage: nginxvolumeMounts: #掛載數據卷- name: htmldir #使用的存儲卷名稱,如果跟下面volume字段name值相同,則表示使用volume的這個存儲卷mountPath: /usr/share/nginx/html #掛載至容器中哪個目錄readOnly: false #讀寫掛載方式,默認為讀寫模式false#volumes字段定義了paues容器關聯的宿主機或分布式文件系統存儲卷volumes:- name: htmldir #存儲卷名稱hostPath: #hostPath方式path: /data/pod/volume1 #在宿主機上目錄的路徑type: DirectoryOrCreate #定義類型,這表示如果宿主機沒有此目錄則會自動創建
kubectl apply -f pod-hostpath.yaml

//訪問測試

kubectl get pods -o wideNAME ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ?NODE ? ? NOMINATED NODE ? READINESS GATES
pod-hostpath ? 2/2 ? ? Running ? 0 ? ? ? ? ?37s ? 10.244.2.35 ? node02 ? <none> ? ? ? ? ? <none>
curl 10.244.2.35node02.xue.com
由于pod現在調度到node2上。就掛載了node2宿主機的目錄、

//刪除pod,再重建,依舊可以訪問原來的內容,實現持久化(不過pod此時還是調度在在node2 掛載的是node2的宿主機目錄)

kubectl delete -f pod-hostpath.yaml ?
kubectl apply -f pod-hostpath.yaml?
kubectl get pods -o wideNAME ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ?NODE ? ? NOMINATED NODE ? READINESS GATES
pod-hostpath ? 2/2 ? ? Running ? 0 ? ? ? ? ?36s ? 10.244.2.37 ? node02 ? <none> ? ? ? ? ? <none>
curl ?10.244.2.37?node02.xue.com

?//刪除pod,再重建,直到pod被調度到node1上

kubectl delete -f pod-hostpath.yaml ?
kubectl apply -f pod-hostpath.yaml?
kubectl get pods -o wideNAME ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ?NODE ? ? NOMINATED NODE ? READINESS GATES
pod-hostpath ? 2/2 ? ? Running ? 0 ? ? ? ? ?36s ? 10.244.2.38 ? node01 ? <none> ? ? ? ? ? <none>
curl ?10.244.2.38node01.xue.com
由于pod現在調度到node1上。就掛載了node1宿主機的目錄、

NFS共享存儲卷?

選取一個節點做NFS存儲。(stor01 192.168.80.110)安裝并配置NFS服務。提供給pod通過網絡掛載文件系統。

生成并授權NFS分享的目錄
mkdir /data/volumes -p
chmod 777 /data/volumes
更改NFS配置分享給192.168.80.0網段的主機
vim /etc/exports/data/volumes 192.168.80.0/24(rw,no_root_squash)
啟動rpcbind(NFS的依賴項)和NFS
systemctl start rpcbind
systemctl start nfs
查看掛載情況(分享情況)
showmount -eExport list for stor01:/data/volumes 192.168.80.0/24


//master節點操作 創建pod并設置掛載NFS文件系統

vim pod-nfs-vol.yamlapiVersion: v1
kind: Pod
metadata:name: pod-vol-nfsnamespace: default
spec:containers:- name: myappimage: nginxvolumeMounts: #掛載存儲卷- name: htmldir #存儲卷名。與volume創建的存儲卷name需要保持一致mountPath: /usr/share/nginx/html #將存儲卷掛載到pod內的指定目錄(這里指定的是下面設定的NFS服務器的/data/volumes,掛載到pod中的/usr/share/nginx/html目錄)volumes: #創建存儲卷- name: htmldir #存儲卷名稱nfs: #NFS方式path: /data/volumes #nfs服務器分享的文件夾#server: stor01 #nfs服務器名。需要做host主機名與IP映射,否則無法解析。可直接指定IPserver: 192.168.80.110 #nfs服務器IP
kubectl apply -f pod-nfs-vol.yaml
kubectl get pods -o wideNAME ? ? ? ? ? ? ? ? ? ? READY ? ? STATUS ? ?RESTARTS ? AGE ? ? ? IP ? ? ? ? ? ?NODE
pod-vol-nfs ? ? ? ? ? ? ?1/1 ? ? ? Running ? 0 ? ? ? ? ?21s ? ? ? 10.244.2.38 ? node02


//在nfs服務器上創建index.html(用于讓pod共享訪問)

cd /data/volumes
vim index.html<h1> nfs stor01</h1>

//master節點操作(pod由于掛載了這個NFS所以可以訪問NFS服務器上這個網頁文件,通過nginx發布網頁)

curl 10.244.2.38<h1> nfs stor01</h1>

? #刪除nfs相關pod,再重新創建,可以發現無論在pod調度在node1上還是在node2上都可以獲取到存儲卷內文件(可以得到數據的持久化存儲,數據都存儲在NFS服務器上,pod掛載nfs。)

kubectl delete -f pod-nfs-vol.yaml 
kubectl apply -f pod-nfs-vol.yaml
kubectl get pods -o wideNAME ? ? ? ? ? ? ? ? ? ? READY ? ? STATUS ? ?RESTARTS ? AGE ? ? ? IP ? ? ? ? ? ?NODE
pod-vol-nfs ? ? ? ? ? ? ?1/1 ? ? ? Running ? 0 ? ? ? ? ?21s ? ? ? 10.244.2.39 ? node01
curl 10.244.2.39<h1> nfs stor01</h1>




PVC 和 PV?

PV 全稱叫做 Persistent Volume,持久化存儲卷。它是用來描述或者說用來定義一個存儲卷的,這個通常都是由運維工程師來定義。

PVC 的全稱是 Persistent Volume Claim,是持久化存儲的請求。它是用來描述希望使用什么樣的或者說是滿足什么條件的 PV 存儲。

PVC 的使用邏輯:在 Pod 中定義一個存儲卷(該存儲卷類型為 PVC),定義的時候直接指定大小,PVC 必須與對應的 PV 建立關系,PVC 會根據配置的定義去 PV 申請,而 PV 是由存儲空間創建出來的。PV 和 PVC 是 Kubernetes 抽象出來的一種存儲資源。

上面介紹的PV和PVC模式是需要運維人員先創建好PV,然后開發人員定義好PVC進行一對一的Bond,但是如果PVC請求成千上萬,那么就需要創建成千上萬的PV,對于運維人員來說維護成本很高,Kubernetes提供一種自動創建PV的機制,叫StorageClass,它的作用就是創建PV的模板。

創建 StorageClass 需要定義 PV 的屬性,比如存儲類型、大小等;另外創建這種 PV 需要用到的存儲插件,比如 Ceph 等。 有了這兩部分信息,Kubernetes 就能夠根據用戶提交的 PVC,找到對應的 StorageClass,然后 Kubernetes 就會調用 StorageClass 聲明的存儲插件,自動創建需要的 PV 并進行綁定。

PV是集群中的資源。 PVC是對這些資源的請求,也是對資源的索引檢查。?

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 以便下次使用,也可以直接從云存儲中刪除

根據這 5 個階段,PV 的狀態有以下 4 種

  • Available(可用):表示可用狀態,PV 被創建出來了,還未被 PVC 綁定
  • Bound(已綁定):表示 PV 已經被 PVC 綁定,PV 與 PVC 是一對一的綁定關系
  • Released(已釋放):表示 PVC 被刪除,但是 PV 資源還未被回收
  • Failed(失敗):表示 PV 自動回收失敗

一個PV從創建到銷毀的具體流程如下

  1. 一個PV創建完后狀態會變成Available,等待被PVC綁定。
  2. 一旦被PVC邦定,PV的狀態會變成Bound,就可以被定義了相應PVC的Pod使用。
  3. Pod使用完后會釋放PV,PV的狀態變成Released。
  4. 變成Released的PV會根據定義的回收策略做相應的回收工作。有三種回收策略,Retain、Delete和Recycle。
    1. Retain就是保留現場,K8S集群什么也不做,等待用戶手動去處理PV里的數據,處理完后,再手動刪除PV。
    2. Delete策略,K8S會自動刪除該PV及里面的數據。
    3. Recycle方式,K8S會將PV里的數據刪除,然后把PV的狀態變成Available,又可以被新的PVC綁定使用。

pv的參數

kubectl explain pv ? ?#查看pv的定義方式FIELDS:apiVersion: v1kind: PersistentVolumemetadata: ? ?#由于 PV 是集群級別的資源,即 PV 可以跨 namespace 使用,所以 PV 的 metadata 中不用配置 namespacename:?spec
kubectl explain pv.spec ? ?#查看pv定義的規格spec:nfs:(定義存儲類型)path:(定義掛載卷路徑)server:(定義服務器名稱)accessModes:(定義訪問模型,有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪問模式)- ReadWriteOnce ? ? ? ? ?#(RWO)卷可以被一個節點以讀寫方式掛載。 ReadWriteOnce 訪問模式也允許運行在同一節點上的多個 Pod 訪問卷。- ReadOnlyMany ? ? ? ? ? #(ROX)卷可以被多個節點以只讀方式掛載。- ReadWriteMany ? ? ? ? ?#(RWX)卷可以被多個節點以讀寫方式掛載。
#nfs 支持全部三種;iSCSI 不支持 ReadWriteMany(iSCSI 就是在 IP 網絡上運行 SCSI 協議的一種網絡存儲技術);HostPath 不支持 ReadOnlyMany 和 ReadWriteMany。capacity:(定義存儲能力,一般用于設置存儲空間)storage: 2Gi (指定大小)storageClassName: (自定義存儲類名稱,此配置用于綁定具有相同類別的PVC和PV)用于pvc指定使用pvpersistentVolumeReclaimPolicy: Retain ? ?#回收策略(Retain/Delete/Recycle)
#Retain(保留):當用戶刪除與之綁定的PVC時候,這個PV被標記為released(PVC與PV解綁但還沒有執行回收策略)且之前的數據依然保存在該PV上,但是該PV不可用,需要手動來處理這些數據并刪除該PV。
#Delete(刪除):刪除與PV相連的后端存儲資源。對于動態配置的PV來說,默認回收策略為Delete。表示當用戶刪除對應的PVC時,動態配置的volume將被自動刪除。(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
#Recycle(回收):如果用戶刪除PVC,則刪除卷上的數據,卷不會刪除。(只有 NFS 和 HostPath 支持)

pvc的參數?

kubectl explain pvc ? #查看PVC的定義方式KIND: ? ? PersistentVolumeClaim
VERSION: ?v1
FIELDS:apiVersion?? ?<string>kind?? ?<string> ?metadata?? ?<Object>spec?? ?<Object>

#PV和PVC中的spec關鍵字段要匹配,比如存儲(storage)大小、訪問模式(accessModes)、存儲類名稱(storageClassName)

kubectl explain pvc.specspec:accessModes: (定義訪問模式,必須是PV的訪問模式的子集)resources:requests:storage: (定義申請資源的大小)storageClassName: (定義存儲類名稱,此配置用于1.綁定具有相同類別的PVC和PV(靜態創建pv情況)2.引用storageclass通過插件創建pv(動態創建pv情況))

NFS使用PV和PVC

PV/PVC調度方式?

你知道哪些kubernetes存儲資源對象 ?? ? /? ? ?kubernetes中 怎么存儲數據?【重要】

? ? ? ? ? ? ? PV? ? ? ? ? ? ? ? ?PVC????????

創建 PV 的方式(PV的類型)

  • 手動根據配置文件創建的靜態PV
  • 通過StorageClass調用存儲卷插件創建的動態PV

怎么創建pv pvc【重要】

動態創建

動態方式是 通過存儲卷插件和storageclass來實現的

  1. 準備好存儲設備和共享目錄
  2. 如果是外置存儲卷插件,需要先創建serviceaccount賬戶(Pod使用的賬戶)和做RBAC授權(創建角色授予相關資源對象的操作權限,再將賬戶和角色進行綁定),使serviceaccount賬戶具有對PV PVC StorageClass等資源的操作權限? ? ? ? ?先創建存儲卷插件用戶,然后給用戶授權
  3. 創建外置存儲卷插件provisioner的Pod,配置中使用serviceaccount賬戶作為Pod的用戶,并設置相關環境變量參數? ? ? ? ? ?使用存儲卷用戶創建存儲卷插件的pod
  4. 創建StorageClass(SC)資源,配置中引用存儲卷插件的插件名稱(PROVISIONER_NAME)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???創建storageclass引用存儲卷插件

---------------- 以上操作都是做授權,是一勞永逸的,以后只需要創建PVC時設置StorageClass就可以自動調用存儲卷插件動態生成PV資源 ----------------

  1. 創建PVC資源,配置中設置 StorageClass資源名稱 訪問模式 存儲空間大小。創建PVC資源會自動創建相關的PV資源。? ? ? ?? 創建pvc引用storageclass
  2. 創建Pod資源掛載PVC存儲卷,配置存儲卷類型為 persistentVolumeClaim ,并在容器配置中定義存儲卷掛載點目錄? ? ? ? ? ? ? ?創建pod 掛載pvc存儲卷

創建使用 靜態PV

  1. 準備好存儲設備和共享目錄
  2. 手動創建PV資源,配置 存儲卷類型 訪問模式(RWO RWX ROX RWOP) 存儲空間大小 ?回收策略(Retain Recycle Delete)等? ? ? ? ?手動創建pv資源
  3. 創建PVC資源,配置請求PV資源的訪問模式(必要條件,必須是PV能支持的訪問模式) 存儲空間大小(默認就近選擇大于等于指定大小的PV)來綁定PV? ? ?pvc與pv綁定
  4. 創建Pod和Pod控制器資源掛載PVC存儲卷,配置存儲卷類型為 persistentVolumeClaim ,并在容器配置中定義存儲卷掛載點目錄? ? ? ? ? 創建pod掛載使用pvc類型存儲卷

1、配置nfs存儲

mkdir -p /data/volumes/
cd /data/volumes/
mkdir v{1,2,3,4,5}vim /etc/exports
/data/volumes/v1 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v4 192.168.80.0/24(rw,no_root_squash)
/data/volumes/v5 192.168.80.0/24(rw,no_root_squash)
systemctl stop firewalld

?

exportfs -arvshowmount -e

?2、手動定義PV
//這里定義5個PV,并且定義掛載的路徑以及訪問模式,還有PV劃分的大小。?

pv只管自己創建,不用考慮與pvc的對應關系: pvc無需指定使用哪一個pv,pvc只管發布需求,然后系統會匹配最近似的pv。

pod則需要指定存儲卷,并在存儲卷中指定使用哪一個pvc,然后再給容器掛載上這個存儲卷。

vim pv-demo.yamlapiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /data/volumes/v1#server: stor01server: 192.168.80.110 #做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPaccessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 1Gi#persistentVolumeReclaimPoilcy: Recycle #pv回收方式#storageClassName: slow #在pvc中指定同樣的storageClassName,可以讓pvc指定使用某一pv
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv002labels:name: pv002
spec:nfs:path: /data/volumes/v2#server: stor01server: 192.168.80.110 #做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPaccessModes: ["ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv003labels:name: pv003
spec:nfs:path: /data/volumes/v3#server: stor01server: 192.168.80.110 #做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPaccessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv004labels:name: pv004
spec:nfs:path: /data/volumes/v4#server: stor01server: 192.168.80.110 #做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPaccessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv005labels:name: pv005
spec:nfs:path: /data/volumes/v5#server: stor01server: 192.168.80.110 #做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPaccessModes: ["ReadWriteMany","ReadWriteOnce"]capacity:storage: 5Gi
kubectl apply -f pv-demo.yaml
kubectl get pvNAME ? ? ?CAPACITY ? ACCESS MODES ? RECLAIM POLICY ? STATUS ? ? ?CLAIM ? ? STORAGECLASS ? REASON ? ?AGE
pv001 ? ? 1Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?7s
pv002 ? ? 2Gi ? ? ? ?RWO ? ? ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?7s
pv003 ? ? 2Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?7s
pv004 ? ? 4Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?7s
pv005 ? ? 5Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ??? ??? ?7s

3、在配置文件中 定義PVC 并在容器中引用
//這里定義了pvc的訪問模式為多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVC申請的大小為2Gi,此時PVC會自動去匹配多路讀寫且大小為2Gi的PV,匹配成功獲取PVC的狀態即為Bound

pv只管自己創建,不用考慮與pvc的對應關系: pvc無需指定使用哪一個pv,pvc只管發布需求,然后系統會匹配最近似的pv。

pod則需要指定存儲卷,并在存儲卷中指定使用哪一個pvc,然后再給容器掛載上這個存儲卷。

vim pod-vol-pvc.yaml
在這個yaml文件中寫了pvc與pod兩個配置文件。也可以分開寫兩個yaml配置文件#定義pvc的配置文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mypvc #保持一致🧨 定義pvc名namespace: default
spec:accessModes: ["ReadWriteMany"]resources:requests:storage: 2Gi---#容器的配置文件。在容器中指定使用pvc
apiVersion: v1
kind: Pod
metadata:name: pod-vol-pvcnamespace: default
spec:containers:- name: myappimage: nginxvolumeMounts:- name: htmldir #保持一致?mountPath: /usr/share/nginx/htmlvolumes:- name: htmldir #保持一致? 指定存儲卷名persistentVolumeClaim: #存儲卷使用PVC方式claimName: mypvc #保持一致🧨 指定使用哪個pvc
kubectl apply -f pod-vol-pvc.yaml

系統自動選擇最適合的pv進行綁定(pvc需求2G并且RWX。pv003最好的滿足了。并且一個pv只能綁定一個pvc,后續pv003在解綁之前不再能被其他pvc綁定)?

kubectl get pvNAME ? ? ?CAPACITY ? ACCESS MODES ? RECLAIM POLICY ? STATUS ? ? ?CLAIM ? ? ? ? ? STORAGECLASS ? REASON ? ?AGE
pv001 ? ? 1Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?19m
pv002 ? ? 2Gi ? ? ? ?RWO ? ? ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?19m
pv003 ? ? 2Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Bound ? ? ? default/mypvc ? ? ? ? ? ? ? ? ? ? ? ? ? ?19m
pv004 ? ? 4Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?19m
pv005 ? ? 5Gi ? ? ? ?RWO,RWX ? ? ? ?Retain ? ? ? ? ? Available ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?19m
kubectl get pvcNAME ? ? ?STATUS ? ?VOLUME ? ?CAPACITY ? ACCESS MODES ? STORAGECLASS ? AGE
mypvc ? ? Bound ? ? pv003 ? ? 2Gi ? ? ? ?RWO,RWX ? ? ? ? ? ? ? ? ? ? ? 22s

4、測試訪問
//在NFS存儲服務器上創建index.html,并寫入數據,通過訪問Pod進行查看,可以獲取到相應的頁面。

cd /data/volumes/v3/
echo "welcome to use pv3" > index.html
kubectl get pods -o widepod-vol-pvc ? ? ? ? ? ? 1/1 ? ? ? Running ? 0 ? ? ? ? ?3m ? ? ? ?10.244.2.4   k8s-node02
curl 10.244.2.42welcome to use pv3

注意,如果pod內容器使用pvc存儲卷,不能使用nodename指定節點調度。

使用pvc存儲 還需要做節點選擇的話 使用nodeselect,節點親和,pod親和,或是污點實現。

搭建 StorageClass + nfs-client-provisioner ,實現 NFS 的動態 PV 創建

Kubernetes 本身支持的動態 PV 創建不包括 NFS,所以需要使用外部存儲卷插件分配PV。詳見:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/

卷插件稱為 Provisioner(存儲分配器),NFS 使用的是 nfs-client,這個外部卷插件會使用已經配置好的 NFS 服務器自動創建 PV。

Provisioner:用于指定 Volume 插件的類型,包括內置插件(如 kubernetes.io/aws-ebs)和外部插件(如 external-storage 提供的 ceph.com/cephfs)。

1.準備存儲設備

2.安裝存儲卷插件(有外置【需要自己安裝】與內置區分)

3.將存儲卷插件與storageclass關聯

pvc提出需求,調用storageclass,storageclass找到相關的存儲卷插件,存儲卷插件根據需求創建指定大小 和 訪問模式的pv資源

1、在stor01節點上安裝nfs,并配置nfs服務

mkdir /opt/k8s
chmod 777 /opt/k8s/
vim /etc/exports/opt/k8s 192.168.80.0/24(rw,no_root_squash,sync)
systemctl restart nfs

2、創建 Service Account(由于NFS卷插件以pod運行 每個pod都有一個用戶賬號 而默認的default權限非常小,需要創建新用戶給NFS卷插件使用),用來管理 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 #ServiceAccount的名稱
---
#創建集群角色
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 #角色 與權限綁定namespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-clusterrole  #權限 與角色綁定apiGroup: rbac.authorization.k8s.io
kubectl apply -f nfs-client-rbac.yaml
kubectl get serviceaccounts

3、使用 Deployment 來創建 NFS Provisioner
NFS Provisioner(即 nfs-client),有兩個功能:一個是在 NFS 共享目錄下創建掛載點(volume),另一個則是將 PV 與 NFS 的掛載點建立關聯。

?#由于?1.20 版本啟用了 selfLink,所以 k8s 1.20+ 版本通過 nfs provisioner 動態生成pv會報錯,解決方法如下

vim /etc/kubernetes/manifests/kube-apiserver.yamlspec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false ? ? ? #添加這一行- --advertise-address=192.168.80.101
......
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

#創建 NFS Provisioner 存儲器插件的pod

vim nfs-client-provisioner.yamlkind: 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-provisioner #nfs插件以容器形式運行image: quay.io/external_storage/nfs-client-provisioner:latest #此處為網絡拉取NFS插件,也可以指定本地插件imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-root #對應下面存儲卷名字?mountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-storage      #😊可自定義 配置provisioner的Name(存儲卷插件的名稱),確保該名稱與StorageClass資源中的provisioner名稱保持一致- name: NFS_SERVER#value: stor01           #配置綁定的nfs服務器地址(與volume定義的server一致)value: 192.168.80.110 #🧨做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IP- name: NFS_PATHvalue: /opt/k8s         #🐔配置綁定的nfs服務器目錄(與volume定義的path一致)volumes:              #申明nfs數據卷- name: nfs-client-root #對應?nfs:#server: stor01server: 192.168.80.110 ##🧨對應 做了host主機名映射可以直接寫主機名,沒做就直接寫nfs服務器IPpath: /opt/k8s #🐔對應
kubectl apply -f nfs-client-provisioner.yaml
kubectl get podNAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
nfs-client-provisioner-cd6ff67-sp8qd ? 1/1 ? ? Running ? 0 ? ? ? ? ?14s

4、創建 StorageClass,負責建立 PVC 并調用 NFS provisioner 進行預定的工作,并讓 PV 與 PVC 建立關聯

vim nfs-client-storageclass.yamlapiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass #🔥下方pvc會指定StorageClass名,保持一致
provisioner: nfs-storage     #😊可自定義 這里的名稱要和provisioner配置文件中的環境變量PROVISIONER_NAME保持一致
parameters:archiveOnDelete: "false"   #false表示在刪除PVC時不會對數據目錄進行打包存檔,即刪除數據;為ture時就會自動對數據目錄進行打包存檔,存檔文件以archived開頭
kubectl apply -f nfs-client-storageclass.yaml
kubectl get storageclassNAME ? ? ? ? ? ? ? ? ? ? ?PROVISIONER ? RECLAIMPOLICY ? VOLUMEBINDINGMODE ? ALLOWVOLUMEEXPANSION ? AGE
nfs-client-storageclass ? nfs-storage ? Delete ? ? ? ? ?Immediate ? ? ? ? ? false ? ? ? ? ? ? ? ? ?43s

5、創建 PVC 和 Pod 測試

vim test-pvc-pod.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-nfs-pvc #?pvc名對應#annotations: volume.beta.kubernetes.io/storage-class: "nfs-client-storageclass"     #另一種SC配置方式(在元信息中添加注釋字段 關聯)
spec:accessModes:- ReadWriteManystorageClassName: nfs-client-storageclass    #🔥與上方StorageClass名保持一致 關聯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-pvc #😊名稱對應mountPath: /mntrestartPolicy: Nevervolumes:       #定義存儲卷- name: nfs-pvc #😊名稱對應persistentVolumeClaim:claimName: test-nfs-pvc      #?與PVC名稱保持一致
kubectl apply -f test-pvc-pod.yaml

?//PVC 通過 StorageClass 自動申請到空間

kubectl get pvcNAME ? ? ? ? ? ?STATUS ? VOLUME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CAPACITY ? ACCESS MODES ? STORAGECLASS ? ? ? ? ? ? ?AGE
test-nfs-pvc ? Bound ? ?pvc-11670f39-782d-41b8-a842-eabe1859a456 ? 1Gi ? ? ? ?RWX ? ? ? ? ? ?nfs-client-storageclass ? 2s

//查看 NFS 服務器上是否生成對應的目錄,自動創建的 PV 會以 ${namespace}-${pvcName}-${pvName} 的目錄格式放到 NFS 服務器上

ls /opt/k8s/
default-test-nfs-pvc-pvc-278882a7-1195-47de-8da3-8d078d84065d

//進入 Pod 在掛載目錄 /mnt 下寫一個文件,然后查看 NFS 服務器上是否存在該文件

kubectl exec -it test-storageclass-pod sh
/ # cd /mnt/
/mnt # echo 'this is test file' > test.txt

//發現 NFS 服務器上存在,說明驗證成功

cat cat /opt/k8s/default-test-nfs-pvc-pvc-278882a7-1195-47de-8da3-8d078d84065d/test.txt

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/37056.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/37056.shtml
英文地址,請注明出處:http://en.pswp.cn/news/37056.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gradle依賴管理:編譯時和運行時依賴的區別

&#x1f337;&#x1f341; 博主貓頭虎 帶您 Go to New World.?&#x1f341; &#x1f984; 博客首頁——貓頭虎的博客&#x1f390; &#x1f433;《面試題大全專欄》 文章圖文并茂&#x1f995;生動形象&#x1f996;簡單易學&#xff01;歡迎大家來踩踩~&#x1f33a; &a…

【LeetCode】《LeetCode 101》第十一章:妙用數據結構

文章目錄 11.1 C STL11.2 數組448. 找到所有數組中消失的數字&#xff08;簡單&#xff09;48. 旋轉圖像&#xff08;中等&#xff09;74. 搜索二維矩陣&#xff08;中等&#xff09;240. 搜索二維矩陣 II&#xff08;中等&#xff09;769. 最多能完成排序的塊&#xff08;中等…

java重寫與重載的區別

在Java中&#xff0c;重寫&#xff08;Override&#xff09;和重載&#xff08;Overload&#xff09;是兩種不同的概念&#xff1a; 重寫&#xff08;Override&#xff09;&#xff1a; 重寫是指子類重新定義&#xff08;覆蓋&#xff09;了從父類繼承而來的方法。重寫要求子類…

ROSpider機器人評測報告

ROSpider機器人評測報告 最近入手了一款ROSpider六足仿生機器人&#xff0c;ROSpider是一款基于ROS 操作系統開發的智能視覺六足機器人。 外觀 外觀上ROSpider六足機器人如同名字一樣有六只機械腿&#xff0c;整體來看像一只六腿的蜘蛛。腿上的關節處用了明亮的橙黃色很是顯…

Redis實現消息的發布和訂閱

Redis實現消息的發布和訂閱 1、在springboot項目的pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schem…

cookie和session的區別,分布式環境怎么保存用戶狀態

1、cookie數據存放在客戶的瀏覽器上&#xff0c;session數據放在服務器上。 2、cookie不是很安全&#xff0c;別人可以分析存放在本地的COOKIE并進行COOKIE欺騙&#xff0c;考慮到安全應當使用session。 3、session會在一定時間內保存在服務器上。當訪問增多&#xff0c;會比…

js和cocos creator學習筆記

1.Javascript有哪些數據類型?舉例兩個最常見的內置對象數據類型? 常用的數據類型:Number,String,Boolean,Null,Undefined,Object 常見內置對象:Array,Function2.下面代碼輸出內容是什么? let a []; a[10] 10; console.log(a.length); console.log(a[0]); a[200] undefi…

arcpy創建基本要素:折線和多邊形

目錄 創建Polyline折線要素步驟一&#xff1a;創建空間參考步驟二&#xff1a;創建屬性類步驟三&#xff1a;創建字段步驟四&#xff1a;創建記錄并插入幾何信息 創建Polygon多邊形要素步驟一&#xff1a;創建空間參考&#xff08;同上&#xff09;步驟二&#xff1a;創建要素類…

Redis使用Lua腳本和Redisson來保證庫存扣減中的原子性和一致性

文章目錄 前言1.使用SpringBoot Redis 原生實現方式2.使用redisson方式實現3. 使用RedisLua腳本實現3.1 lua腳本代碼邏輯 3.2 與SpringBoot集成 4. Lua腳本方式和Redisson的方式對比5. 源碼地址6. Redis從入門到精通系列文章7. 參考文檔 前言 背景&#xff1a;最近有社群技術交…

C++——函數重載及底層原理

函數重載的定義 函數重載&#xff1a; 是函數的一種特殊情況&#xff0c;C允許在同一作用域重聲明幾個功能類似的同名函數&#xff0c;這些同名函數的形參列表&#xff08;參數個數或者類型&#xff0c;類型的順序&#xff09;不同&#xff0c;常用來處理實現功能類似數據結構…

C語言字符串拷貝函數詳解及示例代碼

目錄 簡介字符串拷貝函數 strcpy字符串拷貝函數 strcpy_s使用示例注意事項結束語 1. 簡介 字符串拷貝是C語言中常用的操作之一。當需要將一個字符串復制到另一個字符串數組中時&#xff0c;可以使用字符串拷貝函數來實現。C語言提供了多種字符串拷貝函數&#xff0c;其中最常…

春秋云鏡 CVE-2021-41947

春秋云鏡 CVE-2021-41947 Subrion CMS v4.2.1 存在sql注入 靶標介紹 Subrion CMS v4.2.1 存在sql注入。 啟動場景 漏洞利用 exp http://localhost/panel/visual-mode.json?getaccess&typeblocks UNION ALL SELECT username, password FROM sbr421_members -- -&o…

【需求輸出】流程圖輸出

文章目錄 1、什么是流程圖2、繪制流程圖的工具和基本要素3、流程圖的分類和應用場景4、如何根據具體場景輸出流程圖 1、什么是流程圖 2、繪制流程圖的工具和基本要素 3、流程圖的分類和應用場景 4、如何根據具體場景輸出流程圖

Dubbo1-架構的演變

分布式系統上的相關概念 項目&#xff1a;傳統項目、互聯網項目 傳統項目&#xff1a; 一般為公司內部使用&#xff0c;或者小群體小范圍的使用&#xff0c;一般不要求性能&#xff0c;美觀&#xff0c;并發等 互聯網項目的特點&#xff1a; 1.用戶多 2.流量大&#xff0c;并…

用python來爬取某魚的商品信息(2/2)

目錄 上一篇文章 本章內容 設置瀏覽器為運行結束后不關閉&#xff08;可選&#xff09; 定位到搜索框的xpath地址 執行動作 獲取cookie 保存為json文件 修改cookie的sameSite值并且導入cookie 導入cookie&#xff08;出錯&#xff09; 導入cookie&#xff08;修改后&…

Android Ble藍牙App(五)數據操作

Ble藍牙App&#xff08;五&#xff09;數據操作 前言正文一、操作內容處理二、讀取數據① 概念② 實操 三、寫入數據① 概念② 實操 四、打開通知一、概念二、實操三、收到數據 五、源碼 前言 關于低功耗藍牙的服務、特性、屬性、描述符都已經講清楚了&#xff0c;而下面就是使…

電腦系統重裝日記

重裝原因 電腦C盤幾乎爆炸故重裝系統一清二白 此片原因 記錄重裝過程&#xff0c;強調一些要注意的點&#xff0c;以防日后重裝。 重裝過程 1.清空電腦文件后重啟&#xff0c;電腦冒藍光&#xff0c;一直藍屏反復重啟&#xff0c;故只能重裝系統以解難題。 2.準備一個U盤&…

設計HTML5文檔結構

定義清晰、一致的文檔結構不僅方便后期維護和拓展&#xff0c;同時也大大降低了CSS和JavaScript的應用難度。為了提高搜索引擎的檢索率&#xff0c;適應智能化處理&#xff0c;設計符合語義的結構顯得很重要。 1、頭部結構 在HTML文檔的頭部區域&#xff0c;存儲著各種網頁元…

Python Opencv實踐 - 圖像屬性相關

import numpy as np import cv2 as cv import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) plt.imshow(img[:,:,::-1])#像素操作 pixel img[320,370] print(pixel)#只獲取藍色通道的值 pixel_blue img[320,370,0]…

【Hystrix技術指南】(7)故障切換的運作流程原理分析(含源碼)

背景介紹 目前對于一些非核心操作&#xff0c;如增減庫存后保存操作日志發送異步消息時&#xff08;具體業務流程&#xff09;&#xff0c;一旦出現MQ服務異常時&#xff0c;會導致接口響應超時&#xff0c;因此可以考慮對非核心操作引入服務降級、服務隔離。 Hystrix說明 官方…