深刻浅出聊聊Kubernetes存储(一):详解Kubernetes存储关键概念

Kubernetes存储全解!你知道PV和PVC的区别吗?storage class和provisioner是什么关系?VolumeClaimTemplates是什么?何时用statefulset?数据库


近年来一直关注云计算领域的人,一定知道Docker和Kubernetes的崛起。现在,世界范围内的公有云巨头(谷歌、亚马逊、微软、华为云、阿里云等等)都在其传统的公共云服务之上提供托管的Kubernetes服务。Kubernetes功能强大、扩展性高,在许多人看来,它正在成为云计算的终极解决方案。框架

但不得不说的是,尽管Kubernetes创建在谷歌在生产环境运行工做负载的超过15年的经验之上,它很是复杂,一些设计决策老是让用户难以理解。即便对于经验最丰富的工程师来讲,Kubernetes的学习曲线也很陡峭。性能

就以存储来举例。你知道PV和PVC的区别吗?storage class和provisioner的关系是什么?VolumeClaimTemplates是什么?何时该用statefulset?学习

在本文中,我将尝试解释Kubernetes中的一些关键概念,以及我对它们的见解。我但愿这也会帮助你们更多地了解Kubernetes。使用Kubernetes时,有许多设计选择和警告让我意想不到。今天我将讲讲PV、PVC、Storage Class和Provisioner。阿里云

Docker中的Volume(卷)云计算

在深刻了解Kubernetes以前,让咱们先聊聊Docker——毕竟Kubernetes是构建在Docker之上。插件

Docker因其简单易用闻名,这也是Docker能如此受欢迎,并成为Kubernetes基础的缘由。Docker容器是无状态、快速的,它能够被破坏、重建,而不须要付出太多的代价。可是,就像是患了健忘症的人,想要记住有意义的事情是很困难的同样。不管是数据库、键值存储、仍是一些原始数据,每个都须要持久化存储。设计

在Docker中建立持久化存储很是简单。早期版本中,用户可使用-v来建立一个新的未定义大小的匿名空卷或者在主机上的目录中建立绑定挂载。那个时候,虽然能够很容易地经过挂载那些已经被存储供应商挂载在主机上的目录,但没有第三方接口帮助你直接挂载到Docker上。2015年8月,Docker发布了v1.8版本,正式引入了卷插件,容许第三方链接它们的存储解决方案。Docker会调用已安装的卷插件来建立/删除/挂载/卸载/get/list那些相关卷,并且每一个卷都有一个名字,直到今天,卷插件的框架基本仍保持不变。对象

持久卷和持久卷声明blog

当你想弄清楚如何在Kubernetes中建立持久存储时,可能会遇到两个概念:持久卷(Persistent Volume,PV)和持久卷声明(Persistent Volume Claim,PVC)

它们是什么?它们中哪一个更接近Docker中的卷?

实际上,它们都不像Docker中的卷。除了PV和PVC以外,Kubernetes还有一个Volume的概念,但它与Docker中的概念不一样,稍后咱们会讨论它。

若是你了解一些关于PV和PVC信息,可能会意识到PV就是分配的存储,而PVC是使用该存储的请求。若是之前你有云计算或存储的经验,那么你可能会认为PV就是一个存储池,而PVC是一个从存储池中分割出来的卷。

不过这都不是PV和PVC真正的意义,在Kubernetes中,一个PV映射到一个PVC,反之亦然,它是一对一的映射。

我已经屡次给具备丰富存储和云计算经验的人解释过这些问题,他们几乎都是抓耳挠腮,不明白这是怎么回事。

而在我第一次遇到这两个概念的时候,我也无法理解。

咱们在这里列出PV和PVC的定义

PersistentVolume(PV)是集群中由管理员配置的一块存储。它是集群中的资源,就和节点是集群资源同样。PV是卷插件好比Volumes,可是它的生命周期独立于使用PV的任何pod个体。该API对象捕获实现存储的详细信息,包括NFS、iSCSI或着是云服务商特定的存储系统。

