首页/新闻资讯/正文详情

Rook 托管 PodDisruptionBudget:用 Ceph 故障域感知的 PDB 编排实现安全节点排水与滚动升级

发布时间:2026/9/23 1:39:40 来源:云帆数科 栏目:资讯中心
Rook 托管 PodDisruptionBudget:用 Ceph 故障域感知的 PDB 编排实现安全节点排水与滚动升级
Rook 托管 PodDisruptionBudget用 Ceph 故障域感知的 PDB 编排实现安全节点排水与滚动升级【免费下载链接】rookStorage Orchestration for Kubernetes项目地址: https://gitcode.com/gh_mirrors/roo/rook导读本文围绕 Rook 设计文档 ceph-managed-disruptionbudgets.md 展开系统讲解 Rook Operator 如何通过托管managedPodDisruptionBudget 处理 Kubernetes 节点排水node drain与滚动升级场景下的数据可用性问题。你将掌握Rook 为 OSD 设计的“默认 PDB 故障域级阻塞 PDB”动态切换机制、节点排水检测原理、noout防迁移策略以及 Monitor、MGR、MDS、RGW、rbd-mirror 等无状态守护进程使用的静态 PDB 策略并学会通过disruptionManagement配置项在 CephCluster CR 中启用与调优该能力。背景为什么 OSD 不适合一个朴素的 PodDisruptionBudgetKubernetes 的 PodDisruptionBudgetPDB通过maxUnavailable或minAvailable限制一次允许中断的 Pod 数量是 eviction API 的前置校验。然而 Ceph OSD 有其特殊性Ceph 容忍单个故障域内中断的能力取决于整个集群的健康状态。设计文档明确指出即使升级代理每次只排水一个节点Ceph 也必须在所有 PG 不再处于undersized状态后才能继续排放下一个节点见 ceph-managed-disruptionbudgets.md。这意味着静态地允许“每节点 1 个 OSD 中断”可能导致多个故障域同时丢数据静态地禁止一切中断又无法完成节点滚动升级中断的安全边界应当是故障域failure domain而非单个节点。因此 Rook 提出了一套随集群健康状态动态变化的 OSD PDB 管理方案这也是该设计文档的核心内容。故障域如何确定OSD PDB 的故障域由任何 Ceph RADOS 池所强制的最低故障域层级决定。设计文档给出的例子是集群中有bigrbdpoolCRUSH rule 强制rack层级和.mgrCRUSH rule 强制host层级两个池则 PDB 故障域最终取host见 ceph-managed-disruptionbudgets.md。在源码实现中这一逻辑位于 pools.go 的getMinimumFailureDomain控制器遍历集群中的全部 CephBlockPool、CephFilesystemmetadata pool 与 data pools以及 CephObjectStoremetadata pool 与 data pool的PoolSpec.FailureDomain在所有池的 CRUSH 层级中取“最低/最细粒度”的一个作为 PDB 故障域类型。该文件同时将poolCount返回给协调流程——如果集群中一个池都没有poolCount 1则直接跳过 OSD PDB 协调见 reconcile.go因为此时没有数据可保护。两种 OSD PDBDefault 与 Blocking设计文档将 OSD PDB 划分为两类见 ceph-managed-disruptionbudgets.mdDefault PDB默认 PDB名称固定为rook-ceph-osd通过maxUnavailable1允许任意单一故障域内有一个健康 OSD 下线如果集群中已有 OSD 因非排水原因如硬盘故障下线但 PG 仍activeclean这些已下线 OSD 会通过 label match expression 被排除出 PDB避免阻塞其他健康 OSD 的排水。Blocking PDB阻塞 PDB命名格式为rook-ceph-osd-failureDomainType-FailureDomainName例如rook-ceph-osd-zone-zone-a创建于整个故障域维度上maxUnavailable0彻底禁止该故障域内任何 OSD Pod 被驱逐。设计文档描述了整体工作流一开始为所有 OSD 创建 Default PDB当用户排水某节点导致 OSD 下线后Rook 通过该 OSD Deployment 的标签确定其故障域为其余所有故障域创建 Blocking PDBmaxUnavailable0并删除 Default PDB——这样就把“同时多个故障域有 OSD 下线”的可能性彻底堵死。待被排水的 OSD 恢复且所有 PG 回到activeclean集群自愈完成后重新创建 Default PDB 并删除各阻塞 PDB。源码中的动态切换实现上述切换逻辑在 osd.go 的reconcilePDBsForOSDs中实现其核心是一个状态机依据两个信号推进OSD 是否下线osdDown与PG 是否健康pgClean由cephclient.IsClusterClean结合PGHealthyRegex判断OSD 状态PG 状态行为全部在线activeclean重置 PDB 状态resetPDBConfig即删除阻塞 PDB、恢复默认 PDB有下线activeclean无节点排水事件时把下线 OSD ID 放入excludeOSDs并重置状态若检测到节点排水先等待 60 秒再读取准确的 PG 状态见下文有下线不健康记录“正在排水的故障域”到状态 ConfigMap随后进入 active drain 处理为其他故障域建阻塞 PDB、删除默认 PDB全部在线不健康若状态 ConfigMap 中已存在排水中的故障域则等待 PG 从上次排水事件中恢复no-op关键的“正在排水故障域”状态被持久化在名为rook-ceph-pdbstatemap的 ConfigMap 中见 reconcile.go 与 osd.go 的initializePDBState。ConfigMap 中记录draining-failure-domain当前排水中的故障域、draining-failure-domain-duration排水开始时间戳、set-no-out是否已设置 noout等字段保证协调中断后状态不丢失。切换动作由两个函数执行osd.gohandleActiveDrains对除排水故障域外的所有故障域调用createBlockingPDBForOSD对排水中的故障域调用deleteBlockingPDBForOSD最后deleteDefaultPDBforOSD。此时排水故障域内的 OSD 全部可以安全下线handleInactiveDrains调用createDefaultPDBforOSD可携带excludeOSDs并为所有故障域删除阻塞 PDB。阻塞 PDB 的 label selector 使用osd.TopologyLocationLabel模板生成的topology-location-failureDomainType: failureDomainName匹配标签见 osd.goPDB 名称通过k8sutil.TruncateNodeName截断以保证符合 Kubernetes 名称长度限制osd.go。所有 PDB 均以 CephCluster 为 OwnerReference删除集群时随之清理。节点排水的检测不是靠 API而是靠“不可调度”设计文档强调排水是客户端侧操作难以直接检测。客户端如kubectl drain会先 cordon 节点标记为不可调度然后持续尝试驱逐该节点上的所有 Pod直到成功为止。因此 Rook 采用的判定准则是如果 OSD 本该运行的节点被标记为unschedulableOperator 就认为该节点正在排水见 ceph-managed-disruptionbudgets.md。源码中getOSDFailureDomainsosd.go完整实现了这一判定列出命名空间内所有app: rook-ceph-osd的 Deployment通过topology-location-failureDomain标签读取每个 OSD 所属的故障域对ReadyReplicas 1的 OSD用osd metadata查询其宿主机名再调用hasOSDNodeDrainedosd.go若节点对象不存在或node.Spec.Unschedulable true即判定为节点排水汇总三类结果全部故障域allFailureDomains、检测到排水的故障域nodeDrainFailureDomains、有 OSD 下线的故障域osdDownFailureDomains以及下线的 OSD ID 列表downOSDs。值得注意的实现细节setPDBConfig在同时存在“排水故障域”与“OSD 下线故障域”时排水故障域优先级更高且只有排水事件才会触发noout设置setNoOut true见 osd.go。此外处于替换流程中的 OSD携带ceph.rook.io/replace-in-progress注解会被shouldIgnoreOSD跳过避免整个替换窗口可能持续数天冻结集群级维护osd.go这一行为有单元测试TestGetOSDFailureDomainsSkipsReplacementOSD覆盖见 osd_test.go。设计文档中的示例场景设计文档给出了一个跨三个 zone 的完整推演见 ceph-managed-disruptionbudgets.mdZone x Node a: osd.0, osd.1 Zone y Node b: osd.2, osd.3 Zone z Node c: osd.4, osd.5初始状态为所有 OSD 创建默认 PDBrook-ceph-osdmaxUnavailable1管理员排水Node a进行维护Rook Operator 发现Node a上的osd.0下线为Zone y创建阻塞 PDBrook-ceph-osd-zone-zone-y为Zone z创建rook-ceph-osd-zone-zone-z删除覆盖所有 OSD 的默认 PDB现在Zone x内剩余 OSD 允许被排水其数据仍被 zone y/z 的副本保护当Node-a回归、OSD 全部运行且 PG 全部activeclean时恢复默认 PDBrook-ceph-osdmaxUnavailable1删除两个阻塞 PDB。设计文档还指出类似 OpenShift Machine Config Operator 这类基于 SIG cluster lifecycle 生态、会自动执行节点滚动升级的 Operator 正是该机制的典型受益者基于 cluster-api 的 Kubernetes 部署同样适用该机制也能防止人工误排水破坏存储见 ceph-managed-disruptionbudgets.md。防止不必要的迁移noout 与 OSDMaintenanceTimeout设计文档中的另一个关键点如果节点因计划维护而停机我们不希望被排水 OSD 的数据被迁移到其他 OSD因为维护结束后 OSD 会回归并快速恢复。为此Rook Operator 会为被排水节点的故障域设置 Ceph 的noout标志见 ceph-managed-disruptionbudgets.mdnoout在OSDMaintenanceTimeout到期后被移除该值默认为 30 分钟可在 CephCluster CR 中配置如果 OSD 下线但没有节点被排水例如纯磁盘故障不设置noout。源码中updateNooutosd.go通过osd dump获取 CRUSH map再对指定故障域执行UpdateFlagOnCrushUnit设置/清除noout。它用状态 ConfigMap 中记录的noout-last-set-at时间戳判断超时time.Since(nooutSetTime) r.maintenanceTimeout时移除 noout。maintenanceTimeout来源于 CR 的disruptionManagement.osdMaintenanceTimeout未配置时回退到常量DefaultMaintenanceTimeout 30 * time.Minute见 osd.go 与 reconcile.go。协调的节奏requeue 机制OSD PDB 协调结束后requeuePDBControllerosd.go决定是否立即再次协调默认 PDB 不存在说明正处于阻塞排水状态15 秒后 requeue默认 PDB 的DisruptionsAllowed 0或 PDB 使用了排除表达式有 OSD 下线且 PG 不干净30 秒后 requeue其余情况协调完成无需 requeue。这一节奏保证了“节点回归 → 集群恢复 → 解除阻塞”的闭环能被及时推进。另外控制器通过add.go注册了对 CephCluster、PodDisruptionBudget 以及 CephBlockPool / CephFilesystem / CephObjectStore 等对象的 watch见 add.go任何相关资源变化都会触发重新协调。非排水原因导致的 OSD 下线从 PDB 中排除设计文档专门说明了 OSD 因其他原因如硬盘故障下线时的处理如果尽管 OSD 下线但所有 PG 仍然activecleanRook 会将这些下线 OSD 从默认 PDB 的 selector 中排除。设计文档给出的示例假设 OSD 1、3、5 下线maxUnavailable: 1 selector: matchExpressions: - key: app operator: In values: [rook-ceph-osd] - key: osd operator: NotIn values: [1, 3, 5]这样其他健康 OSD 依然可以被排水见 ceph-managed-disruptionbudgets.md。源码createDefaultPDBforOSDosd.go实现了完全一致的 selector 构造始终匹配app In [rook-ceph-osd]当excludeOSDs非空时追加osd NotIn [...]。需要留意的一个细节当检测到节点排水事件且 OSD 刚下线时reconcilePDBsForOSDs会先等待 60 秒比较状态 ConfigMap 中draining-failure-domain-duration时间戳再决定是否排除因为排水过程中 OSD Pod 会被快速驱逐过早读取 PG 状态可能得到不准确的结论osd.go。Monitor、MGR、MDS、RGW、rbd-mirror静态 PDB与 OSD 不同Monitor、Manager、MDS、RGW、rbd-mirror 这些守护进程没有严格的故障域约束也不属于逻辑分组因此一个静态 PDB 就足够了见 ceph-managed-disruptionbudgets.md每个 PDB 由对应控制器创建并拥有owner仅当 CRD 中 Pod 数量变化时才更新设计文档举例三 Monitor 部署中PDB 使用与 Deployment 相同的 labelSelectormaxUnavailable1当 Monitor 数量增加到 5生产环境的谨慎选择时替换为maxUnavailable2的 PDB。源码中static_pdb.go的reconcileStaticPDBstatic_pdb.go只做“不存在则创建、存在则不动”的幂等操作pools.go中RGWPDB 命名为rook-ceph-rgw-storeNameselector 匹配rgw: storeNameminAvailable 实例数 - 1当minAvailable 1时删除陈旧的 PDBpools.goMDSPDB 命名为rook-ceph-mds-fsNameselector 匹配rook_file_system: fsNameminAvailable activeCount - 1若启用了activeStandby则再加 1pools.go。如何启用与配置disruptionManagement该功能的开关位于 CephCluster CR 的spec.disruptionManagement字段类型定义见 types.go字段类型默认值说明managePodBudgetsboolfalse设为true后Operator 为 OSD、Mon、RGW、MDS 创建并托管 PDBOSD PDB 按上文策略动态管理osdMaintenanceTimeoutduration分钟30排水中的故障域在默认 DOWN/OUT 间隔之外额外保持noout的分钟数仅在managePodBudgetstrue时生效pgHealthyRegexstring^active(\(clean\|deep\|scrubbing\|snaptrim\|snaptrim_wait))$判断哪些 PG 状态视为健康的正则表达式pgHealthCheckTimeoutduration-已废弃不再实现manageMachineDisruptionBudgetsbool-已废弃machineDisruptionBudgetNamespacestring-已废弃deploy/examples/cluster.yaml中给出了开箱即用的示例配置见 cluster.yamldisruptionManagement: # If true, the operator will create and manage PodDisruptionBudgets for OSD, Mon, RGW, and MDS daemons. OSD PDBs are managed dynamically # via the strategy outlined in the design. The operator will block eviction of OSDs by default and unblock them safely when drains are detected. managePodBudgets: true # A duration in minutes that determines how long an entire failureDomain like region/zone/host will be held in noout (in addition to the # default DOWN/OUT interval) when it is draining. This is only relevant when managePodBudgets is true. The default value is 30 minutes. osdMaintenanceTimeout: 30启用managePodBudgets后你会观察到命名空间中动态出现的 PDB 资源kubectl -n rook-ceph get pdb # 无排水时rook-ceph-osdmaxUnavailable1 各 Mon/RGW/MDS 静态 PDB # 排水进行时rook-ceph-osd-fdType-fdName 系列阻塞 PDBmaxUnavailable0CRD 完整字段说明可参考 ceph-cluster-crd.md 与 specification.md。协调入口reconcile()在managePodBudgetsfalse时直接返回、不执行任何 PDB 管理reconcile.go因此该功能是完全可选、按集群启用的。工作流程总结综合设计文档与源码Rook 托管 PDB 的完整闭环可概括为初始化reconcile()读取 CR 配置确定maintenanceTimeout经processPools计算最小故障域常态所有 OSD 共享默认 PDBrook-ceph-osdmaxUnavailable1允许单一故障域内一个 OSD 中断检测排水OSD 下线后查询其节点若节点unschedulable判定为排水将故障域写入rook-ceph-pdbstatemapConfigMap阻塞为其余故障域创建maxUnavailable0的阻塞 PDB删除默认 PDB仅允许排水故障域内 OSD 被驱逐保护数据为排水故障域设置noout避免数据迁移OSDMaintenanceTimeout默认 30 分钟后自动移除恢复OSD 回归、PGactiveclean后恢复默认 PDB、删除阻塞 PDB并根据DisruptionsAllowed决定 requeue 节奏兜底非排水原因的下线 OSD 通过osd NotIn排除表达式被移出默认 PDB不影响其他健康 OSD 的排水。进一步阅读设计文档原文ceph-managed-disruptionbudgets.mdOSD PDB 协调核心实现osd.go 与 reconcile.go故障域计算与 RGW/MDS 静态 PDBpools.go 与 static_pdb.go控制器注册与 Watch 配置add.goCRD 配置类型定义types.go配置示例cluster.yamlCRD 字段说明ceph-cluster-crd.md单元测试含替换 OSD 跳过逻辑osd_test.go【免费下载链接】rookStorage Orchestration for Kubernetes项目地址: https://gitcode.com/gh_mirrors/roo/rook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

