Kubernetes本地持久化方案

Kubernetes中的本地存儲意味着在每一個節點服務器上本地可用的存儲設備或文件系統。本文介紹Kubernetes中現有的本地存儲解決方案,包括官方原生支持的存儲方式以及社區的一些常見方案。node

目前官方支持如下3種本地存儲方式:git

  • emptyDir
  • hostPath
  • Local Persistent Volume

emptyDir

當 Pod 指定到某個節點上時,首先建立的是一個emptyDir卷,而且只要 Pod 在該節點上運行,卷就一直存在。 就像它的名稱表示的那樣,卷最初是空的。 儘管 Pod 中的容器掛載emptyDir卷的路徑可能相同也可能不一樣,可是這些容器均可以讀寫emptyDir卷中相同的文件。 當 Pod 由於某些緣由被從節點上刪除時,emptyDir卷中的數據也會永久刪除。github

注意:容器崩潰並不會致使 Pod 被從節點上移除,所以容器崩潰時 `emptyDir` 卷中的數據是安全的。

emptyDir 的一些用途:docker

  • 緩存空間,例如基於磁盤的歸併排序。
  • 爲耗時較長的計算任務提供檢查點,以便任務能方便地從崩潰前狀態恢復執行。
  • 在 Web 服務器容器服務數據時,保存內容管理器容器獲取的文件。

默認狀況下, emptyDir 卷存儲在支持該節點所使用的介質上;這里的介質能夠是磁盤或 SSD 或網絡存儲,這取決於您的環境。 可是,您能夠將 emptyDir.medium 字段設置爲 "Memory",以告訴 Kubernetes 爲您安裝 tmpfs(基於 RAM 的文件系統)。 雖然 tmpfs 速度很是快,可是要注意它與磁盤不同。 tmpfs 在節點重啓時會被清除,而且您所寫入的全部文件都會計入容器的內存消耗,受容器內存限制約束。數據庫

emptyDir的位置應該在運行pod的給定節點上的/var/lib/kubelet/pods/{podid}/volumes/kubernetes.io~empty-dir/ 目錄下。ubuntu

Pod 示例

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

hostPath卷能將主機節點文件系統上的文件或目錄掛載到您的 Pod 中。 雖然這不是大多數 Pod 須要的,可是它爲一些應用程序提供了強大的逃逸機會。後端

例如,hostPath 的一些用法有:api

  • 運行一個須要訪問 Docker 引擎內部機制的容器;請使用 hostPath 掛載 /var/lib/docker 路徑。
  • 在容器中運行 cAdvisor 時,以 hostPath 方式掛載 /sys
  • 容許 Pod 指定給定的 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定義目錄必須在主機上已經存在,所以在使用主機路徑以前,您必須首先在該目錄中手動建立它。

類型的其餘值是DirectoryOrCreateFileFileOrCreate。若是* OrCreate在主機上尚不存在,將動態建立。

使用此卷類型的缺點:

  • 因爲不一樣節點的hostPath文件/目錄內容不一樣,所以同一模板建立的Pod在不一樣節點上的行爲可能有所不一樣
  • 用hostPath在主機上建立的文件或目錄只能由root寫入。這意味着您要麼須要以root用戶身份運行容器進程,要麼將主機上的文件權限修改成非root用戶可寫,這可能會致使安全問題
  • 不該該將hostPath卷類型用於StatefulSets

Local Persistent Volume

Local PV(本地持久化存儲),指的就是利用機器上的磁盤來存放業務須要持久化的數據,和遠端存儲相似,此時數據依然獨立於 Pod 的生命週期,即便業務 Pod 被刪除,數據也不會丟失。

同時,和遠端存儲相比,本地存儲能夠避免網絡 IO 開銷,擁有更高的讀寫性能,因此分佈式文件系統和分佈式數據庫這類對 IO 要求很高的應用很是適合本地存儲。

可是,在使用本地永久卷時,有一些重要的限制和注意事項須要考慮:

  • 使用本地存儲將您的應用程序綁定到特定節點,從而使您的應用程序難以調度。使用本地存儲的應用程序應指定較高的優先級,以便在須要時能夠搶佔不須要本地存儲的較低優先級的Pod。
  • 若是該節點或本地卷遇到故障並變得不可訪問,則該容器也將變得不可訪問。要從這些狀況中恢復過來,可能須要手動干預,外部控制器或操做員。
  • 儘管大多數遠程存儲系統都實現了同步複製,可是大多數本地磁盤產品並不能提供數據持久性保證。意味着磁盤或節點丟失可能致使該磁盤上的全部數據丟失。

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

TopoLVM,一個用於本地存儲的新CSI插件,可以使用LVM動態配置卷。它實現了動態卷配置,原始塊卷,文件系統指標,並將實如今線卷大小調整和臨時卷。

架構

TopoLVM 組件包括:

  • topolvm-controller: CSI controller
  • topolvm-scheduler: 用於TopoLVM 的scheduler extender
  • topolvm-node: CSI node 服務
  • lvmd: 管理LVM卷的gRPC 服務

特性

  • 動態配置:建立PersistentVolumeClaim對象時動態建立卷。
  • 原始塊體積:這些體積可用做容器內的塊設備。
  • 拓撲:TopoLVM使用CSI拓撲功能將Pod調度到LVM卷存在的節點。
  • 擴展的調度程序:TopoLVM擴展了通用Pod調度程序,以對具備更大存儲容量的節點進行優先級排序。
  • 監控指標:使用狀況統計信息從kubelet中導出爲Prometheus指標。

因爲不是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
相關文章
相關標籤/搜索