6.1.介紹卷
6.1.1.卷的類型
emptyDir-用于存儲臨時數(shù)據(jù)的簡單空目錄
hostPath-用于將目錄從工作節(jié)點(diǎn)的文件系統(tǒng)掛載到pod
nfs-掛載到pod中的NFS共享卷垒玲。
還有其他的如gitRepo陆馁、gcepersistenDisk
6.2.通過卷在容器間共享數(shù)據(jù)
6.2.1.使用emptyDir卷
卷的生命周期與pod的生命周期項(xiàng)關(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的單獨(dú)emptyDir卷,掛載在上面的兩個容器中
emptyDir: {}
6.3.訪問工作節(jié)點(diǎn)文件系統(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é)點(diǎn)上。
所以當(dāng)你使用hostPath時請務(wù)必考慮清楚储狭,當(dāng)重新起一個pod時候互婿,必須要保證pod的節(jié)點(diǎn)與之前相同捣郊。
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é)點(diǎn)都有相同的數(shù)據(jù)可用,這就需要做到持久化存儲慈参。
因此必須要將數(shù)據(jù)存儲在某種類型的網(wǎng)絡(luò)存儲(NAS)中呛牲。
各種支持的方式不盡相同,例如 GlusterFS 需要創(chuàng)建 Endpoint驮配,Ceph/NFS 之流就沒這么麻煩了娘扩。
6.4.1.使用NFS存儲
以NFS為例,yml代碼如下:
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é)點(diǎn)。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節(jié)點(diǎn)忍燥。
ReadWriteMany – PV 能以 read-write 模式 mount 到多個節(jié)點(diǎn)拧晕。
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
STATUS
為 Available
貌虾,表示 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 pvc
和 kubectl 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即可
與使用普通 Volume 的格式類似码党,在 volumes
中通過 persistentVolumeClaim
指定使用 mypvc1
申請的 Volume。
通過命令創(chuàng)建mypod1
:
可見斥黑,在 Pod 中創(chuàng)建的文件 /mydata/hello
確實(shí)已經(jīng)保存到了 NFS 服務(wù)器目錄 /nfsdata
中揖盘。
如果不再需要使用 PV,可用刪除 PVC 回收 PV锌奴。
6.5.5.回收持久卷
當(dāng) PV 不再需要時兽狭,可通過刪除 PVC 回收。
未刪除pvc之前 pv的狀態(tài)是Bound
刪除pvc之后pv的狀態(tài)變?yōu)锳vailable,椭符,此時解除綁定后則可以被新的 PVC 申請荔燎。
/nfsdata文件中的文件被刪除了
因?yàn)?PV 的回收策略設(shè)置為 Recycle
,所以數(shù)據(jù)會被清除销钝,但這可能不是我們想要的結(jié)果有咨。如果我們希望保留數(shù)據(jù),可以將策略設(shè)置為 Retain
蒸健。
通過 kubectl apply
更新 PV:
回收策略已經(jīng)變?yōu)?Retain
座享,通過下面步驟驗(yàn)證其效果:
① 重新創(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ù)并不會被刪除幼衰。
新建的 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 實(shí)現(xiàn)的,StorageClass 定義了如何創(chuàng)建 PV藕届,下面是兩個例子挪蹭。
StorageClass standard
:
StorageClass slow
:
這兩個 StorageClass 都會動態(tài)創(chuàng)建 AWS EBS,不同在于 standard
創(chuàng)建的是 gp2
類型的 EBS休偶,而 slow
創(chuàng)建的是 io1
類型的 EBS梁厉。不同類型的 EBS 支持的參數(shù)可參考 AWS 官方文檔。
StorageClass 支持 Delete
和 Retain
兩種 reclaimPolicy
踏兜,默認(rèn)是 Delete
词顾。
與之前一樣,PVC 在申請 PV 時碱妆,只需要指定 StorageClass 和容量以及訪問模式肉盹,比如:
除了 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ù)庫提供持久化存儲上忍,步驟為:
創(chuàng)建 PV 和 PVC。
部署 MySQL纳本。
向 MySQL 添加數(shù)據(jù)窍蓝。
模擬節(jié)點(diǎn)宕機(jī)故障,Kubernetes 將 MySQL 自動遷移到其他節(jié)點(diǎn)饮醇。
驗(yàn)證數(shù)據(jù)一致性它抱。
首先創(chuàng)建 PV 和 PVC秕豫,配置如下:
mysql-pv.yml
mysql-pvc.yml
創(chuàng)建 mysql-pv
和 mysql-pvc
:
接下來部署 MySQL朴艰,配置文件如下:
PVC mysql-pvc
Bound 的 PV mysql-pv
將被 mount 到 MySQL 的數(shù)據(jù)目錄 var/lib/mysql
。
MySQL 被部署到 k8s-node2
混移,下面通過客戶端訪問 Service mysql
:
更新數(shù)據(jù)庫:
① 切換到數(shù)據(jù)庫 mysql祠墅。
② 創(chuàng)建數(shù)據(jù)庫表 my_id。
③ 插入一條數(shù)據(jù)歌径。
④ 確認(rèn)數(shù)據(jù)已經(jīng)寫入毁嗦。
關(guān)閉 k8s-node2
,模擬節(jié)點(diǎn)宕機(jī)故障回铛。
驗(yàn)證數(shù)據(jù)的一致性:
由于node2節(jié)點(diǎn)已經(jīng)宕機(jī)狗准,node1節(jié)點(diǎn)接管了這個任務(wù)。
通過kubectl run 命令 進(jìn)入node1的這個pod里茵肃,查看數(shù)據(jù)是否依舊存在
MySQL 服務(wù)恢復(fù)腔长,數(shù)據(jù)也完好無損。