PaddleHub 安装指南:环境依赖、pip 安装与网络/离线使用说明
PaddleHub 安装指南:环境依赖、pip 安装与网络/离线使用说明

PaddleHub 安装指南:环境依赖、pip 安装与网络/离线使用说明 【免费下载链接】PaddleFormers PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle. 项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFor… · 2026/9/23 1:39:34

Perso-Arabic 脚本归一化实验复现:Sindhi→English NMTMediumV1 配方详解(OpenNMT-tf 实战)
Perso-Arabic 脚本归一化实验复现:Sindhi→English NMTMediumV1 配方详解(OpenNMT-tf 实战)

Perso-Arabic 脚本归一化实验复现:Sindhi→English NMTMediumV1 配方详解(OpenNMT-tf 实战) 【免费下载链接】google-research Google Research 项目地址: https://gitcode.com/gh_mirrors/go/google-research 本文面向需要复现 Graph… · 2026/9/23 1:39:34

理财一周报新手避坑指南:环境配置与数据流对比
理财一周报新手避坑指南:环境配置与数据流对比

理财一周报新手避坑指南:环境配置与数据流对比 配置环境就卡半天,是不是让你怀疑人生?很多新手在接触【理财一周报】相关技术栈时,往往不是败在逻辑,而是死在环境依赖和版本冲突上。今天咱们不整虚的,直接拆解这个场景下的技术选型,帮你从根源上解决报… · 2026/9/23 1:39:34

