Kubernetes存盤卷概述
Pod本身具有生命周期,這就帶了一系列的問題,第一,當一個容器損壞之后,kubelet會重啟這個容器,但是檔案會丟失-這個容器會是一個全新的狀態;第二,當很多容器在同一Pod中運行的時候,很多時候需要資料檔案的共享,Docker支持配置容器使用存盤卷將資料持久存盤于容器自身檔案系統之外的存盤空間之中,它們可以是節點檔案系統或網路檔案系統之上的存盤空間,相應的,kubernetes也支持類似的存盤卷功能,不過,其存盤卷是與Pod資源系結而非容器,
簡單來說,存盤卷是定義在Pod資源之上、可被其內部的所有容器掛載的共享目錄,它關聯至某外部的存盤設備之上的存盤空間,從而獨立于容器自身的檔案系統,而資料是否具有持久能力取決于存盤卷自身是否支持持久機制,Pod、容器與存盤卷的關系圖如下,

Kubernetes支持的存盤卷型別
Kubernetes支持非常豐富的存盤卷型別,包括本地存盤(節點)和網路存盤系統中的諸多存盤機制,還支持Secret和ConfigMap這樣的特殊存盤資源,例如,關聯節點本地的存盤目錄與關聯GlusterFS存盤系統所需要的配置引數差異巨大,因此指定存盤卷型別時也就限定了其關聯到的后端存盤設備,通過命令# kubectl explain pod.spec可以查看當前kubernetes版本支持的存盤卷型別,常用型別如下:
非持久性存盤
emptyDir
hostPath
網路連接性存盤
SAN:iscsi
NFS:nfs、cfs
分布式存盤
glusterfs、cephfs、rbd
云端存盤
awsElasticBlockStore、azureDisk、gitRepo
存盤卷的使用方式
在Pod中定義使用存盤卷的配置由兩部分組成:一是通過
.spec.volumes欄位定義在Pod之上的存盤卷串列,其支持使用多種不同型別的存盤卷且配置引數差別很大;另一個是通過.spce.containers.volumeMounts欄位在容器上定義的存盤卷掛載串列,它只能掛載當前Pod資源中定義的具體存盤卷,當然,也可以不掛載任何存盤卷,
在Pod級別定義存盤卷時,.spec.volumes欄位的值為物件串列格式,每個物件為一個存盤卷的定義,由存盤卷名稱(.spec.volumes.name <string>)或存盤卷物件(.spec.volumes.VOL_TYPE <Object>)組成,其中VOL_TYPE是使用的存盤卷型別名稱,它的內嵌欄位隨型別的不同而不同,下面示例定義了由兩個存盤卷組成的卷串列,一個為emptyDir型別,一個是gitRepo型別,
...... volumes: - name: data emptyDir: {} - name: example gitRepo: repository: https://github.com/ikubernetes/k8s_book.git revision: master directory:
無論何種型別的存盤卷,掛載格式基本上都是相同的,通過命令# kubectl explain pod.spec.containers.volumeMounts 可以進行查看,在容器中頂一個掛載卷時的通用語法形式如下:
...... volumeMounts: - name <string> -required- #指定要掛載的存盤卷的名稱,必選欄位 mountPath <string> -required- #掛載點路徑,容器檔案系統的路徑,必選欄位 readOnly <boolean> #是否掛載為只讀卷 subPath <string> #掛載存盤卷時使用的子路徑,及mountPath指定的路徑下使用一個子路徑作為其掛載點,
示例,容器myapp將上面定義的data存盤卷掛載于/var/log/myapp,將examply掛載到/webdata/example目錄,
spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: data mountPath: /var/log/myapp/ - name: example mountPath: /webdata/example/
存盤卷使用示例
下面的所有示例的資源清單檔案都放在新建的storage目錄中,
[root@k8s-master ~]# mkdir storage [root@k8s-master ~]# cd storage/
emptyDir 存盤卷
emptyDir存盤卷是Pod物件生命周期中的一個臨時目錄,類似于Docker上的“docker 掛載卷”,在Pod物件啟動時即被創建,而在Pod物件被移除時會被一并洗掉(永久洗掉),Pod中的容器都可以讀寫這個目錄,這個目錄可以被掛載到各個容器相同或者不相同的路徑下,注意:一個容器崩潰了不會導致資料的丟失,因為容器的崩潰并不移除Pod,emptyDir的作用:
普通空間,基于磁盤的資料存盤
作為從崩潰中恢復的備份點
存盤那些需要長久保存的資料,例如
web服務中的資料
emptyDir欄位說明:
[root@k8s-master ~]# kubectl explain pod.spec.volumes.emptyDir medium <string>: #此目錄所在的存盤介質的型別,可取值為“default”或“Memory”,默認為default,表示使用節點的的默認存盤介質;Memory表示使用基于RAM的臨時的檔案系統temfs,空間受限于記憶體,但性能非常好,通常用于為容器中的應用提供快取空間, sizeLimit <string> #當前存盤卷的空間限額,默認值為nil,表示不限制;不過,在medium欄位值為“Memory”時建議務必定義此限額,
emptyDir示例:
這里定義了一個Pod資源物件(vol-emptydir-pod),在其內部定義了兩個容器,其中一個容器是輔助容器sidecar,每隔10秒生成一行資訊追加到index.html檔案中;另一個是nginx容器,將存盤卷掛載到站點家目錄,然后訪問nginx的html頁面驗證兩個容器之間掛載的emptyDir實作共享,

