【轉(zhuǎn)】kubernetes 磁盤、PV、PVC以及MySQL部署

6.1.介紹卷

6.1.1.卷的類型

emptyDir-用于存儲臨時數(shù)據(jù)的簡單空目錄

hostPath-用于將目錄從工作節(jié)點的文件系統(tǒng)掛載到pod

nfs-掛載到pod中的NFS共享卷。

還有其他的如gitRepo、gcepersistenDisk

6.2.通過卷在容器間共享數(shù)據(jù)

6.2.1.使用emptyDir卷

卷的生命周期與pod的生命周期項關(guān)聯(lián),所以當(dāng)刪除pod時,卷的內(nèi)容就會丟失。

使用empty示例代碼如下:

apiVersion: v1

kind: Pod

metadata:

name: fortune

spec:

containers:

- image: luksa/fortune

name: html-gener

volumeMounts:

- name: html

mountPath: /usr/share/nginx

readOnly: true

- image: nginx/aplin

name: web-service

volumeMounts:

- name: html

mountPath: /usr/share

readOnly: true

volumes:

- name: html                        //一個名為html的單獨emptyDir卷,掛載在上面的兩個容器中

emptyDir: {}

6.3.訪問工作節(jié)點文件系統(tǒng)上的文件

6.3.1.hostPath卷

hostPath是持久性存儲,emptyDir卷的內(nèi)容隨著pod的刪除而刪除。

使用hostPath會發(fā)現(xiàn)當(dāng)刪除一個pod,并且下一個pod使用了指向主機(jī)上相同路徑的hostPath卷,則新pod將會發(fā)現(xiàn)上一個pod留下的數(shù)據(jù),但前提是必須將其調(diào)度到與第一個pod相同的節(jié)點上。

所以當(dāng)你使用hostPath時請務(wù)必考慮清楚,當(dāng)重新起一個pod時候,必須要保證pod的節(jié)點與之前相同。

apiVersion: v1

kind: Pod

metadata:

name: test-pd

spec:

containers:

- image: k8s.gcr.io/test-webserver

name: test-container

volumeMounts:

- mountPath: /test-pd

name: test-volume

volumes:

- name: test-volume

hostPath:

# directory location on host

path: /data

# this field is optional

type: Directory

6.4.使用持久化存儲

怎樣保證pod重新啟動后調(diào)度到任意一個節(jié)點都有相同的數(shù)據(jù)可用,這就需要做到持久化存儲。

因此必須要將數(shù)據(jù)存儲在某種類型的網(wǎng)絡(luò)存儲(NAS)中。

各種支持的方式不盡相同,例如 GlusterFS 需要創(chuàng)建 Endpoint,Ceph/NFS 之流就沒這么麻煩了。

6.4.1.使用NFS存儲

以NFS為例,yml代碼如下:

image

6.4.2.configmap和secert

secret和configmap可以理解為特殊的存儲卷,但是它們不是給Pod提供存儲功能的,而是提供了從集群外部向集群內(nèi)部的應(yīng)用注入配置信息的功能。ConfigMap扮演了K8S集群中配置中心的角色。ConfigMap定義了Pod的配置信息,可以以存儲卷的形式掛載至Pod中的應(yīng)用程序配置文件目錄,從configmap中讀取配置信息;也可以基于環(huán)境變量的形式,從ConfigMap中獲取變量注入到Pod容器中使用。但是ConfigMap是明文保存的,如果用來保存數(shù)據(jù)庫賬號密碼這樣敏感信息,就非常不安全。一般這樣的敏感信息配置是通過secret來保存。secret的功能和ConfigMap一樣,不過secret是通過Base64的編碼機(jī)制保存配置信息。

從ConfigMap中獲取配置信息的方法有兩種:

  • 一種是利用環(huán)境變量將配置信息注入Pod容器中的方式,這種方式只在Pod創(chuàng)建的時候生效,這就意味著在ConfigMap中的修改配置信息后,更新的配置不能被已經(jīng)創(chuàng)建Pod容器所應(yīng)用。
  • 另一種是將ConfigMap做為存儲卷掛載至Pod容器內(nèi),這樣在修改ConfigMap配置信息后,Pod容器中的配置也會隨之更新,不過這個過程會有稍微的延遲。

ConfigMap當(dāng)作存儲卷掛載至Pod中的用法:

apiVersion: v1

kind: Pod

metadata:

name: pod-configmap-vol-2

labels:

name: pod-configmap-vol-2

spec:

containers:

- name: myapp

image: ikubernetes/myapp:v1

volumeMounts:

- name: my-cm-www

mountPath: /etc/nginx/conf.d/ # 將名為my-www的configmap掛載至Pod容器的這個目錄下。

