為什麼需要 Volume#

對於用過 Docker 的人來說,Volume 並不陌生。它的功能是把容器內的某個目錄與容器外的目錄連結起來,使兩端的內容互通。如此一來:

  • 多個容器之間可以共享同一份資料。
  • 當容器被刪除時,外部目錄與其中的檔案不會跟著消失。
  • 容器重啟後可以快速還原資料與狀態。

這個「刪除容器但保留資料」的特性,是容器化應用面對狀態與資料保存時最基本的需求。

Kubernetes Volume 的定位#

相較於 Docker,Kubernetes 的 Volume(卷)提供更豐富的類型與更嚴謹的管理概念,並且導入了「生命週期」的觀念:

  • 與 Pod 共生共滅的臨時卷(Ephemeral Volumes)。
  • 生命週期長於 Pod 的持久卷(Persistent Volumes),使資料在 Pod 重啟期間不會遺失。

Volume 的核心是「一個目錄」,Pod 中的容器可以存取這個目錄裡的資料。所選擇的 Volume 類型會決定:

  • 該目錄如何被建立。
  • 使用何種介質保存資料。
  • 目錄裡能放哪些內容。

使用 Volume 時,需要在 Pod spec 的兩個地方設定:

  • .spec.volumes:宣告要提供給 Pod 的 Volume。
  • .spec.containers[*].volumeMounts:宣告該 Volume 在容器中的掛載位置。

常見的 Volume 類型#

Kubernetes 官方提供的 Volume 類型相當細緻,且版本迭代快速(常常某些類型在幾個版本後就被棄用)。以下整理幾種最常見、實務上會遇到的類型。

EmptyDir#

當建立一個 Pod 時,Kubernetes 會在這個 Pod 中產生一個空白資料夾 EmptyDir,Pod 內的所有容器都可以讀寫這個資料夾。常見使用情境:

  • 資料快取(cache)。
  • 臨時儲存。

另外,建構在 EmptyDir 之上的 gitRepo Volume,可以在 Pod 啟動時從指定 Git Repo 拉取資料到底層的 EmptyDir,讓它具備某種程度的「持久性」。

HostPath#

HostPath 可以將節點(Node)上的檔案或目錄掛載到 Pod 中。這種需求不算常見,但對某些情境很有幫助,例如在啟動指定 Pod 之前先檢查節點上的某個檔案是否存在。

官方目前明確指出 HostPath 存在許多安全風險,最佳做法是「盡可能避免使用」。若必須使用,範圍應限制在所需的檔案或目錄,並以唯讀方式掛載。

Network FileSystem(NFS)#

NFS 能將網路上的檔案系統掛載到 Pod 中。不像 EmptyDir 會隨著 Pod 刪除而消失,NFS 可以做為預先填充的資料來源,並讓資料在 Pod 之間共享。實務上常搭配雲端儲存服務使用。

ConfigMap#

ConfigMap 顧名思義與「設定」相關。它通常用來存放:

  • 環境變數檔。
  • 資料庫初始化腳本。
  • 其他偏向部署層面的設定資料。

Secret#

相較於 ConfigMap 偏向部署設定,Secret 通常用來存放敏感資料,例如:

  • 使用者帳號密碼。
  • 憑證、API Key。

Secret 具備 ConfigMap 的多數功能,並且額外有一個特性:內部資料會以 base64 編碼。

Persistent Volume(PV)與 Persistent Volume Claim(PVC)#

  • Persistent Volume(PV):叢集中的一塊儲存資源,由管理者預先設定,屬於整個叢集層級,因此擁有獨立於使用它的 Pod 的生命週期。
  • Persistent Volume Claim(PVC):使用者對儲存資源的「請求」。如同 Pod 對 Node 請求 CPU 或記憶體一樣,PVC 也會請求並消耗 PV 的容量。

小結#

在 Kubernetes 中,「資料如何儲存與設定」是一個重要而持續的課題。從 Volume 切入是相對好理解的起點,後續的章節會逐一動手操作 EmptyDir、ConfigMap、Secret 與 PV/PVC,逐步加深對 Volume 的理解與使用情境。

原文出處#

  • GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day16
  • iThome:https://ithelp.ithome.com.tw/articles/10291557