1)編輯資源清單檔案
[root@k8s-master storage]# vim vol-emptydir.yaml apiVersion: v1 kind: Pod metadata: name: vol-emptydir-pod spec: volumes: #定義存盤卷 - name: html #定義存盤卷的名稱 emptyDir: {} #定義存盤卷的型別 containers: - name: nginx image: nginx:1.12 volumeMounts: #在容器中定義掛載存盤卷的名和路徑 - name: html mountPath: /usr/share/nginx/html - name: sidecar image: alpine volumeMounts: #在容器中定義掛載存盤卷的名和路徑 - name: html mountPath: /html command: ["/bin/sh", "-c"] args: - while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
2)創建并查看狀態
[root@k8s-master storage]# kubectl apply -f vol-emptydir.yaml pod/vol-emptydir-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-emptydir-pod 2/2 Running 0 63s 10.244.2.79 k8s-node2 <none> <none>
3)訪問測驗
[root@k8s-master storage]# curl 10.244.2.79 vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:13 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:23 UTC 2019 ...... #進入vol-emptydir-pod中的sidecar容器中查看掛載目錄下的index.html檔案 [root@k8s-master storage]# kubectl exec vol-emptydir-pod -c sidecar -it -- /bin/sh / # ls bin etc html media opt root sbin sys usr dev home lib mnt proc run srv tmp var / # ls /html index.html / # cat /html/index.html vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 ...... #進入vol-emptydir-pod中的nginx容器中查看掛載目錄下的index.html檔案 [root@k8s-master storage]# kubectl exec vol-emptydir-pod -c nginx -it -- /bin/sh # cat /usr/share/nginx/html/index.html vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 ......
hostPath 存盤卷
hostPath型別的存盤卷是指將作業節點上的某檔案系統的目錄或檔案掛載于Pod中的一種存盤卷,獨立于Pod資源的生命周期,具有持久性,在Pod洗掉時,資料不會丟失,