PersistentVolumeClaim(PVC)是用户关于存储的请求。它相似于一个pod,pod消耗节点资源,而PVC消耗PV资源。Pods能够请求特定级别的资源(CPU和内容),而Claim能够请求特定的大小和访问模式(例如,能够一次读/写或者屡次只读)。

这里须要留意的是“管理员”以及“用户”的区别。

简而言之,Kubernetes将基本存储单元分为两个概念。PV是一个存储器,应该由管理员预先分配,而PVC是用户对存储的请求。

也就是说,Kubernetes但愿管理员来实现分配各类大小的PV。当用户建立PVC来请求存储时,Kubernetes将尝试用该PVC和预先分配的PV匹配。若是能够找到匹配项,就将PVC绑定到PV,用户就能够开始使用这片预分配的存储区。

这种方式和传统方法不一样,传统方法中管理员并不负责分配每一个存储空间。他们只须要授予用户访问某个存储池的权限,而且肯定该用户的配额是多少,而后让用户从存储池中分割出所需的存储部分便可。

不过在Kubernetes的设计中,PV已经从存储池中分割了出来,等待和PVC进行匹配,所以用户只能请求到预先分配的固定大小的存储空间。这就出现了两种状况:

若是用户只须要1GiB的卷,而可用的最小PV是1TiB,那么用户就必须使用这个1TiB的卷。这样以后其余用户就无法使用到这个卷,而这些用户可能需求的容量超过了1GiB。这不只会形成存储空间的浪费,还会致使因为资源限制没法启动某些工做负载的状况,而其余的工做负载可能正占有了不须要的资源。

为了解决第一个问题,管理员要么须要不断地和用户保持通讯,肯定用户须要的存储大小/性能,要么就预测好需求,并相应地预先分配PV。

这样一来就很难强制执行单独的分配(PV)和使用(PVC)。在实际使用中,我并无看到你们讲PV和PVC做为他们的设计方式。极可能管理员很快就放弃了建立PV的权限并把它委托给用户执行。因为PV和PVC仍然是一对一的绑定,PVC的存在就变得不那么必要了。

在我看来,至少能够说,使用PV和PVC的示例是不常见的。

Storage Class和Provisioner

可能由于PV和PVC使用起来太麻烦了,在2017年3月,随着v1.6版本的发布,Kubernetes引入了动态纳管(dynamic provisioning)、Storage Class和Provisioner的概念。动态纳管与传统存储方法相似。管理员可使用Storage Class来描述他们提供的存储“class”。Storage Class能够有不一样的容量限制、不一样的IOPS或其余Provisioner支持的参数。特定于存储供应商的Provisioner将与Storage Class一块儿使用,根据Storage Class对象中设置的参数自动分配PV。此外,Provisioner如今可以强制执行用户的报价(quotes)和权限要求。在这种设计中,管理员已经从预测和分配PV的繁琐中摆脱出来,这样的方式更有意义。

另外,你还可使用Storage Class而无需在Kubernetes中建立Storage Class对象。因为Storage Class也是用于PVC和PV(没必要由Provisioner建立)的字段,所以你可使用自定义的Storage Class名称手动建立PV,而后建立一个请求相同Storage Class名称的PVC。即便存储类Storage Class对象不存在,Kubernetes也会将PVC绑定到具备相同存储类名称的PV上。

dynamic provisioning、Storage Class以及Provisioner对我来讲很是有意义,它解决了最初的PV和PVC设计中最大的可用性问题。但与此同时,这些新概念也加重了Kubernetes存储的另外一个问题,即处理持久存储的各类方式形成的混乱。在本系列文章的下一篇中,咱们将分享Kubernetes中的卷与持久化存储的相关内容,敬请关注!

相关文章
相关标签/搜索