通过上一节介绍的《Kubernetes 工作负载详解》,我们对Pod以及Pod控制器(Controllers)有了一定的了解,我们知道当业务应用出现故障后,Kubernetes会自动帮我们重建Pod来达到故障恢复的能力,并且当服务恢复后,我们的业务数据仍然在,可以继续保持故障前的状态,这个状态是如何存储和管理的,本节就给大家介绍Kubernetes是如何管理我们的业务数据的。
Volumes介绍
我们的业务数据一般都是存储在各种各样的Volumes里面,这些Volumes以插件的形式被管理和使用。它主要用来解决容器挂掉后数据不丢失的问题和多容器之间共享文件的问题。
Volumes我们也成为卷,Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。
卷的核心是包含一些数据的目录,Pod 中的容器可以访问该目录。 特定的卷类型可以决定这个目录是如何形成的,并能决定它支持何种介质。
使用卷时, Pod 声明中需要提供卷的类型 (.spec.volumes
字段)和卷挂载的位置 (.spec.containers.volumeMounts
字段).并且在容器中的进程能看到由它们的 Docker 镜像和卷组成的文件系统视图。
Volume 的类型
Kubernetes 支持下列类型的卷:
- awsElasticBlockStore
- azureDisk
- azureFile
- cephfs
- cinder
- configMap
- csi
- downwardAPI
- emptyDir
- fc (fibre channel)
- flexVolume
- flocker
- gcePersistentDisk
- gitRepo (deprecated)
- glusterfs
- hostPath
- iscsi
- local
- nfs
- persistentVolumeClaim
- projected
- portworxVolume
- quobyte
- rbd
- scaleIO
- secret
- storageos
- vsphereVolume
下面主要介绍几个常见类型的卷:
emptyDir:临时空目录,与Pod紧密联接,随Pod创建、删除。比如:
hostPath:挂载主机上的一个文件或者目录。比如:
nfs: 即Network File System,NFS中的数据是可以永久保存的,NFS支持同时写操作。Pod被删除时,数据不会丢失。比如:
ConnfigMap:用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件,比如:
创建ConfigMap:
使用ConfigMap:
Secret :跟ConfigMap很类似,主要用于保存包含敏感信息的配置,比如密码、token、密钥等.比如:
生成密码:
输出结果为:dGVzdCBzZWNyZXQ=
创建Secret:
使用Secret:
PersistentVolume介绍
Volume虽然能提供很好的数据持久化,但在可管理性上,还是不足的,要使用Volume,用户必须知道当前的Volume信息和提前创建好对应的Volume,所以推荐使用Kubernetes中的PersistentVolume、PersistentVolumeClaim来解决存储持久化的问题。
PersistentVolume(PV)跟Volume相比,它是Kubernetes中的一种资源,具有生命周期。可以通过Kubernetes创建,删除等管理。PV是一个系统的资源,因此没有所属的命名空间。
在Kubernetes中,PV可以通过以下Volume插件进行实现:
GCEPersistentDisk
AWSElasticBlockStore
AzureFile
AzureDisk
CSI
FC (Fibre Channel)
FlexVolume
Flocker
NFS
iSCSI
RBD (Ceph Block Device)
CephFS
Cinder (OpenStack block storage)
Glusterfs
VsphereVolume
Quobyte Volumes
HostPath
Portworx Volumes
ScaleIO Volumes
StorageOS
比如通过nfs实现:
capacity
指定 PV 的容量为 100Mi。accessModes
指定访问模式为ReadWriteMany
,支持的访问模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。
ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。
PersistentVolumeClaim介绍
PersistentVolumeClaim(PVC)也是Kubernetes中的一种资源,PVC是对PV的请求和使用。
Pod通过PVC来使用PV, PV 和 PVC 之间的交互过程有着自己的生命周期,这个生命周期分为5个阶段:
- 供应(Provisioning):即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建
- 绑定(Binding):将PV分配给PVC
- 使用(Using):Pod通过PVC使用该Volume
- 释放(Releasing):Pod释放Volume并删除PVC
- 回收(Reclaiming):回收PV,可以保留PV以便下次使用,也可以直接从云存储中删除。支持三种策略:
- 保留(Retain): PVC删除后PV和数据仍然保留但此时不可以再创建PVC了,需要管理员手工回收。如果PV是管理员手动创建的,则该策略为默认策略。
- 回收(Recycle):已过时,PVC删除后会自动起一个Pod将PV内的数据全部清空,可以创建新的PVC,需要插件支持。
- 删除(Delete):删除 Storage Provider 上的对应存储资源,需要插件支持。如果PV是通过StorageClass动态创建的,则该策略为默认策略。
根据上述的5个阶段,存储卷存在下面4种状态:
- Available:可用状态,处于此状态表明PV已经准备就绪了,可以被PVC使用了。
- Bound:绑定状态,表明PV已被分配给了PVC。
- Released:释放状态,表明PVC解绑PV,但还未执行回收策略。
- Failed:错误状态,表明PV发生错误。
下面创建一个PVC:
创建Pod(片段),使用上面创建的PVC:
StorageClass介绍
StorageClass用于动态创建PV,它为管理员提供了描述存储 "类"
的方法。
每个 StorageClass
都包含 provisioner
、parameters
和 reclaimPolicy
字段, 这些字段会在StorageClass
需要动态分配 PersistentVolume
时会使用到。
StorageClass
对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass
对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。
下面示例为通过StorageClass来动态创建PV:
1.创建provisioner片段:
- provisioner名称为:my-provisioner
2.创建StorageClass,指向刚才定义的provisioner:
3.创建StatefulSet使用刚创建的StorageClass:
PV和PVC的绑定
在Kubernetes中,会动态的将PVC与可用的PV的进行绑定。Kubernetes的Master中有一个控制器,它将监控新的PVC,并为其查找匹配的PV(如果有),并把PVC和PV绑定在一起。如果一个PV曾经动态供给到了一个新的PVC,那么这个控制器会一直绑定这个PV和PVC。另外,用户总是能得到它们所要求的存储,但是Volume可能超过它们的请求。一旦绑定了,PVC绑定就是专属的,无论它们的绑定模式是什么。
如果没有匹配的PV,那么PVC会无限期的处于未绑定状态,一旦存在匹配的PV,PVC就会绑定此PV。比如,就算集群中存在很多的50G的PV,需要100G容量的PVC也不会匹配这些不满足需求的PV。直到集群中有100G的PV时,PVC才会被绑定。PVC基于下面的条件绑定PV,如果下面的条件同时存在,则选择符合所有要求的PV进行绑定:
1)如果PVC指定了存储类(StorageClass),则只会绑定指定了同样存储类(StorageClass)的PV;
2)如果PVC设置了选择器,则选择器去匹配符合的PV;
3)如果没有指定存储类和设置选取器,PVC会根据存储空间容量大小和访问模式匹配符合的PV。
总结
PersistentVolume(PV)用于为用户和管理员提供如何提供和消费存储的API,PV是由管理员在集群中提供的存储。它就像Node一样是集群中的一种资源。PV也是和存储卷一样的一种插件,但其有着自己独立的生命周期。PersistentVolumeClaim (PVC)是用户对存储的请求,类似于Pod消费Node资源,PVC消费PV资源。Pod能够请求特定的资源(CPU和内存),声明请求特定的存储大小和访问模式。关于Kubernetes存储这里就介绍这么多,大家理解了PV,PVC以及StorageClass基本上就可以玩转Kubernetes的存储了。下节给大家介绍《Kubernetes 网络详解》。