我們知道容器和 pod 可能會(huì)被頻繁地銷(xiāo)毀和創(chuàng)建,在銷(xiāo)毀的時(shí)候,容器內(nèi)部的數(shù)據(jù)也會(huì)被清除掉。這對(duì)于需要讀寫(xiě)容器內(nèi)部數(shù)據(jù)的應(yīng)用來(lái)說(shuō)就是一個(gè)很大的問(wèn)題。其次,有一些場(chǎng)景,可能一個(gè) pod 里面的多個(gè)容器需要共享數(shù)據(jù)。怎么來(lái)解決呢?
volume 的生命周期與 pod 相同,當(dāng) volume 被 mount 到一個(gè) pod 上時(shí),pod 中的所有容器都可以訪問(wèn)這個(gè) volume,容器的創(chuàng)建和銷(xiāo)毀并不會(huì)影響 volume。但是,當(dāng) pod 被銷(xiāo)毀時(shí),volume 也就不復(fù)存在了。 那數(shù)據(jù)是不是也丟了嗎?
其實(shí) volume 只是一個(gè)目錄,至于這個(gè) volume 是如何創(chuàng)建的,它的內(nèi)容是什么等等,實(shí)際上是取決于所使用的 volume 類(lèi)型。常見(jiàn)的類(lèi)型包括 emptyDir、hostPath、nfs、Ceph 等,完整列表可以參考官網(wǎng)說(shuō)明:
https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes
接下來(lái)我們來(lái)看看最簡(jiǎn)單的 emptyDir 類(lèi)型。
emptyDir
emptyDir volume 類(lèi)型,實(shí)際上是主機(jī)上的一個(gè)臨時(shí)空目錄。臨時(shí)就是說(shuō)當(dāng) pod 被刪除時(shí),這個(gè)空目錄也會(huì)跟著被刪除,里面的數(shù)據(jù)也就不存在了。但是對(duì)于容器來(lái)說(shuō),只要 pod 還在,即使容器被銷(xiāo)毀,數(shù)據(jù)還是存在的。
常見(jiàn)的使用場(chǎng)景:
- 用于一個(gè) pod 內(nèi)多個(gè)容器共享臨時(shí)數(shù)據(jù)(如日志收集)
下面通過(guò)例子來(lái)使用 emptyDir 模擬日志收集。
創(chuàng)建 app.yaml 文件:
apiVersion: v1
kind: Pod
metadata:
name: emptydir
spec:
containers:
- image: busybox
name: app
volumeMounts:
- mountPath: /logs
name: shared-dir
args:
- /bin/sh
- -c
- echo `date '+%H:%M:%S'` >> /logs/app.log; sleep 60000
- image: busybox
name: log-collector
volumeMounts:
- mountPath: /app_logs
name: shared-dir
args:
- /bin/sh
- -c
- cat /app_logs/app.log; sleep 60000
volumes:
- name: shared-dir
emptyDir: {}
創(chuàng)建 pod:
$ kubectl create -f app.yaml
pod "emptydir" created
pod 中有兩個(gè)容器,一個(gè)是 app(對(duì)應(yīng)實(shí)際場(chǎng)景中的應(yīng)用),另一個(gè)是 log-collector(對(duì)應(yīng)實(shí)際場(chǎng)景中的日志收集)。app負(fù)責(zé)把日志寫(xiě)到日志文件中,而 log-collector 則從日志文件中讀取日志。
看看模擬的效果。
查看日志文件內(nèi)容:
$ kubectl exec emptydir -c log-collector cat /app_logs/app.log
12:36:51
說(shuō)明通過(guò) emptyDir volume 可以實(shí)現(xiàn) pod 內(nèi)容器之間的數(shù)據(jù)共享。
接下來(lái)把 pod 刪除再重新創(chuàng)建:
$ kubectl delete -f app.yaml
pod "emptydir" deleted
$ kubectl create -f app.yaml
pod "emptydir" created
再次查看日志文件內(nèi)容:
$ kubectl exec emptydir -c log-collector cat /app_logs/app.log
12:38:45
可見(jiàn)當(dāng) pod 被刪除之后,之前的數(shù)據(jù)已經(jīng)被清除了。
所以記住一點(diǎn),emptyDir volume 實(shí)際就是一個(gè)臨時(shí)共享目錄。
臨時(shí):指的是生命周期和pod一樣,數(shù)據(jù)隨pod的銷(xiāo)毀而銷(xiāo)毀。
共享:指的是同一個(gè) pod 內(nèi),多個(gè)容器可以使用同一個(gè)目錄進(jìn)行數(shù)據(jù)的共享。
hostPath
hostPath 類(lèi)型的 volume,是將主機(jī)上的目錄 mount 給 pod 的容器。與 emptyDir 不同的是,即使 pod 被銷(xiāo)毀了,hostPath 對(duì)應(yīng)的目錄數(shù)據(jù)也還會(huì)被保留。
常見(jiàn)的有兩種場(chǎng)景:
- 用于同一主機(jī)上 pod 之間的數(shù)據(jù)共享;
- 某些固定在節(jié)點(diǎn)上,且需要數(shù)據(jù)持久化的應(yīng)用(如使用 DaemonSet 的應(yīng)用)。
大部分應(yīng)用都不會(huì)直接使用 hostPath volume,因?yàn)檫@會(huì)增加了 pod 與節(jié)點(diǎn)的耦合,應(yīng)用難以伸縮和調(diào)度,所以很少會(huì)使用第一種場(chǎng)景。
簡(jiǎn)單介紹完 emptyDir 和 hostPath,其他類(lèi)型的 volume 可以參考
官網(wǎng)說(shuō)明。大家根據(jù)實(shí)際的需要去選擇,比如在公有云上,可以使用公有云提供的云盤(pán)?;蛘呤褂梅植际酱鎯?chǔ),如Ceph、GlusterFS等。