Kubernetes Volume實(shí)踐

我們知道容器和 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)景:

  1. 用于同一主機(jī)上 pod 之間的數(shù)據(jù)共享;
  2. 某些固定在節(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等。

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

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

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