写点什么

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

  • 2020-04-22
  • 本文字数:2832 字

    阅读完需:约 9 分钟

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

近年来一直关注云计算领域的人,必定知道 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 那些相关卷,而且每个卷都有一个名字,直到今天,卷插件的框架基本仍保持不变。

持久卷和持久卷声明

当你想弄清楚如何在 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 进行匹配,因此用户只能请求到预先分配的固定大小的存储空间。这就出现了两种情况:


  1. 如果用户只需要 1GiB 的卷,而可用的最小 PV 是 1TiB,那么用户就必须使用这个 1TiB 的卷。这样之后其他用户就没法使用到这个卷,而这些用户可能需求的容量超过了 1GiB。这不仅会造成存储空间的浪费,还会导致由于资源限制无法启动某些工作负载的情况,而其他的工作负载可能正占有了不需要的资源。

  2. 为了解决第一个问题,管理员要么需要不断地和用户保持通信,确定用户需要的存储大小/性能,要么就预测好需求,并相应地预先分配 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 中的卷与持久化存储的相关内容,敬请关注!


2020-04-22 18:32663

评论

发布
暂无评论
发现更多内容

让人“眼前一亮、不明觉厉”的互联网技术PPT

不脱发的程序猿

程序人生 PPT 2月春节不断更 互联网技术PPT 互联网工具

如何制作和使用自签名证书

soulteary

Docker SSL证书

Java线上故障解决方案

Java 架构

张弛之间,皆是生活

boshi

随笔 七日更

week-13-作业一

未来已来

期末大作业一

心在那片海

简金秋:区块链技术构建服装行业全新商业模式

CECBC

区块链 服装行业

1. 这才是 Python 学习的正确起手姿势,滚雪球学 Python

梦想橡皮擦

Python python 爬虫 2月春节不断更 python入门 python学习

用python提前预测jvm cpu100%自动dump thread

程序员石磊

JVM Thread cpu 100%

反常识的学习思维

小匚

自我思考 成长笔记

话题讨论:公司已经发不出工资了,你会选择坚持还是放弃?

石云升

话题讨论 2月春节不断更

话题讨论 | 云原生应用应该是什么样子?面临的技术挑战有哪些?

xcbeyond

微服务 云原生 Service Mesh 话题讨论

全球区块链与数字经济领军课程

CECBC

数字经济 科技

week12-作业一

未来已来

《王阳明一切心法》读书随笔

BigYoung

读书笔记 28天写作 2月春节不断更 王阳明

第十一周命题作业

cc

阿里架构师经验分享!写给互联网大厂员工的真心话,最全的BAT大厂面试题整理

欢喜学安卓

android 程序员 面试 移动开发

从零开始学Android!15个经典面试问题及回答思路,这原因我服了

欢喜学安卓

android 程序员 面试 移动开发

week12-根据当周学习情况,完成一篇学习总结

未来已来

热乎的阿里、百度、平安等大厂面试真题 你要不要?

比伯

Java 编程 架构 面试 计算机

探寻内部类的奥秘(下)

后台技术汇

2月春节不断更

week13-作业二-根据当周学习情况,完成一篇学习总结

未来已来

AI窥人(一):为什么人类热衷“过度投射”?

脑极体

期末大作业二

心在那片海

复盘银行的区块链实践:从分布式账本,到产业数字化

CECBC

大数据 银行

从崩溃的选课系统,论为什么更安全的 HTTPS 协议没有被全面采用

飞天小牛肉

Java 程序员 面试 计算机网络 2月春节不断更

架构师训练营大作业

菜青虫

基于Docker的大数据开发环境 - HDP Sandbox

大数志

大数据 hadoop spark

使用 Tye 辅助开发 k8s 应用竟如此简单(二)

newbe36524

微服务 k8s dotnet 服务发现

第十一周学习心得

cc

Springboot+Netty+Websocket实现消息推送实例

Java架构师迁哥

深入浅出聊聊Kubernetes存储(一):详解Kubernetes存储关键概念_文化 & 方法_Rancher_InfoQ精选文章