TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘
正文
研发测试场景下,一般追求的是一键快速起环境,横向动态复制,一人一套,随起随用,用完即走。作为使用方,其不用关心实际的物理资源是怎样的,环境起在哪里,只要声明自己的使用需求即可。但作为方案构建者以及infrastructure支撑,我们却深知,要想提供更好的解决方案,个中问题还有很多,且颇为不易。
比如在过去,笔者就曾一度困扰于如何优雅的放开本地物理盘给业务使用这个问题,尤其是本地HDD数据盘。
这里有个背景,我们的Kubernetes研发测试集群是用线上退下来的过保机器搭建,然后七牛又搞云存储,所以我们的机器中很多那种多盘位的存储密集型机器(比如挂12块4T的盘)。所以如何更好的利用这些磁盘,就是个问题。
方案之一是把这些盘组成网络存储,然后通过七牛自身的云服务或者ceph等系统提供出去,这当然是可行的。不过有些业务其实就想单纯使用物理盘,那该怎么办呢?
纵观Kubernetes目前原生提供的几种方案,笔者发现都不完美:
- Emptydir 非持久化方案,Pod删除,EmptyDir也会被清空。另外Emptydir使用的是rootfs的存储空间,而这个空间有可能是放在在系统盘上的,所以对它的使用当慎之又慎。
- HostPath 持久化方案,但安全风险很高,官方不推荐。另外,从使用角度也不方便。比如作为用户,你首先要清楚知道目标系统的情况,知道具体的盘符和目录位置然后才能在HostPath里正确引用。但现实是从集群安全角度,用户不一定有直接登录机器的权限。另外即使你的Pod占了某个宿主机的目录,也不能排除别人二次占用,或者误操作。所以HostPath的使用场景实际很受限。
- Local Persistent Volume 持久化方案,以PVC/PV的形式来使用本地存储。想法很好,但是不能动态创建PV,对于PV提供者来说,心智负担较高。当然社区现在也有提供Local Static Provisioner,某种程度上简化了这块的心智负担,但是仍然需要预先规划目录或者分区,略显不足。
笔者以为,理想中的本地磁盘使用方案,应当是按需申请,空间隔离,且自动化生命周期管理。这样才能既方便终端用户使用,也能减少运维支撑,提高效率。这里的关键技术点有三个:
- 按需申请 意味着最好以PVC+StorageClass的模式来提供服务,做到PV动态创建。而要实现这点,容量感知 是关键,因为若调度到空间不足的节点上很明显是不合理的。最好能结合PVC申请的容量+Node上的剩余容量,综合选择最优的节点来做绑定。
- 空间隔离 要确保用户申请的空间大小一定是足额的,不被侵占的。从这里看,单纯的把文件系统的目录用作PV但容量上彼此不隔离显然不合适。
- 自动化生命周期管理 动态Provisioning是强需。
综合以上三点,我们会发现基于 LVM或分区技术+CSI 的实现,当是比较符合上述用户体验的,而TopoLVM就是这样一个项目。
TopoLVM是基于LVM的Kubernetes本地化磁盘方案,以CSI形式提供给用户使用。目前主要支持以下功能:
- 动态Provisioning
- 支持原生数据块卷(Raw Block Volume)
- Volume伸缩
整体架构如下:

值得注意的是,在早期版本,为了能够动态感知节点上的剩余存储容量,TopoLVM设计了个自定义扩展调度器(上图topolvm-scheduler部分),方便在Scheduling阶段为Pod绑定合适的Node。而在Kubernetes 1.21之后,Kubernete已经原生支持了 Storage Capacity Tracking的能力,这块的实现整体就变的优雅很多,topolvm-Scheduler也就不再需要了。
当然,要想认知到TopoLVM的核心原理,除了了解CSI编写规范外,最重要的就是需要了解LVM相关技术。而正是因为通过LVM能够动态创建LV,动态扩缩容,TopoLVM才能支持动态Provisioning相关的能力。
不过,虽然作为开源项目TopoLVM已基本够用,但丰富度略显不足。而博云近期也开源了他们的云原生本地磁盘管理方案Carina,看起来更完善一些。
Carina除了提供基于LVM的方案外,还支持裸盘分区方式,以及IOPS限制等,功能更加丰富。代码组织规范也更贴合云原生社区的方式,整体非常值得一探。
参考链接
- Volume: https://kubernetes.io/docs/concepts/storage/volumes/
- PV: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- Storage Capacity: https://kubernetes.io/docs/concepts/storage/storage-capacity/
- LVM: https://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)
往期推荐
- 聊聊领导力与带团队的那些事
- 聊聊 Kubernetes Pod or Namespace 卡在 Terminating 状态的场景
- 构建高效Presubmit卡点,落地测试左移最佳实践
- 谈谈测试环境管理与实践
- 我们是如何做go系统覆盖率收集的?
- 聊聊Go代码覆盖率技术与最佳实践
TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘的更多相关文章
- iOS应用架构谈 本地持久化方案及动态部署
转载: iOS应用架构谈 本地持久化方案及动态部署 前言 嗯,你们要的大招.跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给 ...
- ssiOS应用架构谈 本地持久化方案及动态部署
本文转载至 http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html ...
- K8S学习笔记之Kubernetes数据持久化方案
在开始介绍k8s持久化存储前,我们有必要了解一下k8s的emptydir和hostpath.configmap以及secret的机制和用途. 0x00 Emptydir EmptyDir是一个空目录, ...
- Unity常见的三种数据本地持久化方案
做游戏的时候常常会有数据配置或者存读档的需求,本文整理了常用的几种解决方案,分别是Unity自带的PlayerPrefs类,XML文件和Json文件. 一. PlayerPrefs 这是Unity自带 ...
- Kubernetes之持久化存储
转载自 https://blog.csdn.net/dkfajsldfsdfsd/article/details/81319735 ConfigMap.Secret.emptyDir.hostPath ...
- Kubernetes 学习(十)Kubernetes 容器持久化存储
0. 前言 最近在学习张磊老师的 深入剖析Kubernetes 系列课程,最近学到了 Kubernetes 容器持久化存储部分 现对这一部分的相关学习和体会做一下整理,内容参考 深入剖析Kuberne ...
- Kubernetes审计日志方案
前言 当前Kubernetes(K8S)已经成为事实上的容器编排标准,大家关注的重点也不再是最新发布的功能.稳定性提升等,正如Kubernetes项目创始人和维护者谈到,Kubernetes已经不再是 ...
- iOS: 数据持久化方案
数据持久化方案(如果总结不到位,或者有误的地方,敬请斧正) 一.功能: 主要是将数据持久化到本地,减少对网络请求的次数,既节省了用户的流量,也增强了App的体验效果. 二.种类: plist存储:使 ...
- [转]App离线本地存储方案
App离线本地存储方案 原文地址:http://ask.dcloud.net.cn/article/166 HTML5+的离线本地存储有如下多种方案:HTML5标准方案:cookie.localsto ...
随机推荐
- Java之万年历
@(文章目录) 二.Java之万年历 2.1 要求 输入年份: 输入月份: 输出某年某月的日历. 2.2 思路 实现从控制台接收年和月,判断是否是闰年(判断是否是闰年:能被4整除但不能被100整除:或 ...
- Go Slice Tricks Cheat Sheet、Go 切片使用小妙招
AppendVector. Copy. Cut. Delete. Delete without preserving order. Cut (GC). Delete (GC). Delete with ...
- OpenHarmony 3.1 Beta版本关键特性解析——HAP包安装实现剖析
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 石磊 随着社会的不断发展,人们逐渐注重更加高效.舒适.便捷.有趣的生活和工作体验. OpenAtom OpenHa ...
- 使用C#制作九九
效果图如下 源码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; usi ...
- gin框架使用【1.Hello World】
package mainimport ( "github.com/gin-gonic/gin")func main() { router := gin.Default() rout ...
- .NET MAUI RC 是完整的 API 并准备好起飞 (GA)
2022年4月12日 微软发布了 .NET Multiplatform App UI (.NET MAUI) 作为候选版本RC ,具体参见 https://devblogs.microsoft.com ...
- Hyperledger Fabric 通道配置文件和容器环境变量详解
摘要 Fabric 网络启动的过程中需要进行大量配置,新学时对各个配置的作用一无所知,这导致我曾在网络出问题时先对配置文件的内容进行排列组合后再祈祷它能在某个时刻顺利运行,因此掌握 fabric 各个 ...
- error: 'xxxxxx' does not have a commit checked out
今天完成了毕业设计的主要功能,想上传到Git上给朋友看一下.以前也没用过git,看了一下视频,现学现卖了就是. 在使用git add命令时提示error: 'xxxxxx' does not have ...
- MySQL left join 引发的惨案
当我用这个进行更改值时,type未控制order表 其他数据被更改 还好备份数据表了(这里就体现了备份的重要性) UPDATE expense_order as a left join ( SELEC ...
- Springboot 整合 MyBatisPlus[详细过程]
Springboot 整合 MyBatisPlus[详细过程] 提要 这里已经将Springboot环境创建好 这里只是整合MyBatis过程 引入Maven依赖 添加MyBatisPlus启动依赖, ...