在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在K8S中,当Pod重建的时候,数据是会丢失的,K8S也是通过数据卷挂载来提供Pod数据的持久化的。K8S数据卷是对Docker数据卷的扩展,K8S数据卷是Pod级别的,可以用来实现Pod中容器的文件共享。
支持的类型
EmptyDir
HostPath
GCE PersistentDisk
AWS ElasticBlock Store
NFS
iSCSI
Flocker
GlusterFS
RBD
Git Repo
Secret
PersistentVolume Claim
Downward API
本地数据卷
EmptyDir、HostPath这两种类型的数据卷,只能用于本地文件系统。本地数据卷中的数据只会存在于一台机器上,所以当Pod发生迁移的时候,数据便会丢失。该类型Volume的用途是:Pod中容器间的文件共享、共享宿主机的文件系统。
EmptyDir
如果Pod配置了EmpyDir数据卷,在Pod的生命周期内都会存在,当Pod被分配到Node上时,会在Node上创建EmptyDir数据卷,并挂载到Pod的容器中。只要Pod存在,EmpyDir数据卷都会存在(容器删除不会导致EmpyDir数据卷丟失数据),但是如果Pod的生命周期终结(Pod被删除),EmpyDir数据卷也会被删除,并且永久丢失。
EmpyDir数据卷非常适合实现Pod中容器的文件共享。Pod的设计提供了一个很好的容器组合的模型,容器之间各司其职,通过共享文件目录来完成交互,比如可以通过一个专职日志收集容器,在每个Pod中和业务容器中进行组合,来完成日志的收集和汇总。
HostPath
HostPath数据卷允许将容器宿主机上的文件系统挂载到Pod中。如果Pod需要使用宿主机上的某些文件,可以使用HostPath。
网络数据卷
K8S提供了很多类型的数据卷以集成第三方的存储系统,包括一些非常流行的分布式文件系统,也有在IaaS平台上提供的存储支持,这些存储系统都是分布式的,通过网络共享文件系统,因此我们称这一类数据卷为网络数据卷。
网络数据卷能够满足数据的持久化需求,Pod通过配置使用网络数据卷,每次Pod创建的时候都会将存储系统的远端文件目录挂载到容器中,数据卷中的数据将被永久保存,即使Pod被删除,只是除去挂载数据卷,数据卷中的数据仍然保存在存储系统中,且当新的Pod被创建时,仍是挂载同样的数据卷。网络数据卷包含以下几种:NFS、iSCISI、GlusterFS、RBD(Ceph Block Device)、Flocker、AWS Elastic Block Store、GCE Persistent Disk
Persistent Volume和PersistentVolume Claim
概念
存储管理跟计算管理是两个不同的问题。理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,有时并不需要关心各种存储实现,只希望能够安全可靠地存储数据。
为了简化对存储调度,K8S对存储的供应和使用做了抽象,以API形式提供给管理员和用户使用。要完成这一任务,引入了两个新的API资源:Persistent Volume(持久卷,以下简称PV)和Persistent Volume Claim(持久卷申请,以下简称PVC)。
PV是集群中的一块网络存储,跟Node一样,也是集群的资源。PV跟Volume(卷)类似,不过会有独立于Pod的生命周期。由系统管理员配置创建的一个数据卷(目前支持HostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、iSCSI、GlusterFS、RBD),它代表了某一类存储插件实现。
PVC是用户的一个请求,跟Pod类似。Pod消费Node的资源,PVC消费PV的资源。Pod 能够申请特定的资源(CPU和内存);PVC能够申请特定的尺寸和访问模式(例如可以加载一个读写,以及多个只读实例),而无须感知后端的存储实现。
生命周期
PV是集群的资源。PVC是对这一资源的请求,也是对资源的所有权的检验。PV和PVC 之间的互动遵循如下的生命周期。
供应
集群管理员会创建一系列的PV。这些PV包含了为集群用户提供的真实存储资源。可利用 K8S API来消费。
绑定
用户创建一个包含了容量和访问模式的持久卷申请。Master会监听PVC的产生,并尝试根据请求内容查找匹配的PV,并把PV和PVC进行绑定。用户能够获取满足需要的资源,并且在使用过程中可能超出请求数量。
如果找不到合适的卷,这一申请就会持续处于非绑定状态,一直到出现合适的PV。例如一个集群准备了很多的50G大小的持久卷,(虽然总量足够)也是无法响应100G的申请的,除非把100G的PV加入集群。
使用
Pod把申请作为卷来使用。集群会通过PVC查找绑定的PV,并Mount给Pod。对于支持多种访问方式的卷,用户在使用 PVC 作为卷的时候,可以指定需要的访问方式。
一旦用户拥有了一个已经绑定的PVC,被绑定的PV就归该用户所有了。用户的Pods能够通过在Pod的卷中包含的PVC来访问他们占有的PV。
释放
当用户完成对卷的使用时,就可以利用API删除PVC对象了,而且他还可以重新申请。删除PVC后,对应的卷被视为“被释放”,但是这时还不能给其他的PVC使用。之前的PVC数据还保存在卷中,要根据策略来进行后续处理。
回收
PV的回收策略向集群阐述了在PVC释放卷时,应如何进行后续工作。目前可以采用三种策略:保留,回收或者删除。保留策略允许重新申请这一资源。在持久卷能够支持的情况下,删除策略会同时删除持久卷以及AWS EBS/GCE PD或者Cinder卷中的存储内容。如果插件能够支持,回收策略会执行基础的擦除操作(rm -rf /thevolume/*),这一卷就能被重新申请了。
例子
持久卷
每个PV包含一个spec,用于描述该卷的规格和状态。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /tmp
server: 172.17.0.2
Capacity(容量)
一般来说,PV会指定存储容量。这里需要使用PV的capcity属性。
目前存储大小是唯一一个能够被申请的指标。
Access Modes(访问模式)
只要资源提供者支持,持久卷能够被用任何方式加载到主机上。每种存储都会有不同的能力,每个PV的访问模式也会被设置成为该卷所支持的特定模式。例如NFS能够支持多个读写客户端,但某个NFS PV可能会在服务器上以只读方式使用。每个PV都有自己的一系列的访问模式,这些访问模式取决于PV的能力。
访问模式的可选范围如下:
ReadWriteOnce:该卷能够以读写模式被加载到一个节点上。
ReadOnlyMany:该卷能够以只读模式加载到多个节点上。
ReadWriteMany:该卷能够以读写模式被多个节点同时加载。
在 CLI 下,访问模式缩写为:
RWO:ReadWriteOnce
ROX:ReadOnlyMany
RWX:ReadWriteMany
重要!一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。例如一个 GCEPersistentDisk既能支持ReadWriteOnce,也能支持ReadOnlyMany。
Recycling Policy(回收策略)
当前的回收策略可选值包括:
Retain-人工重新申请
Recycle-基础擦除(“rm-rf /thevolume/*”)
Delete-相关的存储资产,例如AWSEBS或GCE PD卷一并删除。
目前,只有NFS和HostPath支持Recycle策略,AWSEBS、GCE PD支持Delete策略。
阶段(Phase)
一个卷会处于如下阶段之一:
Available:可用资源,尚未被绑定到PVC上
Bound:该卷已经被绑定
Released:PVC已经被删除,但该资源尚未被集群回收
Failed:该卷的自动回收过程失败。
CLI 会显示绑定到该 PV 的 PVC。
持久卷申请
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
-ReadWriteOnce
resources:
requests:
storage: 8Gi
访问模式
PVC使用跟PV一致的访问模式。
资源
PVC跟Pod一样可以请求特定数量的资源。在这里的请求内容就是存储(storage)。Resource Model 文中提到的内容对 PV 和 PVC 同样适用。
PVC卷
Pod能够借助PVC来访问存储。PVC必须跟Pod处于同一个命名空间。集群找到Pod命名空间中的PVC,然后利用PVC获取到背后的PV。这个卷就会被加载到主机上,让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
信息数据卷
K8S中有一些数据卷,主要用来给容器传递配置信息,称之为信息数据卷,比如Secret(处理敏感配置信息,密码、Token等)、Downward API(通过环境变量的方式告诉容器Pod的信息)、Git Repo(将Git仓库下载到Pod中),都是将Pod的信息以文件形式保存,然后以数据卷方式挂载到容器中,容器通过读取文件获取相应的信息。