KUBERNETES存儲之PERSISTENT VOLUMES簡介

KUBERNETES存儲之PERSISTENT VOLUMES簡介

簡介

  管理存儲和管理計算有着明顯的不同。PersistentVolume子系統給用戶和管理員提供了一套API,從而抽象出存儲是如何提供和消耗的細節。在這裏,我們介紹兩種新的API資源:PersistentVolume(簡稱PV)和PersistentVolumeClaim(簡稱PVC)。
  PersistentVolume(持久卷,簡稱PV)是集羣內,由管理員提供的網絡存儲的一部分。就像集羣中的節點一樣,PV也是集羣中的一種資源。它也像Volume一樣,是一種volume插件,但是它的生命週期卻是和使用它的Pod相互獨立的。PV這個API對象,捕獲了諸如NFS、ISCSI、或其他雲存儲系統的實現細節。
  PersistentVolumeClaim(持久卷聲明,簡稱PVC)是用戶的一種存儲請求。它和Pod類似,Pod消耗Node資源,而PVC消耗PV資源。Pod能夠請求特定的資源(如CPU和內存)。PVC能夠請求指定的大小和訪問的模式(可以被映射爲一次讀寫或者多次只讀)。
  PVC允許用戶消耗抽象的存儲資源,用戶也經常需要各種屬性(如性能)的PV。集羣管理員需要提供各種各樣、不同大小、不同訪問模式的PV,而不用向用戶暴露這些volume如何實現的細節。因爲這種需求,就催生出一種StorageClass資源。
  StorageClass提供了一種方式,使得管理員能夠描述他提供的存儲的等級。集羣管理員可以將不同的等級映射到不同的服務等級、不同的後端策略。
  請查看detailed walkthrough with working examples

volume和claim的生命週期

  PV是集羣中的資源,PVC是對這些資源的請求,同時也是這些資源的“提取證”。PV和PVC的交互遵循以下生命週期:

供給

  有兩種PV提供的方式:靜態和動態。

靜態

  集羣管理員創建多個PV,它們攜帶着真實存儲的詳細信息,這些存儲對於集羣用戶是可用的。它們存在於Kubernetes API中,並可用於存儲使用。

動態

  當管理員創建的靜態PV都不匹配用戶的PVC時,集羣可能會嘗試專門地供給volume給PVC。這種供給基於StorageClass:PVC必須請求這樣一個等級,而管理員必須已經創建和配置過這樣一個等級,以備發生這種動態供給的情況。請求等級配置爲“”的PVC,有效地禁用了它自身的動態供給功能。

綁定

  用戶創建一個PVC(或者之前就已經就爲動態供給創建了),指定要求存儲的大小和訪問模式。master中有一個控制迴路用於監控新的PVC,查找匹配的PV(如果有),並把PVC和PV綁定在一起。如果一個PV曾經動態供給到了一個新的PVC,那麼這個迴路會一直綁定這個PV和PVC。另外,用戶總是至少能得到它們所要求的存儲,但是volume可能超過它們的請求。一旦綁定了,PVC綁定就是專屬的,無論它們的綁定模式是什麼。
  如果沒找到匹配的PV,那麼PVC會無限期得處於unbound未綁定狀態,一旦PV可用了,PVC就會又變成綁定狀態。比如,如果一個供給了很多50G的PV集羣,不會匹配要求100G的PVC。直到100G的PV添加到該集羣時,PVC纔會被綁定。

使用

  Pod使用PVC就像使用volume一樣。集羣檢查PVC,查找綁定的PV,並映射PV給Pod。對於支持多種訪問模式的PV,用戶可以指定想用的模式。
  一旦用戶擁有了一個PVC,並且PVC被綁定,那麼只要用戶還需要,PV就一直屬於這個用戶。用戶調度Pod,通過在Pod的volume塊中包含PVC來訪問PV。

釋放

  當用戶使用PV完畢後,他們可以通過API來刪除PVC對象。當PVC被刪除後,對應的PV就被認爲是已經是“released”了,但還不能再給另外一個PVC使用。前一個PVC的屬於還存在於該PV中,必須根據策略來處理掉。

回收

  PV的回收策略告訴集羣,在PV被釋放之後集羣應該如何處理該PV。當前,PV可以被Retained(保留)、 Recycled(再利用)或者Deleted(刪除)。保留允許手動地再次聲明資源。對於支持刪除操作的PV卷,刪除操作會從Kubernetes中移除PV對象,還有對應的外部存儲(如AWS EBS,GCE PD,Azure Disk,或者Cinder volume)。動態供給的卷總是會被刪除。