volumes:

- name: my-cm-www

configMap: # 存儲卷類型選configMap

secert的方法類似,只是secert對數(shù)據(jù)進(jìn)行了加密

6.5.從底層存儲技術(shù)解耦pod

6.5.1.介紹持久卷和持久卷聲明

當(dāng)集群用戶需要在其pod中使用持久化存儲時,他們首先創(chuàng)建持久化聲明(PVC)清單,指定所需要的最低容量要求,和訪問模式,然后用戶將持久卷聲明清單提交給kubernetes API服務(wù)器,kubernetes將找到可以匹配的持久卷并將其綁定到持久卷聲明。

持久卷聲明可以當(dāng)做pod中的一個卷來使用,其他用戶不能使用相同的持久卷,除非先通過刪除持久卷聲明綁定來釋放。

6.5.2.創(chuàng)建持久卷

下面創(chuàng)建一個 PV mypv1,配置文件pv1.yml 如下:

apiVersion: v1

kind: PersistentVolume

metadata:

name: yh_pv1

spec:

capacity:

storage: 1Gi ``//capacity 指定 PV 的容量為 1G

accessModes: ``//accessModes 指定訪問模式為 ReadWriteOnce

- ReadWriteOnce

persistentVolumeReclaimpolicy: Recycle ``//persistentVolumeReclaimPolicy 指定當(dāng) PV 的回收策略為 Recycle

storageClassName: nfs ``//storageClassName 指定 PV 的 class 為 nfs。相當(dāng)于為 PV 設(shè)置了一個分類,PVC 可以指定 class 申請相應(yīng) class 的 PV。

nfs:

path: /nfs/data ``//指定 PV 在 NFS 服務(wù)器上對應(yīng)的目錄

server: 10.10.0.11

1.accessModes 指定訪問模式為 ReadWriteOnce,支持的訪問模式有:

ReadWriteOnce – PV 能以 read-write 模式 mount 到單個節(jié)點。
  ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節(jié)點。
  ReadWriteMany – PV 能以 read-write 模式 mount 到多個節(jié)點。

