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 exampleshtml

volume和claim的生命週期

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

供給

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

靜態

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

動態

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

綁定

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

使用

  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中,必須根據策略來處理掉。api

回收

  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字段將具備所需的效果。

相關文章
相關標籤/搜索