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

相关文章
相关标签/搜索