2.persistentVolumeReclaimPolicy 指定當(dāng) PV 的回收策略為 Recycle,支持的策略有:
  Retain – 需要管理員手工回收。
  Recycle – 清除 PV 中的數(shù)據(jù),效果相當(dāng)于執(zhí)行 rm -rf /thevolume/*。
  Delete – 刪除 Storage Provider 上的對應(yīng)存儲資源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

創(chuàng)建 pv

# kubectl apply -f pv1.yml

persistentvolume/yh-pv1 created

查看pv:

# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

yh-pv1 1Gi RWO Recycle Available nfs 17m

STATUSAvailable,表示 yh-pv1就緒,可以被 PVC 申請。

6.5.3.通過持久卷聲明來獲取持久卷

接下來創(chuàng)建 PVC mypvc1,配置文件 pvc1.yml 如下:

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: yh-pvc

spec:

accessModes:

- ReadWriteOnce

resources:

requests:

storage: 1Gi

storageClassName: nfs

PVC 就很簡單了,只需要指定 PV 的容量,訪問模式和 class。

執(zhí)行命令創(chuàng)建 mypvc1

# kubectl apply -f pvc1.yml

persistentvolumeclaim/yh-pvc created

查看pvc

# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

yh-pvc Bound yh-pv1 1Gi RWO nfs 64s

kubectl get pvckubectl get pv 的輸出可以看到 yh-pvc1 已經(jīng) Bound 到y(tǒng)h- pv1,申請成功。

# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

yh-pv1 1Gi RWO Recycle Bound ``default``/yh-pvc nfs 47m

6.5.4.在pod中使用持久卷聲明

上面已經(jīng)創(chuàng)建好了pv和pvc,pod中直接使用這個pvc即可

image

與使用普通 Volume 的格式類似,在 volumes 中通過 persistentVolumeClaim 指定使用 mypvc1 申請的 Volume。

通過命令創(chuàng)建mypod1

image
image

可見,在 Pod 中創(chuàng)建的文件 /mydata/hello 確實已經(jīng)保存到了 NFS 服務(wù)器目錄 /nfsdata中。

如果不再需要使用 PV,可用刪除 PVC 回收 PV。

6.5.5.回收持久卷

當(dāng) PV 不再需要時,可通過刪除 PVC 回收。

image

未刪除pvc之前 pv的狀態(tài)是Bound

image

image

刪除pvc之后pv的狀態(tài)變?yōu)锳vailable,,此時解除綁定后則可以被新的 PVC 申請。

/nfsdata文件中的文件被刪除了

image
image

因為 PV 的回收策略設(shè)置為 Recycle,所以數(shù)據(jù)會被清除,但這可能不是我們想要的結(jié)果。如果我們希望保留數(shù)據(jù),可以將策略設(shè)置為 Retain

image

通過 kubectl apply 更新 PV:

image

回收策略已經(jīng)變?yōu)?Retain,通過下面步驟驗證其效果:

image

① 重新創(chuàng)建 mypvc1。

② 在 mypv1 中創(chuàng)建文件 hello。

mypv1 狀態(tài)變?yōu)?Released。

④ PV 中的數(shù)據(jù)被完整保留。

雖然 mypv1 中的數(shù)據(jù)得到了保留,但其 PV 狀態(tài)會一直處于 Released,不能被其他 PVC 申請。為了重新使用存儲資源,可以刪除并重新創(chuàng)建 mypv1。刪除操作只是刪除了 PV 對象,存儲空間中的數(shù)據(jù)并不會被刪除。

image

新建的 mypv1 狀態(tài)為 Available,已經(jīng)可以被 PVC 申請。

PV 還支持 Delete 的回收策略,會刪除 PV 在 Storage Provider 上對應(yīng)存儲空間。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

回到頂部

6.6.持久卷的動態(tài)配置

6.6.1.通過StorageClass資源定義可用存儲類型

前面的例子中,我們提前創(chuàng)建了 PV,然后通過 PVC 申請 PV 并在 Pod 中使用,這種方式叫做靜態(tài)供給(Static Provision)。

與之對應(yīng)的是動態(tài)供給(Dynamical Provision),即如果沒有滿足 PVC 條件的 PV,會動態(tài)創(chuàng)建 PV。相比靜態(tài)供給,動態(tài)供給有明顯的優(yōu)勢:不需要提前創(chuàng)建 PV,減少了管理員的工作量,效率高。

動態(tài)供給是通過 StorageClass 實現(xiàn)的,StorageClass 定義了如何創(chuàng)建 PV,下面是兩個例子。

StorageClass standard

image

StorageClass slow

image

這兩個 StorageClass 都會動態(tài)創(chuàng)建 AWS EBS,不同在于 standard 創(chuàng)建的是 gp2 類型的 EBS,而 slow 創(chuàng)建的是 io1 類型的 EBS。不同類型的 EBS 支持的參數(shù)可參考 AWS 官方文檔。

StorageClass 支持 DeleteRetain 兩種 reclaimPolicy,默認(rèn)是 Delete。

與之前一樣,PVC 在申請 PV 時,只需要指定 StorageClass 和容量以及訪問模式,比如:

image

除了 AWS EBS,Kubernetes 支持其他多種動態(tài)供給 PV 的 Provisioner,完整列表請參考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

6.6.2.PV&&PVC在應(yīng)用在mysql的持久化存儲

下面演示如何為 MySQL 數(shù)據(jù)庫提供持久化存儲,步驟為:

  1. 創(chuàng)建 PV 和 PVC。

  2. 部署 MySQL。

  3. 向 MySQL 添加數(shù)據(jù)。

  4. 模擬節(jié)點宕機(jī)故障,Kubernetes 將 MySQL 自動遷移到其他節(jié)點。

  5. 驗證數(shù)據(jù)一致性。

首先創(chuàng)建 PV 和 PVC,配置如下:

mysql-pv.yml

image

mysql-pvc.yml

image

創(chuàng)建 mysql-pvmysql-pvc

image

接下來部署 MySQL,配置文件如下:

image

PVC mysql-pvc Bound 的 PV mysql-pv 將被 mount 到 MySQL 的數(shù)據(jù)目錄 var/lib/mysql。

image

MySQL 被部署到 k8s-node2,下面通過客戶端訪問 Service mysql

image

更新數(shù)據(jù)庫:

image

① 切換到數(shù)據(jù)庫 mysql。

② 創(chuàng)建數(shù)據(jù)庫表 my_id。

③ 插入一條數(shù)據(jù)。

④ 確認(rèn)數(shù)據(jù)已經(jīng)寫入。

關(guān)閉 k8s-node2,模擬節(jié)點宕機(jī)故障。

image

驗證數(shù)據(jù)的一致性:

由于node2節(jié)點已經(jīng)宕機(jī),node1節(jié)點接管了這個任務(wù)。

image

通過kubectl run 命令 進(jìn)入node1的這個pod里,查看數(shù)據(jù)是否依舊存在

image
image

MySQL 服務(wù)恢復(fù),數(shù)據(jù)也完好無損。

參考:

https://www.cnblogs.com/yaohong/p/11489164.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容