hostPath欄位說明:
[root@k8s-master storage]# kubectl explain pod.spec.volumes.hostPath path <string> -required- #指定作業節點上的目錄路徑 type <string> #指定存盤卷型別 type型別如下: DirectoryOrCreate 指定的路徑不存在時自動創建其權限為0755的空目錄,屬主和屬組為kubelet Directory 必須存在的目錄路徑 FileOrCreate 指定的路徑不存在時自動創建其權限為0644的空檔案,屬主和屬組為kubelet File 必須存在的檔案路徑 Socket 必須存在的Socket檔案路徑 CharDevice 必須存在的字符設備檔案路徑 BlockDevice 必須存在的塊設備檔案路徑
hostPath示例:
1)編輯資源清單檔案
[root@k8s-master storage]# vim vol-hostpath.yaml apiVersion: v1 kind: Pod metadata: name: pod-vol-hostpath namespace: default spec: containers: - name: myapp image: nginx:1.15 imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html hostPath: path: /data/pod/volume1 type: DirectoryOrCreate
2)創建并查看狀態
[root@k8s-master storage]# kubectl apply -f vol-hostpath.yaml pod/vol-hostpath-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-hostpath-pod 1/1 Running 0 7s 10.244.1.83 k8s-node1 <none> <none>
3)通過上面查看pod被調度到節點1上面,查看節點1的目錄并創建測驗檔案
[root@k8s-node1 ~]# ll /data/pod/volume1/ 總用量 0 [root@k8s-node1 ~]# echo "<h1>kubernetes hostPath test</h1>" >> /data/pod/volume1/index.html
4)訪問測驗,及洗掉測驗
[root@k8s-master storage]# curl 10.244.1.83 <h1>kubernetes hostPath test</h1> #洗掉pod資源再次查看節點1上面的檔案 [root@k8s-master storage]# kubectl delete -f vol-hostpath.yaml pod "vol-hostpath-pod" deleted [root@k8s-node1 ~]# ll /data/pod/volume1/ 總用量 4 -rw-r--r-- 1 root root 34 10月 9 16:09 index.html
nfs 存盤卷
nfs存盤卷用于將事先存在的NFS服務器上匯出的存盤空間掛載到Pod中供容器使用,與emptyDir不同的是,當pod資源洗掉時emptyDir也會被洗掉,而NFS在Pod物件洗掉時僅是被卸載而非洗掉,這就意味NFS能夠允許我們提前對資料進行處理,而且這些資料可以在Pod之間相互傳遞,并且NFS可以同時被多個Pod掛載并進行讀寫,
nfs欄位說明:
[root@k8s-master ~]# kubectl explain pod.spec.volumes.nfs server <string> -required- #NFS服務器的IP地址或主機名,必選欄位 path <string> -required- #NFS服務器匯出(共享)的檔案系統路徑,必選欄位 readOnly <boolean> #是否以只讀方式掛載,默認為false
nfs示例:
1)首先準備一個nfs服務器
[root@storage ~]# yum -y install nfs-utils #安裝軟體 [root@storage ~]# mkdir -p /data/k8s/v1 #創建共享目錄 [root@storage ~]# vim /etc/exports #編輯組態檔配置共享目錄 /data/k8s/v1 192.168.1.0/24(rw,no_root_squash) [root@storage ~]# systemctl start rpcbind #啟動rpcbind服務(nfs依賴服務) [root@storage ~]# systemctl start nfs #啟動nfs [root@k8s-node1 ~]# showmount -e 192.168.1.34 #k8s節點測驗能否正常訪問到nfs服務器 Export list for 192.168.1.34: /data/k8s/v1 192.168.1.0/24
2)編輯資源清單檔案
[root@k8s-master storage]# vim vol-nfs.yaml
3)創建并查看狀態
[root@k8s-master storage]# kubectl apply -f vol-nfs.yaml pod/vol-nfs-pod created [root@k8s-master storage]# kubectl get pods NAME READY STATUS RESTARTS AGE vol-nfs-pod 1/1 Running 0 45s [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-nfs-pod 1/1 Running 0 51s 10.244.2.80 k8s-node2 <none> <none>
4)測驗驗證
[root@k8s-master storage]# kubectl exec -it vol-nfs-pod redis-cli 127.0.0.1:6379> set mykey "hello test" OK 127.0.0.1:6379> get mykey "hello test 127.0.0.1:6379> bgsave Background saving started 127.0.0.1:6379> exit #為了測驗其資料持久化效果,下面洗掉Pod資源vol-nfs-pod,并于再次重新創建后檢測資料是否依然能夠訪問 [root@k8s-master storage]# kubectl delete -f vol-nfs.yaml pod "vol-nfs-pod" deleted [root@k8s-master storage]# kubectl apply -f vol-nfs.yaml pod/vol-nfs-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-nfs-pod 1/1 Running 0 47s 10.244.1.84 k8s-node1 <none> <none> [root@k8s-master storage]# kubectl exec -it vol-nfs-pod redis-cli 127.0.0.1:6379> get mykey "hello test" 127.0.0.1:6379>
通過上面測驗可以看出,此前創建的mykey及其資料在Pod資源重建后依然存在,且不論pod資源調度到哪個節點,這表明在洗掉Pod資源時,其關聯的外部存盤卷并不會被一同洗掉,如果需要洗掉此類的資料,需要用戶通過存盤系統的管理介面手動進行,
PVC與PV
介紹
前面提到Kubernetes提供那么多存盤介面,但是首先Kubernetes的各個Node節點能管理這些存盤,但是各種存盤引數也需要專業的存盤工程師才能了解,由此我們的Kubernetes管理變的更加復雜,由此kubernetes提出了PV和PVC的概念,這樣開發人員和使用者就不需要關注后端存盤是什么,使用什么引數等問題,如下圖:

PV:
PersistentVolume(PV)是集群中已由管理員配置的一段網路存盤,集群中的資源就像一個節點是一個集群資源,PV是諸如卷之類的卷插件,但是具有獨立于使用PV的任何單個Pod的生命周期,該API物件捕獲存盤的實作細節,即NFS,ISCSI或云提供商特定的存盤系統,
PVC:
PersistentVolumeClaim(PVC)是用戶存盤的請求,它類似于Pod,Pod消耗節點資源,PVC消耗存盤資源,Pod可以請求特定級別的資源(CPU和記憶體),權限要求可以請求特定的大小和訪問模式,
雖然
PersistentVolumeClaims允許用戶使用抽象存盤資源,但是常見的是,用戶需要具有不同屬性(如性能)的PersistentVolumes,用于不同的問題,集群管理員需要能夠提供多種不同于PersistentVolumes的PersistentVolumes,而不僅僅是大小和訪問模式,而不會使用戶了解這些卷的實作細節,對于這些需求,存在StorageClass資源,
StorageClass為管理員提供了一種描述他們提供的存盤的“類”的方法,不同的類可能映射到服務質量級別,或備份策略,或者由集群管理員確定的任意策略,Kubernetes本身對于什么類別代表是不言而喻的,這個概念有時在其它存盤系統中稱為“組態檔”
生命周期
PV是集群中的資源,PVC是對這些資源的請求,也是對資源的索賠檢查,PV和PVC之間的相互作用遵循這個生命周期:
Provisioning—>Binding—>Using—>Releasing—>Recycling
供應準備Provisioning
PV有兩種提供方式:靜態或者動態
Static:集群管理員創建多個
PV,它們攜帶可供集群用戶使用的真實存盤的詳細資訊,它們存在于Kubernetes API中,可用于消費,Dynamic:當管理員創建的靜態
PV都不匹配用戶的PersistentVolumesClaim時,集群可能會嘗試為PVC動態配置卷,此配置基于StorageClasses:PVC必須請求一個類,并且管理員必須已經創建并配置該類才能進行動態配置,要求該類的宣告有效地位自己禁用動態配置,
系結Binding
用戶創建
PVC并指定需要的資源和訪問模式,在找到可用PV之前,PVC會保持未系結狀態,
使用Using
用戶可在
Pod中像volume一樣使用PVC,
釋放Releasing
用戶洗掉
PVC來回收存盤資源,PV將變成“released”狀態,由于還保留著之前的資料,這些資料要根據不同的策略來處理,否則這些存盤資源無法被其它PVC使用
回收Recycling
PV可以設定三種回收策略:保留(Retain)、回收(Recycle)和洗掉(Delete),
創建PV
欄位說明:
PersistentVolume Spec主要支持以下幾個通用欄位,用于定義PV的容量、訪問模式、和回收策略
[root@k8s-master ~]# kubectl explain pv.spec capacity <map[string]string> #當前PV的容量;目前,capacity僅支持空間設定,將來應該還可以指定IOPS和throughput, accessModes <[]string> #訪問模式;盡管在PV層看起來并無差異,但存盤設備支持及啟用的功能特性卻可能不盡相同,例如NFS存盤支持多客戶端同時掛載及讀寫操作,但也可能是在共享時僅啟用了只讀操作,其他存盤系統也存在類似的可配置特性,因此,PV底層的設備或許存在其特有的訪問模式,用戶使用時必須在其特性范圍內設定其功能,參考:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes - ReadWribeOnce:僅可被單個節點讀寫掛載;命令列中簡寫為RWO, - ReadOnlyMany:可被多個節點同時只讀掛載;命令列中簡寫為ROX, - ReadWriteMany:可被多個節點同時讀寫掛載;命令列中簡寫為RWX, persistentVolumeReclaimPolicy <string> #PV空間被釋放時的處理機制;可用型別僅為Retain(默認)、Recycle或Delete,具體說明如下, - Retain:保持不動,由管理員隨后手動回收, - Recycle:空間回收,即洗掉存盤卷目錄下的所有檔案(包括子目錄和隱藏檔案),目前僅NFS和hostPath支持此操作, - Delete:洗掉存盤卷,區域分云端存盤系統支持,如AWS EBS、GCE PD、Azure Disk和Cinder volumeMode <string> #卷模型,用于指定此卷可被用作檔案系統還是裸格式的塊設備;默認為Filesystem, storageClassName <string> #當前PV所屬的StorageClass的名稱;默認為空值,即不屬于任何StorageClass, mountOptions <[]string> #掛載選項組成的串列,如ro、soft和hard等,
創建PVC
欄位說明:
PersistentVolumeClaim是存盤卷型別的資源,它通過申請占用某個PersistentVolume而創建,它與PV是一對一的關系,用戶無須關系其底層實作細節,申請時,用戶只需要指定目標空間的大小、訪問模式、PV標簽選擇器和StorageClass等相關資訊即可,PVC的Spec欄位的可嵌套欄位具體如下:
[root@k8s-master ~]# kubectl explain pvc.spec accessModes <[]string> #當前PVC的訪問模式,其可用模式與PV相同 resources <Object> #當前PVC存盤卷需要占用的資源量最小值;目前,PVC的資源限定僅指其空間大小 selector <Object> #系結時對PV應用的標簽選擇器(matchLabels)或匹配條件運算式(matchEx-pressions),用于挑選要系結的PV;如果同時指定了兩種挑選機制,則必須同時滿足兩種選擇機制的PV才能被選出 storageClassName <string> #所依賴的存盤卷的名稱 volumeMode <string> #卷模型,用于指定此卷可被用作于檔案系統還是裸格式的塊設備;默認為“Filesystem” volumeName <string> #用于直接指定要系結的PV的卷名
在Pod中使用PVC
在Pod資源中呼叫PVC資源,只需要在定義volumes時使用persistentVolumeClaims欄位嵌套指定兩個欄位即可,具體如下:
[root@k8s-master ~]# kubectl explain pod.spec.volumes.persistentVolumeClaim claimName <string> -required- #要呼叫的PVC存盤卷的名稱,PVC卷要與Pod在同一名稱空間中 readOnly <boolean> #是否將存盤卷掛載為只讀模式,默認為false,
示例使用PVC和PV
說明:下面示例中,準備了一臺NFS Server創建了幾個共享目錄提供給Kubernetes作為PV使用,在創建PV的同時指定了不同的大小和不同的訪問權限,然后在創建PVC時候指定了大小為6Gi,故滿足條件的PV只有pv003~pv005,這里通過標簽選擇器選擇了pv003,Pod中的容器使用了MySQL,并將MySQL的資料目錄掛載到PV上,示例圖如下:

1)準備NFS服務
(1)創建存盤卷對應的目錄 [root@storage ~]# mkdir /data/volumes/v{1..5} -p (2)修改nfs的組態檔 [root@storage ~]# vim /etc/exports /data/volumes/v1 192.168.1.0/24(rw,no_root_squash) /data/volumes/v2 192.168.1.0/24(rw,no_root_squash) /data/volumes/v3 192.168.1.0/24(rw,no_root_squash) /data/volumes/v4 192.168.1.0/24(rw,no_root_squash) /data/volumes/v5 192.168.1.0/24(rw,no_root_squash) (3)查看nfs的配置 [root@storage ~]# exportfs -arv exporting 192.168.1.0/24:/data/volumes/v5 exporting 192.168.1.0/24:/data/volumes/v4 exporting 192.168.1.0/24:/data/volumes/v3 exporting 192.168.1.0/24:/data/volumes/v2 exporting 192.168.1.0/24:/data/volumes/v1 (4)使配置生效 [root@storage ~]# showmount -e Export list for storage: /data/volumes/v5 192.168.1.0/24 /data/volumes/v4 192.168.1.0/24 /data/volumes/v3 192.168.1.0/24 /data/volumes/v2 192.168.1.0/24 /data/volumes/v1 192.168.1.0/24
2)創建PV;這里創建5個PV,存盤大小各不相等,是否可讀也不相同
(1)撰寫資源清單檔案 [root@k8s-master storage]# vim pv-nfs-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-001 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 2Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce"] capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-003 labels: name: pv003 spec: nfs: path: /data/volumes/v3 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 10Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-004 labels: name: pv004 spec: nfs: path: /data/volumes/v4 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 15Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-005 labels: name: pv005 spec: nfs: path: /data/volumes/v5 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 20Gi persistentVolumeReclaimPolicy: Retain (2)創建PV [root@k8s-master storage]# kubectl apply -f pv-nfs-demo.yaml persistentvolume/pv-nfs-001 created persistentvolume/pv-nfs-002 created persistentvolume/pv-nfs-003 created persistentvolume/pv-nfs-004 created persistentvolume/pv-nfs-005 created (3)查看PV [root@k8s-master storage]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs-001 2Gi RWO,RWX Retain Available 2s pv-nfs-002 5Gi RWO Retain Available 2s pv-nfs-003 10Gi RWO,RWX Retain Available 2s pv-nfs-004 15Gi RWO,RWX Retain Available 2s pv-nfs-005 20Gi RWO,RWX Retain Available 2s
3)創建PVC,系結PV
(1)撰寫資源清單檔案 [root@k8s-master storage]# vim vol-nfs-pvc.yaml #創建PVC apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: ["ReadWriteMany"] resources: requests: storage: 6Gi #指定PVC大小為6Gi selector: #這里通過標簽選擇器指定了所使用的pv卷為key為name,value為pv003的pv資源 matchLabels: name: pv003 --- #創建Pod apiVersion: v1 kind: Pod metadata: name: pvc-mysql labels: app: mysql spec: containers: - name: pvc-mysql-pod image: mysql:latest imagePullPolicy: IfNotPresent ports: - name: mysqlport containerPort: 3306 volumeMounts: - name: mysqldata mountPath: /var/lib/mysql env: - name: MYSQL_ROOT_PASSWORD value: "mysql" volumes: - name: mysqldata persistentVolumeClaim: #通過該欄位定義使用pvc claimName: nfs-pvc #指定pvc的名稱 readOnly: false #關閉只讀 (2)創建PVC和Pod [root@k8s-master storage]# kubectl apply -f vol-nfs-pvc.yaml persistentvolumeclaim/nfs-pvc created pod/pvc-mysql created
4)查詢驗證pv和pvc
[root@k8s-master storage]# kubectl get pvc #查看pvc,可以看到該pvc使用的是pv-nfs-003資源 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfs-pvc Bound pv-nfs-003 10Gi RWO,RWX 12s [root@k8s-master storage]# kubectl get pv #查看pv,可以看出pv-nfs-003資源的狀態從Availabel變成了Bound NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs-001 2Gi RWO,RWX Retain Available 64m pv-nfs-002 5Gi RWO Retain Available 64m pv-nfs-003 10Gi RWO,RWX Retain Bound default/nfs-pvc 64m pv-nfs-004 15Gi RWO,RWX Retain Available 64m pv-nfs-005 20Gi RWO,RWX Retain Available 64m [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pvc-mysql 1/1 Running 0 31s 10.244.2.84 k8s-node2 <none> <none> [root@storage ~]# ls /data/volumes/v3/ #查看nfs服務器的pv3對應的共享目錄,里面生成了mysql的資料, auto.cnf ca-key.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem binlog.000001 ca.pem ibdata1 #innodb_temp private_key.pem sys binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001 binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002
5)測驗驗證
#(1)進入到pod連接容器mysql并創建一個資料庫 [root@k8s-master ~]# kubectl exec -it pvc-mysql -- mysql -u root -pmysql ...... mysql> mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec) mysql> create database volumes; Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | volumes | +--------------------+ 5 rows in set (0.00 sec) mysql> exit Bye #(2)洗掉pvc和pod和pv [root@k8s-master storage]# kubectl delete -f vol-nfs-pvc.yaml #洗掉pvc persistentvolumeclaim "nfs-pvc" deleted pod "pvc-mysql" deleted [root@k8s-master storage]# kubectl delete -f pv-nfs-demo.yaml #洗掉pv(如果有pv在被使用的狀態,需要先洗掉pvc方可洗掉pv) persistentvolume "pv-nfs-001" deleted persistentvolume "pv-nfs-002" deleted persistentvolume "pv-nfs-003" deleted persistentvolume "pv-nfs-004" deleted persistentvolume "pv-nfs-005" deleted [root@storage ~]# ls /data/volumes/v3/ #上面洗掉了pv和pvc,可以看出存盤服務器上面的資料還是存在 auto.cnf ca-key.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem volumes binlog.000001 ca.pem ibdata1 #innodb_temp private_key.pem sys binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001 binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002 #(3)重新創建pv和pvc和pod驗證資料 [root@k8s-master storage]# kubectl apply -f pv-nfs-demo.yaml persistentvolume/pv-nfs-001 created persistentvolume/pv-nfs-002 created persistentvolume/pv-nfs-003 created persistentvolume/pv-nfs-004 created persistentvolume/pv-nfs-005 created [root@k8s-master storage]# kubectl apply -f vol-nfs-pvc.yaml persistentvolumeclaim/nfs-pvc created pod/pvc-mysql created [root@k8s-master ~]# kubectl exec -it pvc-mysql -- mysql -u root -pmysql mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | volumes | +--------------------+ 5 rows in set (0.00 sec) ### 測驗說明: 如果洗掉pvc不洗掉pv,重新創建同樣的pvc,那么pvc狀態會處于Pending狀態,因為pv的當前狀態為Released,這也和上面定義的回收策略息息相關,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/5138.html
標籤:其他