道路坑洼识别CNN二分类实战:从数据预处理到PyQt5界面部署
道路坑洼识别CNN二分类实战:从数据预处理到PyQt5界面部署

简介:这是一套基于PyTorch与CNN的道路坑洼识别方案,配套完整数据集,面向深度学习初学者及道路病害检测方向的动手实践者。压缩包共252个文件,其中246张JPG图片覆盖正常与坑洼两类样本,并包含旋转、填充灰边等增强后的图… · 2026/9/23 2:42:42

泉州防水补漏上门电话|本地师傅勘查漏水位置|欧米到家服务电话
泉州防水补漏上门电话|本地师傅勘查漏水位置|欧米到家服务电话

📝 文章简介泉州住宅、商铺和办公场所常见的漏水问题,包括卫生间渗水、阳台积水、屋顶漏水、外墙返潮、厨房墙面发霉、窗边渗水、地下室潮湿等。欧米到家提供泉州多区域防水补漏、漏水点排查、局部修补、卫浴及水电相关维修服务。遇到雨后渗水、墙顶水印… · 2026/9/23 2:42:29

Self-hosted LiveSync 贡献指南:从环境搭建、代码验证到翻译与发布的全流程实战
Self-hosted LiveSync 贡献指南:从环境搭建、代码验证到翻译与发布的全流程实战

