【编者的话】本次分享分为三大部分。第一部分主要介绍Kubernetes中经常使用的几种存储,及其使用场景和生命周期等等。第二部分试图介绍一些设计原则和基本架构,并简要介绍各类存储plugin的实现机制及持久卷的一些特性,例如访问模式、回收策略等等。动态卷供给是一个Kubernetes独有的功能,这一功能容许按需建立存储卷,使管理员没必要预先建立存储卷,而是随用户需求进行建立。第三部分会介绍一下v1.9中存储的一些新特性。html
在Kubernetes中部署和运行的服务大体分为:git
Kubernetes使用ReplicaSet来保证一个服务的实例数量,若是说某个Pod实例因为某种缘由挂掉或崩溃,ReplicaSet会马上用这个Pod的模版新启一个Pod来替代它。因为是无状态的服务,新Pod与旧Pod如出一辙。此外Kubernetes经过Service(一个Service后面能够挂多个Pod)对外提供一个稳定的访问接口,实现服务的高可用。github
和无状态服务相比,它多了状态保存的需求。Kubernetes提供了以Volume和Persistent Volume为基础的存储系统,能够实现服务的状态保存。docker
和普通有状态服务相比,它多了集群管理的需求。要运行有状态集群服务要解决的问题有两个,一个是状态保存,另外一个是集群管理。Kubernetes为此开发了StatefulSet(之前叫作PetSet),方便有状态集群服务在Kubernetes上部署和管理。安全
简单来讲是经过Init Container来作集群的初始化工做,用Headless Service来维持集群成员的稳定关系,用动态存储供给来方便集群扩容,最后用StatefulSet来综合管理整个集群。架构
分析以上的服务类型,Kubernetes中对于存储的使用主要集中在如下几个方面:app
目前Kubernetes所支持的Volume Plugins以下表所示,less
Kubernetes已经提供很是丰富的Volume和Persistent Volume插件,你们能够根据本身业务的须要,使用这些插件给容器提供存储服务。每一种Plugin的使用方法和注意事项在此不作赘述,请参考 Kubernetes Volume 的官方文档。ide
容器存储接口(Container Storage Interface,CSI )是一项跨行业标准倡议,旨在下降云原生存储开发工做的门槛,从而进一步确保兼容性水平。Kubernetes v1.9已经引入了 CSI 的一套alpha实现版本,将新分卷插件的安装流程简化至与安装pod至关,并容许第三方存储供应商在无需接触核心Kubernetes代码库的前提下开发本身的解决方案。post
若是上述的这些Plugin不知足业务要求, 你能够经过如下两种途径进行二次开发,
feature-gate
中enable,不推荐在production环境中使用。v1.9已经把 CSI 做为in-tree plugin,把out-off-tree volume插件的开发从 Kubernetes 中脱离出来,极大地方便了插件的开发、维护和集成。如何使用CSI,可参考How to Use Kubernetes 1.9.0 with CSI。Kubernete存储在设计的时候遵循着Kubernetes的一向哲学,即声明式(Declarative)架构。同时为了尽量多地兼容各类存储平台,Kubernetes以in-tree plugin的形式来对接不一样的存储系统,知足用户能够根据本身业务的须要使用这些插件给容器提供存储服务。同时兼容用户使用FlexVolume和CSI定制化插件。相比较于Docker Volume,支持的存储功能更加丰富和多样。
Kubernetes中mount 一个PV的基本过程包括:
in-tree
或者out-of-tree
),建立PV,并在系统中与对应的PVC绑定;其实对于Kubernetes中大部分的Volume Plugin来讲,mount的过程遵循着以下的规则:
/some/global/mount/path -> /var/lib/kubelet/pods/<pod uid> /volumes/<volume plugin>/<volume name>/ -> container volume
这种方式的好处至关于热插拔,一旦Pod挂掉,kubelet能够立刻重启,并快速mount volume,不会出现相似于device busy的情形。
可是对于hostpath
这个Plugin而言,直接就是 /some/global/mount/path -> container volume
。
一个运行中的容器,缺省状况下,对文件系统的写入,都是发生在其分层文件系统的可写层的(Copy-on-Write)。当迁移的应用程序从开发到生产环境时候,开发人员面临着巨大的挑战。当容器挂掉、崩溃或运行结束时,任何与之相关的数据都会丢失。为了解决这个问题引起的数据丢失,咱们须要将数据存储持久化,也能够称为Persistent Volume。
Kubernetes使用两种资源管理存储:
Kubernetes中的Volume则是基于Docker进行扩展,使用Docker Volume挂载宿主机上的文件目录到容器中。
通常来讲,Kubernetes中Pod经过以下三种方式来访问存储资源。
该种方式移植性较差,可扩展能力差,把Volume的基本信息彻底暴露给用户,有严重的安全隐患,同时须要协调不一样users对Volume的访问。
StorageClass将说明Volume将由哪一种Volume Plugin建立、建立时参数以及从其余功能性/非功能性角度描述的后台volume的各类参数。通常为storage cluster的一些配置信息,以及label注释信息。
通常来讲,PV和PVC的生命周期分为5个阶段:
根据这5个阶段,Volume的状态有如下4种:
详细的步骤请参考相关的 Proposal及其代码实现。
简单来讲,这个Fianlizer相似于垃圾回收(GC)里面的指针计数,当这个使用这个PVC的POD都被删除(deleted)或处于完成状态(completed)时,才能够删除这个PVC。从而避免了删除正在运行中的container的PVC,从而引起数据丢失。