k8s管理存儲資源

Volume

本節我們討論 Kubernetes 的存儲模型 Volume,學習如何將各種持久化存儲映射到容器。

 

我們經常會說:容器和 Pod 是短暫的。

其含義是它們的生命週期可能很短,會被頻繁地銷燬和創建。容器銷燬時,保存在容器內部文件系統中的數據都會被清除。

 

爲了持久化保存容器的數據,可以使用 Kubernetes Volume。

Volume 的生命週期獨立於容器,Pod 中的容器可能被銷燬和重建,但 Volume 會被保留。

本質上,Kubernetes Volume 是一個目錄,這一點與 Docker Volume 類似。當 Volume 被 mount 到 Pod,Pod 中的所有容器都可以訪問這個 Volume。Kubernetes Volume 也支持多種 backend 類型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph 等。

kubernetes Volume種類:

emptyDir

 

emptyDir 是最基礎的 Volume 類型。正如其名字所示,一個 emptyDir Volume 是 Host 上的一個空目錄。

emptyDir Volume 對於容器來說是持久的,對於 Pod 則不是。當 Pod 從節點刪除時,Volume 的內容也會被刪除。但如果只是容器被銷燬而 Pod 還在,則 Volume 不受影響。

也就是說:emptyDir Volume 的生命週期與 Pod 一致。 Pod 中的所有容器都可以共享 Volume,它們可以指定各自的 mount 路徑。下面通過例子來實踐 emptyDir,配置文件如下:

 

 

 

這裏我們模擬了一個 producer-consumer 場景。Pod 有兩個容器 producer和 consumer,它們共享一個 Volume。producer 負責往 Volume 中寫數據,consumer 則是從 Volume 讀取數據。

① 文件最底部 volumes 定義了一個 emptyDir 類型的 Volume shared-volume。

② producer 容器將 shared-volume mount 到 /producer_dir 目錄。

③ producer 通過 echo 將數據寫到文件 hello 裏。

④ consumer 容器將 shared-volume mount 到 /consumer_dir 目錄。

⑤ consumer 通過 cat 從文件 hello 讀數據。

emptyDir 是 Host 上創建的臨時目錄,其優點是能夠方便地爲 Pod 中的容器提供共享存儲,不需要額外的配置。但它不具備持久性,如果 Pod 不存在了,emptyDir 也就沒有了。根據這個特性,emptyDir 特別適合 Pod 中的容器需要臨時共享存儲空間的場景,比如前面的生產者消費者用例。

 

hostPath Volume

 

hostPath Volume 的作用是將 Docker Host 文件系統中已經存在的目錄 mount 給 Pod 的容器。大部分應用都不會使用 hostPath Volume,因爲這實際上增加了 Pod 與節點的耦合,限制了 Pod 的使用。不過那些需要訪問 Kubernetes 或 Docker 內部數據(配置文件和二進制庫)的應用則需要使用 hostPath。

 

 

 

這裏定義了三個 hostPath volume k8s、certs 和 pki,分別對應 Host 目錄 /etc/kubernetes、/etc/ssl/certs 和 /etc/pki。

如果 Pod 被銷燬了,hostPath 對應的目錄也還會被保留,從這點看,hostPath 的持久性比 emptyDir 強。不過一旦 Host 崩潰,hostPath 也就沒法訪問了。

 

外部 Storage Provider

如果 Kubernetes 部署在諸如 AWS、GCE、Azure 等公有云上,可以直接使用雲硬盤作爲 Volume,下面是 AWS Elastic Block Store 的例子:

要在 Pod 中使用 ESB volume,必須先在 AWS 中創建,然後通過 volume-id 引用。其他雲硬盤的使用方法可參考各公有云廠商的官方文檔。

Kubernetes Volume 也可以使用主流的分佈式存,比如 Ceph、GlusterFS 等,下面是 Ceph 的例子:

Ceph 文件系統的 /some/path/in/side/cephfs 目錄被 mount 到容器路徑 /test-ceph。

相對於 emptyDir 和 hostPath,這些 Volume 類型的最大特點就是不依賴 Kubernetes。Volume 的底層基礎設施由獨立的存儲系統管理,與 Kubernetes 集羣是分離的。數據被持久化後,即使整個 Kubernetes 崩潰也不會受損。

當然,運維這樣的存儲系統通常不是項簡單的工作,特別是對可靠性、高可用和擴展性有較高要求時。

