說起存儲(chǔ)卷和docker的存儲(chǔ)卷有幾分相似的地方,數(shù)據(jù)不會(huì)跟隨Pod的停止或刪除而消失怀伦,從而實(shí)現(xiàn)數(shù)據(jù)的持久性柳琢,但是由于K8s的獨(dú)特坏瘩,K8s面對(duì)的是集群盅抚,如果要實(shí)現(xiàn)數(shù)據(jù)的持久性,Pod會(huì)分布到各個(gè)節(jié)點(diǎn)之上倔矾,所以引入了外部存儲(chǔ)卷妄均。
① · 常見的存儲(chǔ)卷類型有:
- emptyDir :當(dāng)Pod生命周期結(jié)束后,存儲(chǔ)卷會(huì)被一并刪除哪自,這種通常會(huì)存放一些臨時(shí)數(shù)據(jù)丛晦。
- hostPath:宿主機(jī)目錄映射
- 本地的SAN(iSCSI,FC)、NAS(nfs,cifs,http)存儲(chǔ)
- 分布式存儲(chǔ)(glusterfs提陶,rbd,cephfs)
- 云存儲(chǔ)(EBS匹层,Azure Disk)
種類繁多的存儲(chǔ)無疑會(huì)提高K8s的使用門檻隙笆,這意味著你不僅要懂K8s還要懂存儲(chǔ)的結(jié)構(gòu)、用法升筏、參數(shù)撑柔、使用場景等等等...
所以K8s又引入了一個(gè)概念叫做PVC 全稱 persistentVolumeClaim -->PVC(存儲(chǔ)卷創(chuàng)建申請(qǐng))
當(dāng)你需要一個(gè)存儲(chǔ)空間的時(shí)候,只要進(jìn)行對(duì)應(yīng)的申請(qǐng)即可您访,靈魂圖: ↓
在Pod 上定義一個(gè)PVC铅忿,但該P(yáng)VC只是一個(gè)申請(qǐng),他需要和PV進(jìn)行關(guān)聯(lián)灵汪,PV是屬于存儲(chǔ)設(shè)備上的一部分空間檀训,so申請(qǐng)之前我們應(yīng)該創(chuàng)建好對(duì)應(yīng)大小的pv等待使用柑潦,那么就造成了每次用戶需要存儲(chǔ)卷的時(shí)候都要想K8s的管理員申請(qǐng),等管理員建立好他才能進(jìn)行PVC的申請(qǐng)峻凫,這聽起來比較麻煩渗鬼,于是又有了另一個(gè)方案。
不要pv層荧琼,把所有存儲(chǔ)資源抽象成一個(gè)存儲(chǔ)類譬胎,當(dāng)用戶申請(qǐng)PVC到達(dá)存儲(chǔ)類的時(shí)候,會(huì)根據(jù)申請(qǐng)大小命锄,自動(dòng)創(chuàng)建出相應(yīng)的存儲(chǔ)空間堰乔,實(shí)現(xiàn)動(dòng)態(tài)供給。
emptydir類型示例:
emptydir具體操作步驟: ↓
① · 在Pod層定義volume,并指明關(guān)聯(lián)到哪個(gè)存儲(chǔ)設(shè)備
② · 在容器中層使用 volume mount 進(jìn)行掛載
emptydir:
是一個(gè)臨時(shí)的空目錄脐恩,在pod之上的每個(gè)容器都可以掛載到相同或不同的目錄上镐侯,并且共享里面的內(nèi)容,當(dāng)Pod因?yàn)槿魏卧虮粍h除時(shí)被盈,存儲(chǔ)卷會(huì)被一并刪除析孽,無法保留數(shù)據(jù)。但是容器崩潰的時(shí)候只怎,不會(huì)影響數(shù)據(jù)袜瞬,因?yàn)橐粋€(gè)容器崩潰不會(huì)導(dǎo)致Pod被刪除。
默認(rèn)情況下emptydir是一個(gè)普通磁盤提供的存儲(chǔ)空間身堡,但是也可以定義為memory邓尤,意為使用node的內(nèi)存來提供存儲(chǔ)功能,因?yàn)閮?nèi)存性能強(qiáng)大贴谎,但是要注意當(dāng)node重啟的時(shí)候汞扎,內(nèi)存內(nèi)的數(shù)據(jù)會(huì)丟失,emptydir的數(shù)據(jù)也會(huì)隨之消失擅这。
清單示例:
apiVersion: v1
kind: Pod
metadata:
name: Pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /data/
command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
volumes:
- name: html
emptydir: {}
上述清單定義了一個(gè)類型為emptydir的存儲(chǔ)卷澈魄,并且創(chuàng)建了兩個(gè)容器共同掛載,由后端的busybox不停的向目錄中注入內(nèi)容仲翎,通過從前端訪問顯示內(nèi)容痹扇,實(shí)現(xiàn)兩個(gè)容器之間的存儲(chǔ)共享。
[root@k8s-master volumes]# kubectl apply -f pod-vol-demo.yaml
pod/pod-vol-demo created
[root@k8s-master volumes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-vol-demo 2/2 Running 0 27s
[root@k8s-master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
......
pod-vol-demo 2/2 Running 0 16s 10.244.2.34 k8s-node02
......
[root@k8s-master volumes]# curl 10.244.2.34 #訪問驗(yàn)證
Tue Oct 9 03:56:53 UTC 2018
Tue Oct 9 03:56:55 UTC 2018
Tue Oct 9 03:56:57 UTC 2018
Tue Oct 9 03:56:59 UTC 2018
Tue Oct 9 03:57:01 UTC 2018
Tue Oct 9 03:57:03 UTC 2018
Tue Oct 9 03:57:05 UTC 2018
Tue Oct 9 03:57:07 UTC 2018
Tue Oct 9 03:57:09 UTC 2018
Tue Oct 9 03:57:11 UTC 2018
Tue Oct 9 03:57:13 UTC 2018
Tue Oct 9 03:57:15 UTC 2018
另外一種比較特殊類型的存儲(chǔ)類型叫做gitrepo溯香,就是利用github倉庫作為外部持久存儲(chǔ)鲫构,但是他的基礎(chǔ)仍然是emptydir來實(shí)現(xiàn)的,并且要確保node之上有Git工具玫坛,因?yàn)檫@是通過node 來驅(qū)動(dòng)的git结笨,具體實(shí)現(xiàn)方式就是通過sidecar容器將gitrepo clone到容器上,然后不停的往GitHub之上push數(shù)據(jù)來實(shí)現(xiàn)。
hostPath類型示例:
hostPath是將宿主機(jī)上的某個(gè)目錄與Pod中的容器建立關(guān)聯(lián)關(guān)系炕吸,數(shù)據(jù)不屬于container伐憾,所以當(dāng)Pod生命周期結(jié)束的時(shí)候,數(shù)據(jù)不會(huì)丟失算途。但是當(dāng)node節(jié)點(diǎn)發(fā)生故障的時(shí)候塞耕,數(shù)據(jù)也會(huì)丟失。
apiVersion: v1
kind: Pod
metadata:
name: pod-hostPath
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
volumeMonts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
hostPath:
path: /data/pod/volume1
type: DirectoryOrCreate
# type:
#DirectoryOrCreate 宿主機(jī)上不存在創(chuàng)建此目錄
#Directory 必須存在掛載目錄
#FileOrCreate 宿主機(jī)上不存在掛載文件就創(chuàng)建
#File 必須存在文件
在node節(jié)點(diǎn)上創(chuàng)建掛載目錄
[root@k8s-node01 ~]# mkdir -p /data/pod/volume1
[root@k8s-node01 ~]# vim /data/pod/volume1/index.html
node01.magedu.com
[root@k8s-node02 ~]# mkdir -p /data/pod/volume1
[root@k8s-node02 ~]# vim /data/pod/volume1/index.html
node02.magedu.com
[root@k8s-master volumes]# kubectl apply -f pod-hostpath-vol.yaml
pod/pod-vol-hostpath created
(4)訪問測試
[root@k8s-master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
......
pod-vol-hostpath 1/1 Running 0 37s 10.244.2.35 k8s-node02
......
[root@k8s-master volumes]# curl 10.244.2.35
node02.magedu.com
[root@k8s-master volumes]# kubectl delete -f pod-hostpath-vol.yaml #刪除pod嘴瓤,再重建扫外,驗(yàn)證是否依舊可以訪問原來的內(nèi)容
[root@k8s-master volumes]# kubectl apply -f pod-hostpath-vol.yaml
pod/pod-vol-hostpath created
[root@k8s-master volumes]# curl 10.244.2.37
node02.magedu.com
NFS類型示例:
NFS掛載是在其中一個(gè)node之上將共享的目錄發(fā)布出來,并且在各個(gè)node之上都安裝好nfs-utils工具廓脆,只要在創(chuàng)建Pod的時(shí)候指定要掛載的文件系統(tǒng)為nfs筛谚,和掛載點(diǎn)、權(quán)限即可自動(dòng)完成掛載操作停忿,并且能實(shí)現(xiàn)數(shù)據(jù)同步驾讲。
在創(chuàng)建Pod之前要做好nfs的配置
在stor01節(jié)點(diǎn)上安裝nfs,并配置nfs服務(wù)
[root@stor01 ~]# yum install -y nfs-utils ## 192.168.56.14
[root@stor01 ~]# mkdir /data/volumes -pv
[root@stor01 ~]# vim /etc/exports
/data/volumes 192.168.56.0/24(rw,no_root_squash)
[root@stor01 ~]# systemctl start nfs
[root@stor01 ~]# showmount -e
Export list for stor01:
/data/volumes 192.168.56.0/24
在node2上測試連接席赂,成功后即可創(chuàng)建Pod
[root@k8s-node02 ~]# yum install -y nfs-utils
[root@k8s-node02 ~]# mount -t nfs stor01:/data/volumes /mnt
[root@k8s-node02 ~]# mount
......
stor01:/data/volumes on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.56.13,local_lock=none,addr=192.168.56.14)
[root@k8s-node02 ~]# umount /mnt/
清單示例:
apiVersion: v1
kind: Pod
metadata:
name: Pod-nfs
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
path: /data/volumes # 共享出來的目錄
server: stor01 #要提前做好解析