Kubernetes中的本地存儲意味着在每一個節點服務器上本地可用的存儲設備或文件系統。本文介紹Kubernetes中現有的本地存儲解決方案,包括官方原生支持的存儲方式以及社區的一些常見方案。node
目前官方支持如下3種本地存儲方式:git
當 Pod 指定到某個節點上時,首先建立的是一個emptyDir
卷,而且只要 Pod 在該節點上運行,卷就一直存在。 就像它的名稱表示的那樣,卷最初是空的。 儘管 Pod 中的容器掛載emptyDir
卷的路徑可能相同也可能不一樣,可是這些容器均可以讀寫emptyDir
卷中相同的文件。 當 Pod 由於某些緣由被從節點上刪除時,emptyDir
卷中的數據也會永久刪除。github
注意:容器崩潰並不會致使 Pod 被從節點上移除,所以容器崩潰時 `emptyDir` 卷中的數據是安全的。
emptyDir
的一些用途:docker
默認狀況下, emptyDir
卷存儲在支持該節點所使用的介質上;這里的介質能夠是磁盤或 SSD 或網絡存儲,這取決於您的環境。 可是,您能夠將 emptyDir.medium
字段設置爲 "Memory"
,以告訴 Kubernetes 爲您安裝 tmpfs(基於 RAM 的文件系統)。 雖然 tmpfs 速度很是快,可是要注意它與磁盤不同。 tmpfs 在節點重啓時會被清除,而且您所寫入的全部文件都會計入容器的內存消耗,受容器內存限制約束。數據庫
emptyDir的位置應該在運行pod的給定節點上的/var/lib/kubelet/pods/{podid}/volumes/kubernetes.io~empty-dir/
目錄下。ubuntu
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - image: my-app-image name: my-app volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
Pod中的全部容器共享使用emptyDir卷。所以,咱們使用emptyDir的一個場景是,Pod中init容器負責到配置中心或是祕鑰管理中心拉取一些配置,而後寫入到emptyDir中,這樣業務容器就能夠讀取到配置。
hostPath
卷能將主機節點文件系統上的文件或目錄掛載到您的 Pod 中。 雖然這不是大多數 Pod 須要的,可是它爲一些應用程序提供了強大的逃逸機會。後端
例如,hostPath
的一些用法有:api
hostPath
掛載 /var/lib/docker
路徑。hostPath
方式掛載 /sys
。hostPath
在運行 Pod 以前是否應該存在,是否應該建立以及應該以什麼方式存在。除了必需的 path
屬性以外,用戶能夠選擇性地爲 hostPath
卷指定 type
。緩存
例如:安全
apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - image: my-app-image name: my-app volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: path: /data #directory on host type: Directory #optional
type: Directory
定義目錄必須在主機上已經存在,所以在使用主機路徑以前,您必須首先在該目錄中手動建立它。
類型的其餘值是DirectoryOrCreate
,File
,FileOrCreate
。若是* OrCreate在主機上尚不存在,將動態建立。
使用此卷類型的缺點:
Local PV(本地持久化存儲),指的就是利用機器上的磁盤來存放業務須要持久化的數據,和遠端存儲相似,此時數據依然獨立於 Pod 的生命週期,即便業務 Pod 被刪除,數據也不會丟失。
同時,和遠端存儲相比,本地存儲能夠避免網絡 IO 開銷,擁有更高的讀寫性能,因此分佈式文件系統和分佈式數據庫這類對 IO 要求很高的應用很是適合本地存儲。
可是,在使用本地永久卷時,有一些重要的限制和注意事項須要考慮:
Local PV和hostPath區別
爲了更好地瞭解本地持久卷的好處,將其與HostPath捲進行比較頗有用。 HostPath卷將主機節點文件系統中的文件或目錄裝載到Pod中。一樣,本地永久卷將本地磁盤或分區安裝到Pod中。
最大的區別是Kubernetes調度程序瞭解本地持久卷屬於哪一個節點。對於HostPath卷,調度程序可能會將引用HostPath卷的pod移至其餘節點,從而致使數據丟失。可是對於本地持久卷,Kubernetes調度程序可確保始終將使用本地持久卷的容器調度到同一節點。
儘管能夠經過持久卷聲明(PVC)引用HostPath卷,也能夠在pod定義中直接內聯HostPath卷,可是隻能經過PVC引用本地持久卷。因爲Persistent Volume對象是由管理員管理的,所以,Pod不能訪問主機上的任何路徑,所以能夠提供額外的安全優點。
其餘好處包括支持在安裝期間格式化塊設備以及使用fsGroup進行卷全部權。
如何使用Local PV?
工做負載可使用與遠程存儲後端相同的PersistentVolumeClaim接口請求本地持久卷。這使得跨集羣,雲和本地環境輕鬆交換存儲後端。
首先,應該建立一個StorageClass來設置volumeBindingMode:WaitForFirstConsumer
來啓用卷拓撲感知調度。該模式指示Kubernetes等待綁定PVC,直到Pod開始使用它。
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer
而後,能夠配置並運行外部靜態預配器,覺得節點上的全部本地磁盤建立PV。
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE local-pv-27c0f084 368Gi RWO Delete Available local-storage 8s local-pv-3796b049 368Gi RWO Delete Available local-storage 7s local-pv-3ddecaea 368Gi RWO Delete Available local-storage 7s
以後,經過建立帶有volumeClaimTemplates的PVC和Pod或StatefulSet,工做負載能夠開始使用PV。
apiVersion: apps/v1 kind: StatefulSet metadata: name: local-test spec: serviceName: "local-service" replicas: 3 selector: matchLabels: app: local-test template: metadata: labels: app: local-test spec: containers: - name: test-container image: k8s.gcr.io/busybox command: - "/bin/sh" args: - "-c" - "sleep 100000" volumeMounts: - name: local-vol mountPath: /usr/test-pod volumeClaimTemplates: - metadata: name: local-vol spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "local-storage" resources: requests: storage: 368Gi
一旦StatefulSet啓動並運行,PVC都將綁定:
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE local-vol-local-test-0 Bound local-pv-27c0f084 368Gi RWO local-storage 3m45s local-vol-local-test-1 Bound local-pv-3ddecaea 368Gi RWO local-storage 3m40s local-vol-local-test-2 Bound local-pv-3796b049 368Gi RWO local-storage 3m36s
當再也不須要磁盤時,能夠刪除PVC。外部靜態預配器將清理磁盤,並使PV再次可用。
社區的一些方案:
TopoLVM
TopoLVM,一個用於本地存儲的新CSI插件,可以使用LVM動態配置卷。它實現了動態卷配置,原始塊卷,文件系統指標,並將實如今線卷大小調整和臨時卷。
架構
TopoLVM 組件包括:
topolvm-controller
: CSI controllertopolvm-scheduler
: 用於TopoLVM 的scheduler extender topolvm-node
: CSI node 服務lvmd
: 管理LVM卷的gRPC 服務
特性
因爲不是k8s原生方案,因此在使用前,咱們須要先安裝。關於安裝,你們參考官方文檔便可。
示例:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: topolvm-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: topolvm-provisioner --- apiVersion: v1 kind: Pod metadata: name: my-pod labels: app.kubernetes.io/name: my-pod spec: containers: - name: ubuntu image: quay.io/cybozu/ubuntu:18.04 command: ["/usr/local/bin/pause"] volumeMounts: - mountPath: /test1 name: my-volume volumes: - name: my-volume persistentVolumeClaim: claimName: topolvm-pvc