数据同步 【免费下载链接】obsidian-livesync 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-livesync 点击查看 免费下载 本篇指南基于 obsidian-livesync 仓库的 CONTRIBUTING.md 与 devs.md 编写,系统讲解如何为 Self-hosted LiveSync&… · 2026/9/23 2:42:29

自研还是采购?一套可复制的BI选型决策框架与成本模型
自研还是采购?一套可复制的BI选型决策框架与成本模型

聊到BI选型,团队里几乎绕不开同一个争论:到底是自研一套BI,还是直接采购成熟产品。这个问题的答案远不是一句“看预算”就能打发的。过去几年我既带人从零搭过BI平台,也主导过Power BI、FineBI这类成熟产品的落地,两种… · 2026/9/23 2:42:29

Figma vs 开源设计工具:Penpot与OpenPencil迁移实战与选型指南
Figma vs 开源设计工具:Penpot与OpenPencil迁移实战与选型指南

1. 设计工具选型的十字路口:为什么现在讨论这个话题设计工具的选择从来都不是一个纯粹的技术问题。过去几年里,Figma几乎成了UI/UX设计领域的默认答案——协作流畅、插件生态丰富、社区资源庞大,团队里只要有人甩出一个链接,所有人… · 2026/9/23 2:42:29

AI做PPT返工率太高?实测五款工具后,我总结了低返工工作流
AI做PPT返工率太高?实测五款工具后,我总结了低返工工作流

1. 为什么“返工”成了AI做PPT的隐形天花板我大概从2023年上半年开始,陆续试了市面上能叫得出名字的AI生成PPT工具,少说也有十几款。一开始确实惊艳——输入一句话,几十秒后一份带配图、有版式、甚至带点动画的PPT就出来了。但用得越多&#… · 2026/9/23 2:42:29

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码