Volume 提供了非常好的數據持久化方案,不過在可管理性上還有不足。

 

PV & PVC

 

Volume 提供了非常好的數據持久化方案,不過在可管理性上還有不足。

拿前面 AWS EBS 的例子來說,要使用 Volume,Pod 必須事先知道如下信息:

  1. 當前 Volume 來自 AWS EBS。

  2. EBS Volume 已經提前創建,並且知道確切的 volume-id。

Pod 通常是由應用的開發人員維護,而 Volume 則通常是由存儲系統的管理員維護。開發人員要獲得上面的信息:

  1. 要麼詢問管理員。

  2. 要麼自己就是管理員。

這樣就帶來一個管理上的問題:應用開發人員和系統管理員的職責耦合在一起了。如果系統規模較小或者對於開發環境這樣的情況還可以接受。但當集羣規模變大,特別是對於生成環境,考慮到效率和安全性,這就成了必須要解決的問題。

Kubernetes 給出的解決方案是 PersistentVolume 和 PersistentVolumeClaim。

PersistentVolume (PV) 是外部存儲系統中的一塊存儲空間,由管理員創建和維護。與 Volume 一樣,PV 具有持久性,生命週期獨立於 Pod。

PersistentVolumeClaim (PVC) 是對 PV 的申請 (Claim)。PVC 通常由普通用戶創建和維護。需要爲 Pod 分配存儲資源時,用戶可以創建一個 PVC,指明存儲資源的容量大小和訪問模式(比如只讀)等信息,Kubernetes 會查找並提供滿足條件的 PV。

有了 PersistentVolumeClaim,用戶只需要告訴 Kubernetes 需要什麼樣的存儲資源,而不必關心真正的空間從哪裏分配,如何訪問等底層細節信息。這些 Storage Provider 的底層信息交給管理員來處理,只有管理員才應該關心創建 PersistentVolume 的細節信息。

NFS PersistentVolume

部署節點搭建nfs服務器

 

創建 PV 

#vim nfs-pv1.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 192.168.146.151

 

① capacity 指定 PV 的容量爲 1G。

② accessModes 指定訪問模式爲 ReadWriteOnce,支持的訪問模式有:

    ReadWriteOnce – PV 能以 read-write 模式 mount 到單個節點。

    ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節點。

    ReadWriteMany – PV 能以 read-write 模式 mount 到多個節點。

③ persistentVolumeReclaimPolicy 指定當 PV 的回收策略爲 Recycle,支持的策略有:

    Retain – 需要管理員手工回收。

    Recycle – 清除 PV 中的數據,效果相當於執行 rm -rf /thevolume/*

    Delete – 刪除 Storage Provider 上的對應存儲資源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

④ storageClassName 指定 PV 的 class 爲 nfs。相當於爲 PV 設置了一個分類,PVC 可以指定 class 申請相應 class 的 PV。

⑤ 指定 PV 在 NFS 服務器上對應的目錄。

 

注意要做storage-provider段要提前建好文件夾

#kubectl apply -f nfs-pv1.yml

#kubectl get pv

創建pvc

#vim nfs-pvc1.yml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs

#kubectl apply -f nfs-pvc1.yml

 

Pod使用pvc

接下來就可以在 Pod 中使用存儲了,Pod 配置文件 pod1.yml 如下:

kind: Pod
apiVersion: v1
metadata:
  name: mypod1
spec:
  containers:
    - name: mypod1
      image: busybox
      args:
      - /bin/sh
      - -c
      - sleep 30000
      volumeMounts:
      - mountPath: "/mydata"
        name: mydata
  volumes:
    - name: mydata
      persistentVolumeClaim:
        claimName: mypvc

驗證

通過pvc回收pv

 

當 PV 不再需要時,可通過刪除 PVC 回收。

#kubectl delete -f pod1.yml

#kubectl delete pvc mypvc1

 

 

當 PVC mypvc1 被刪除後,我們發現 Kubernetes 啓動了一個新 Pod這個 Pod 的作用就是清除 PV mypv1 的數據。這個時候我們再看 NFS 服務器目錄 /nfsdata/pv1 中已經沒有數據了。

 

當數據清除完畢,mypv1 的狀態重新變爲 Available,此時則可以被新的 PVC 申請。

 

因爲 PV 的回收策略設置爲 Recycle,所以數據會被清除,但這可能不是我們想要的結果。如果我們希望保留數據,可以將策略設置爲 Retain。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章