在Kubernetes中部署和运行的服务大致分为:
无状态服务
Kubernetes使用ReplicaSet来保证一个服务的实例数量,如果说某个Pod实例由于某种原因挂掉或崩溃,ReplicaSet会立刻用这个Pod的模版新启一个Pod来替代它。由于是无状态的服务,新Pod与旧Pod一模一样。此外Kubernetes通过Service(一个Service后面可以挂多个Pod)对外提供一个稳定的访问接口,实现服务的高可用。
普通有状态服务
和无状态服务相比,它多了状态保存的需求。Kubernetes提供了以Volume和Persistent Volume为基础的存储系统,可以实现服务的状态保存。
有状态集群服务
和普通有状态服务相比,它多了集群管理的需求。要运行有状态集群服务要解决的问题有两个,一个是状态保存,另一个是集群管理。Kubernetes为此开发了StatefulSet(以前叫做PetSet),方便有状态集群服务在Kubernetes上部署和管理。
简单来说是通过Init Container来做集群的初始化工作,用Headless Service来维持集群成员的稳定关系,用动态存储供给来方便集群扩容,最后用StatefulSet来综合管理整个集群。
分析以上的服务类型,Kubernetes中对于存储的使用主要集中在以下几个方面:
目前Kubernetes所支持的Volume Plugins如下表所示,
Kubernetes已经提供非常丰富的Volume和Persistent Volume插件,大家可以根据自己业务的需要,使用这些插件给容器提供存储服务。每一种Plugin的使用方法和注意事项在此不做赘述,请参考 Kubernetes Volume 的官方文档。
容器存储接口(Container Storage Interface,CSI )是一项跨行业标准倡议,旨在降低云原生存储开发工作的门槛,从而进一步确保兼容性水平。Kubernetes v1.9已经引入了 CSI 的一套alpha实现版本,将新分卷插件的安装流程简化至与安装pod相当,并允许第三方存储供应商在无需接触核心Kubernetes代码库的前提下开发自己的解决方案。
如果上述的这些Plugin不满足业务要求, 你可以通过以下两种途径进行二次开发,
Kubernete存储在设计的时候遵循着Kubernetes的一贯哲学,即声明式(Declarative)架构。同时为了尽可能多地兼容各种存储平台,Kubernetes以in-tree plugin的形式来对接不同的存储系统,满足用户可以根据自己业务的需要使用这些插件给容器提供存储服务。同时兼容用户使用FlexVolume和CSI定制化插件。相比较于Docker Volume,支持的存储功能更加丰富和多样。
其实对于Kubernetes中大部分的Volume Plugin来说,mount的过程遵循着如下的规则:
/some/global/mount/path -> /var/lib/kubelet/pods/
/volumes/// -> 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的访问。
静态provision
动态provision
StorageClass将说明Volume将由哪种Volume Plugin创建、创建时参数以及从其他功能性/非功能性角度描述的后台volume的各种参数。一般为storage cluster的一些配置信息,以及label注释信息。
原文地址