很多人對hostPath volume和local persistent volume的使用場景還存在很多困惑。下面對這兩種volume的使用場景、基本的工作機制進行了分析,介紹了使用時的注意事項,並簡單介紹local volume manager如何幫助administrator進行local persistent volume的生命周期管理的
1、hostPath volume存在的問題
過去我們經常會通過hostPath volume讓Pod能夠使用本地存儲,將Node文件系統中的文件或者目錄掛載到容器內,但是hostPath volume的使用是很難受的,並不適合在生產環境中使用。
我們先看看hostPath Type有哪些類型:
取值 | 行為 |
---|---|
空字符串(默認)用於向后兼容,這意味着在安裝 hostPath 卷之前不會執行任何檢查。 | |
DirectoryOrCreate | 在給定路徑上必須存在的目錄。 |
FileOrCreate | 如果在給定路徑上什么都不存在,那么將在那里根據需要創建空文件,權限設置為 0644,具有與 Kubelet 相同的組和所有權。 |
File | 在給定路徑上必須存在的文件。 |
Socket | 在給定路徑上必須存在的 UNIX 套接字。 |
CharDevice | 在給定路徑上必須存在的字符設備。 |
BlockDevice | 在給定路徑上必須存在的塊設備。 |
看起來支持這么多type還是挺好的,但為什么說不適合在生產環境中使用呢?
-
由於集群內每個節點的差異化,要使用
hostPath Volume
,我們需要通過NodeSelector
等方式進行精確調度,這種事情多了,你就會不耐煩了。 -
注意
DirectoryOrCreate
和FileOrCreate
兩種類型的hostPath
,當Node
上沒有對應的File/Directory
時,你需要保證kubelet
有在Node上Create File/Directory
的權限。 -
另外,如果
Node
上的文件或目錄是由root
創建的,掛載到容器內之后,你通常還要保證容器內進程有權限對該文件或者目錄進行寫入,比如你需要以root
用戶啟動進程並運行於privileged
容器,或者你需要事先修改好Node
上的文件權限配置。 -
Scheduler
並不會考慮hostPath volume
的大小,hostPath
也不能申明需要的storage
size,這樣調度時存儲的考慮,就需要人為檢查並保證。
2、local persistent volume工作機制
Local persistent volume
就是用來解決 hostPath volume
面臨的portability
,disk accounting, and scheduling
的缺陷。PV Controller
和Scheduler
會對local PV
做特殊的邏輯處理,以實現Pod
使用本地存儲時發生Pod re-schedule
的情況下能再次調度到ocal volume
所在的Node
。
local pv
在生產中使用,也是需要謹慎的,畢竟它本質上還是使用的是節點上的本地存儲,如果沒有相應的存儲副本機制,那意味着一旦節點或者磁盤異常,使用該volume
的Pod
也會異常,甚至出現數據丟失,除非你明確知道這個風險不會對你的應用造成很大影響或者允許數據丟失。
那么通常什么情況會使用Local PV
呢?
-
比如節點上的目錄數據是從遠程的網絡存儲上掛載或者預先讀取到本地的,為了能加速
Pod
讀取這些數據的速度,相當於起Cache
作用,這種情況下因為只讀,不存在懼怕數據丟失。這種AI
訓練中存在需要重復利用並且訓練數據巨大的時候可能會采取的方式。 -
如果本地節點上目錄/磁盤實際是具有副本/分片機制的分布式存儲(比如
gluster
,ceph
等)掛載過來的,這種情況也可以使用local pv
。
Local volume
允許掛載本地的disk
,partition
,directory
到容器內某個掛載點。在Kuberentes 1.11
仍然僅支持local pv
的static provision
,不支持dynamic provision
。
-
Kubernetes
使用PersistentVolume
的.spec.nodeAffinityfield
來描述local volume
與Node
的綁定關系。 -
使用
volumeBindingMode: WaitForFirstConsumer
的local-storage StorageClass
來實現PVC
的延遲綁定,使得PV Controller
並不會立刻PVC
做Bound
,而是等待某個需要使用該local pv
的Pod
完成調度后,才去做Bound
。
下面是定義local pv的Sample:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
# volumeMode field requires BlockVolume Alpha feature gate to be enabled.
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
對應的local-storage storageClass定義如下:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
3、使用local persistent volume注意事項
-
使用
local pv
時必須定義nodeAffinity
,Kubernetes Scheduler
需要使用PV
的nodeAffinity
描述信息來保證Pod
能夠調度到有對應local volume
的Node
上。 -
volumeMode
可以是FileSystem(Default)和 Block
,並且需要enable BlockVolume Alpha feature gate
。 -
創建
local PV
之前,你需要先保證有對應的storageClass
已經創建。並且該storageClass
的volumeBindingMode
必須是WaitForFirstConsumer
以標識延遲Volume Binding
。WaitForFirstConsumer
可以保證正常的Pod
調度要求(resource requirements, node selectors, Pod affinity, and Pod anti-affinity等),又能保證Pod
需要的Local PV 的 nodeAffinity
得到滿足,實際上,一共有以下兩種volumeBindingMode
:
// VolumeBindingImmediate indicates that PersistentVolumeClaims should be
// immediately provisioned and bound.
VolumeBindingImmediate VolumeBindingMode = "Immediate"
// VolumeBindingWaitForFirstConsumer indicates that PersistentVolumeClaims
// should not be provisioned and bound until the first Pod is created that
// references the PeristentVolumeClaim. The volume provisioning and
// binding will occur during Pod scheduing.
VolumeBindingWaitForFirstConsumer VolumeBindingMode = "WaitForFirstConsumer"
- 節點上
local volume
的初始化需要我們人為去完成(比如local disk
需要pre-partitioned
,formatted
,and mounted
. 共享存儲對應的Directories
也需要pre-created
),並且人工創建這個local PV
,當Pod
結束,我們還需要手動的清理local volume
,然后手動刪除該local PV
對象。因此,persistentVolumeReclaimPolicy
只能是Retain
。
4、local volume manager
上面這么多事情需要人為的去做預處理的工作,我們必須要有解決方案幫我們自動完成local volume
的 create
和cleanup
的工作。官方給出了一個簡單的 local volume manager
,注意它仍然只是一個 static provisioner
,目前主要幫我們做兩件事:
-
local volume manager
監控配置好的discovery directory
的新的掛載點,並為每個掛載點根據對應的storageClassName
,path
,nodeAffinity
,and capacity
創建PersistentVolume object
。 -
當
Pod
結束並刪除了使用local volume
的PVC
,local volume manager
將自動清理該local mount
上的所有文件, 然后刪除對應的PersistentVolume object
。
因此,除了需要人為的完成local volume
的mount
操作,local PV
的生命周期管理就全部交給local volume manager
了。
5、總結
本文對hostPath volume
不能在生產環境中很好使用的原因進行了闡述,然后對local persistent volume
的使用場景、基本的工作機制進行了分析,介紹了使用時的注意事項,最后簡單介紹了local volume manager
如何幫助administrator
進行local persistent volume
的生命周期管理的。