Recycled(再利用)

  如果PV卷支持再利用,再利用會在PV捲上執行一個基礎的擦除操作(rm -rf /thevolume/*),使得它可以再次被其他PVC聲明利用。
  管理員可以通過Kubernetes controller manager的命令行工具(點擊查看),來配置自定義的再利用Pod模板。自定義的再利用Pod模板必須包含PV卷的詳細內容,如下示例:

apiVersion: v1
kind: Pod
metadata:
  name: pv-recycler-
  namespace: default
spec:
  restartPolicy: Never
  volumes:
  - name: vol
    hostPath:
      path: /any/path/it/will/be/replaced
  containers:
  - name: pv-recycler
    image: "gcr.io/google_containers/busybox"
    command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
    volumeMounts:
    - name: vol
      mountPath: /scrub

  如上,在volumes部分的指定路徑,應該被替換爲PV卷需要再利用的路徑。
  

PV類型

  PV類型使用插件的形式來實現。Kubernetes現在支持以下插件:
  GCEPersistentDisk
  AWSElasticBlockStore
  AzureFile
  AzureDisk
  FC (Fibre Channel)
  Flocker
  NFS
  iSCSI
  RBD (Ceph Block Device)
  CephFS
  Cinder (OpenStack block storage)
  Glusterfs
  VsphereVolume
  Quobyte Volumes
  HostPath (僅測試過單節點的情況——不支持任何形式的本地存儲,多節點集羣中不能工作)
  VMware Photon
  Portworx Volumes
  ScaleIO Volumes

PV介紹

  每個PV都包含一個spec和狀態,即說明書和PV卷的狀態。

  apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: pv0003
  spec:
    capacity:
      storage: 5Gi
    accessModes:
      - ReadWriteOnce
    persistentVolumeReclaimPolicy: Recycle
    storageClassName: slow
    nfs:
      path: /tmp
      server: 172.17.0.2

Capacity(容量)

  一般來說,PV會指定存儲的容量,使用PV的capacity屬性來設置。查看Kubernetes的Resource Model來了解capacity
  當前,存儲大小是唯一能被設置或請求的資源。未來可能包含IOPS,吞吐率等屬性。

訪問模式

  PV可以使用存儲資源提供商支持的任何方法來映射到host中。如下的表格中所示,提供商有着不同的功能,每個PV的訪問模式被設置爲卷支持的指定模式。比如,NFS可以支持多個讀/寫的客戶端,但可以在服務器上指定一個只讀的NFS PV。每個PV有它自己的訪問模式。
  訪問模式包括:
   ▷ ReadWriteOnce —— 該volume只能被單個節點以讀寫的方式映射
   ▷ ReadOnlyMany —— 該volume可以被多個節點以只讀方式映射
   ▷ ReadWriteMany —— 該volume只能被多個節點以讀寫的方式映射
  在CLI中,訪問模式可以簡寫爲:
   ▷ RWO - ReadWriteOnce
   ▷ ROX - ReadOnlyMany
   ▷ RWX - ReadWriteMany
  注意:即使volume支持很多種訪問模式,但它同時只能使用一種方式來映射。比如,GCEPersistentDisk可以被單個節點映射爲ReadWriteOnce,或者多個節點映射爲ReadOnlyMany,但不能同時使用這兩種方式來映射。

Volume Plugin ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStore - -
AzureFile
AzureDisk - -
CephFS
Cinder - -
FC -
FlexVolume -
Flocker - -
GCEPersistentDisk -
Glusterfs
HostPath - -
iSCSI -
PhotonPersistentDisk - -
Quobyte
NFS
RBD -
VsphereVolume - -
PortworxVolume -
ScaleIO -

Class

  一個PV可以有一種class,通過設置storageClassName屬性來選擇指定的StorageClass。有指定class的PV只能綁定給請求該class的PVC。沒有設置storageClassName屬性的PV只能綁定給未請求class的PVC。
  過去,使用volume.beta.kubernetes.io/storage-class註解,而不是storageClassName屬性。該註解現在依然可以工作,但在Kubernetes的未來版本中已經被完全棄用了。

回收策略

  當前的回收策略有:
   ▷ Retain:手動回收
   ▷ Recycle:需要擦出後才能再使用
   ▷ Delete:相關聯的存儲資產,如AWS EBS,GCE PD,Azure Disk,or OpenStack Cinder卷都會被刪除
  當前,只有NFS和HostPath支持回收利用,AWS EBS,GCE PD,Azure Disk,or OpenStack Cinder卷支持刪除操作。

階段

  一個volume卷處於以下幾個階段之一:
   ▷ Available:空閒的資源,未綁定給PVC
   ▷ Bound:綁定給了某個PVC
   ▷ Released:PVC已經刪除了,但是PV還沒有被集羣回收
   ▷ Failed:PV在自動回收中失敗了
  CLI可以顯示PV綁定的PVC名稱。

映射選項

  當PV被映射到一個node上時,Kubernetes管理員可以指定額外的映射選項。可以通過使用標註volume.beta.kubernetes.io/mount-options來指定PV的映射選項。
  比如:

apiVersion: "v1"
kind: "PersistentVolume"
metadata:
  name: gce-disk-1
  annotations:
    volume.beta.kubernetes.io/mount-options: "discard"
spec:
  capacity:
    storage: "10Gi"
  accessModes:
    - "ReadWriteOnce"
  gcePersistentDisk:
    fsType: "ext4"
    pdName: "gce-disk-1

  映射選項是當映射PV到磁盤時,一個可以被遞增地添加和使用的字符串。
  注意,並非所有的PV類型都支持映射選項。在Kubernetes v1.6中,以下的PV類型支持映射選項。
   ● GCEPersistentDisk
   ● AWSElasticBlockStore
   ● AzureFile
   ● AzureDisk
   ● NFS
   ● iSCSI
   ● RBD (Ceph Block Device)
   ● CephFS
   ● Cinder (OpenStack block storage)
   ● Glusterfs
   ● VsphereVolume
   ● Quobyte Volumes
   ● VMware Photon

PersistentVolumeClaims(PVC)

  每個PVC都包含一個specstatus,即該PVC的規則說明和狀態。

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

訪問模式

  當請求指定訪問模式的存儲時,PVC使用的規則和PV相同。

資源

  PVC,就像pod一樣,可以請求指定數量的資源。請求資源時,PV和PVC都使用相同的資源樣式

選擇器(Selector)

  PVC可以指定標籤選擇器進行更深度的過濾PV,只有匹配了選擇器標籤的PV才能綁定給PVC。選擇器包含兩個字段:
   ● matchLabels(匹配標籤) - PV必須有一個包含該值得標籤
   ● matchExpressions(匹配表達式) - 一個請求列表,包含指定的鍵、值的列表、關聯鍵和值的操作符。合法的操作符包含In,NotIn,Exists,和DoesNotExist。
  所有來自matchLabelsmatchExpressions的請求,都是邏輯與關係的,它們必須全部滿足才能匹配上。

等級(Class)

  PVC可以使用屬性storageClassName來指定StorageClass的名稱,從而請求指定的等級。只有滿足請求等級的PV,即那些包含了和PVC相同storageClassName的PV,才能與PVC綁定。
  PVC並非必須要請求一個等級。設置storageClassName爲“”的PVC總是被理解爲請求一個無等級的PV,因此它只能被綁定到無等級的PV(未設置對應的標註,或者設置爲“”)。未設置storageClassName的PVC不太相同,DefaultStorageClass的權限插件打開與否,集羣也會區別處理PVC。
   • 如果權限插件被打開,管理員可能會指定一個默認的StorageClass。所有沒有指定StorageClassName的PVC只能被綁定到默認等級的PV。要指定默認的StorageClass,需要在StorageClass對象中將標註storageclass.kubernetes.io/is-default-class設置爲“true”。如果管理員沒有指定這個默認值,集羣對PVC創建請求的迴應就和權限插件被關閉時一樣。如果指定了多個默認等級,那麼權限插件禁止PVC創建請求。
   • 如果權限插件被關閉,那麼久沒有默認StorageClass的概念。所有沒有設置StorageClassName的PVC都只能綁定到沒有等級的PV。因此,沒有設置StorageClassName的PVC就如同設置StorageClassName爲“”的PVC一樣被對待。
   根據安裝方法的不同,默認的StorageClass可能會在安裝過程中被插件管理默認的部署在Kubernetes集羣中。
   當PVC指定selector來請求StorageClass時,所有請求都是與操作的。只有滿足了指定等級和標籤的PV纔可能綁定給PVC。當前,一個非空selector的PVC不能使用PV動態供給。
   過去,使用volume.beta.kubernetes.io/storage-class註解,而不是storageClassName屬性。該註解現在依然可以工作,但在Kubernetes的未來版本中已經被完全棄用了。

使用PVC

  Pod通過使用PVC(使用方式和volume一樣)來訪問存儲。PVC必須和使用它的pod在同一個命名空間,集羣發現pod命名空間的PVC,根據PVC得到其後端的PV,然後PV被映射到host中,再提供給pod。

kind: Pod
apiVersion: v1
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: dockerfile/nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

命名空間注意事項

  PV綁定是獨有的,因爲PVC是命名空間對象,映射PVC時只能在同一個命名空間中使用多種模式(ROXRWX)。

StorageClass

  每個StorageClass都包含字段provisionerparameters,在所屬的PV需要動態供給時使用這些字段。
  StorageClass對象的命名是非常重要的,它是用戶請求指定等級的方式。當創建StorageClass對象時,管理員設置等級的名稱和其他參數,但對象不會在創建後馬上就被更新。
  管理員可以指定一個默認的StorageClass,用於綁定到那些未請求指定等級的PVC。詳細信息可參考PersistentVolumeClaim章節。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2

Provisioner

  StorageClass都有存儲供應商provisioner,用來決定哪種volume插件提供給PV使用。必須制定該字段。
  你不限於指定此處列出的“內部”供應商(其名稱前綴爲“kubernetes.io”並與Kubernetes一起分發)。你還可以運行和指定外部供應商,它們是遵循Kubernetes定義的規範的獨立程序。外部提供者的作者對代碼的生命週期,供應商的分發方式,運行狀況以及使用的卷插件(包括Flex)等都有充分的自主權。庫kubernetes-incubator/external-storage存放了一個庫, 用於編寫外部存儲供應商,而這些提供者實現了大量的規範,並且是各種社區維護的。

參數

  StorageClass有一些參數用於描述歸屬於該StorageClass的volume。不同的存儲提供商可能需要不同的參數。比如,參數type對應的值io1,還有參數iopsPerGB,都是EBS專用的參數。當參數省略時,就會使用它的默認值。

AWS

...

GCE

...

Glusterfs

...

OpenStack Cinder

...

vSphere

...

Ceph RBD

  apiVersion: storage.k8s.io/v1
  kind: StorageClass
  metadata:
    name: fast
  provisioner: kubernetes.io/rbd
  parameters:
    monitors: 10.16.153.105:6789
    adminId: kube
    adminSecretName: ceph-secret
    adminSecretNamespace: kube-system
    pool: kube
    userId: kube
    userSecretName: ceph-secret-user

  ● monitors:Ceph的monitor,逗號分隔。該參數是必須的。
  ● adminId:Ceph的客戶端ID,可在pool中創建鏡像。默認的是“admin”。
  ● adminSecretNamespace:adminSecret的命名空間,默認值是“default”。
  ● adminSecretNameadminId的Secret Name。改參數是必須的,提供的祕鑰必須有類型“kubernetes.io/rbd”。
  ● pool:Ceph的RBD pool,默認值是“rbd”。
  ● userId:Ceph的客戶ID,用於映射RBD鏡像的,默認值和adminId參數相同。
  ● userSecretName:Ceph Secret的名稱,userId用該參數來映射RBD鏡像。它必須和PVC在相同的命名空間。該參數也是必須的。提供的祕鑰必須有類型“kubernetes.io/rbd”。比如,按照下面的方式來創建:

$ kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' --namespace=kube-system

Quobyte

...

Azure Disk

...

Portworx Volume

...

ScaleIO

...

配置

  如果你在寫配置模板和示例,用於在需要持久化存儲的集羣中使用,那麼,我們建議你使用以下的一些模式:
   ● 在你的捆綁配置(如Deployment、ConfigMap胖)中包含PVC對象。
   ● 在配置中不要包含PersistentVolume對象,因爲實例化配置的用戶可能沒有創建PersistentVolumes的權限
   ● 當用戶提供實例化模板時,給用戶提供存儲類名稱的選項。
    ▷ 如果用戶提供了一個StorageClass名稱,並且Kubernetes版本是1.4及以上,那麼將該值設置在PVC的volume.beta.kubernetes.io/storage-class標註上。這會使得PVC匹配到正確的StorageClass
    ▷ 如果用戶沒有提供StorageClass名稱,或者集羣版本是1.3,那麼久需要在PVC配置中設置volume.alpha.kubernetes.io/storage-class: default標註。
     ☞ 這會使得在一些默認配置健全的集羣中,PV可以動態的提供給用戶。
     ☞ 儘管在名稱中包含了alpha單詞,但是該標註對應的代碼有着beta級別的支持。
     ☞ 不要使用volume.beta.kubernetes.io/storage-class,無論設置什麼值,甚至是空字符串。因爲它會阻止DefaultStorageClass許可控制器。
   ● 在你的工具中,要監視那些一段時間後還沒有獲得綁定的PVC,並且展示給用戶。因爲這可能表明集羣沒有支持動態存儲(此時我們應該創建匹配的PV),或者集羣沒有存儲系統(此時用戶不能部署需要PVC的情況)。
   ● 未來,我們期望大多數集羣都可以使能DefaultStorageClass,並且能有一些可用的存儲形式。然而,可能沒有行在所有集羣都能運的StorageClass,所以默認情況下不要只設置一種。在某些時候,alpha標註將不再具有意義,但復位PVC的storageClass字段將具有所需的效果。

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