ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Longhorn RWX 卷 NFS 服务器专用恢复后端(Recovery Backend)设计与实现解析

Longhorn RWX 卷 NFS 服务器专用恢复后端(Recovery Backend)设计与实现解析 云原生存储高可用容器编排【免费下载链接】longhornCloud-Native distributed storage built on and for Kubernetes项目地址https://gitcode.com/gh_mirrors/lo/longhorn点击查看免费下载本篇技术指南以 Longhorn 增强提案 20220727-dedicated-recovery-backend-for-rwx-volume-nfs-server.md 为骨架系统讲解 RWXReadWriteMany卷的 share-manager NFS 服务器在节点故障后如何通过专用的 recovery backend 完成客户端连接信息持久化与锁回收lock reclaim从而实现高可用故障切换。读完本文你将掌握 NFSv4 宽限期grace period机制、nfs-ganesha恢复后端五类操作的语义、ConfigMap 数据格式以及 share-manager 故障切换的完整测试与调优方案。背景与动机为什么 RWX 卷的 NFS 服务器无法可靠故障切换Longhorn 的 RWX 卷依赖一个位于 share-manager pod 内部的 NFS 服务器基于用户态 NFS 服务器nfs-ganesha对外提供ReadWriteMany访问能力。当承载 share-manager pod 的节点宕机时share-manager controller 会在另一个节点上重新创建 share-manager pod并重新挂载attach底层卷。然而在引入恢复后端之前故障切换无法正确工作根本原因有两点缺少合适的恢复后端NFS 服务器重启后客户端NFS client的连接信息client ID、锁、委派 delegation全部丢失无法被重新认领连接信息无法持久化原 NFS 服务器持有的关于每个客户端的状态没有写入任何可跨节点访问的持久化介质。其直接后果是客户端文件系统上的锁无法被正确回收lock reclaim客户端的文件系统操作被中断。该问题对应 Longhorn issue #2293 中“NFS recovery backend based on Kubernetes built-in resource, ConfigMap”的描述。目标与非目标Goals为 Longhorn 实现一个专用的 recovery backend让 NFS 服务器具备故障切换failover能力实现 RWX 卷的高可用。Non-goals不实现 active/active 或 active/passive 的 NFS 服务器双活模式。原因在提案中有明确说明Longhorn 目前仅支持本地文件系统如 ext4、xfs提供服务节点上的任何变更都无法同步到备用节点这直接排除了 active/active 设计当前 Longhorn 架构中创建 engine 进程至少需要一个 replica并通过 iSCSI 前端导出卷active/passive 配置所需的“备用 engine 进程”在现有架构中不可行。架构设计专用恢复后端总览恢复后端的整体架构可以用下图表示图源自增强提案原文┌────────────────────────────────────────────────┐ │ service │ ┌──► │ │ │ longhorn-nfs-recovery-backend │ │ └───────────────────────┬────────────────────────┘ │ │ HTTP API ┌─────────────┴──────────────┐ │ │ │ │ │ endpoint 1 │ endpoint N ┌──────────────────────┐ │ ┌─────────▼────────┐ ┌────────▼─────────┐ │ share-manager pod │ │ │ recovery-backend │ │ recovery-backend │ │ │ │ │ pod │ │ pod │ │ ┌──────────────────┐ │ │ │ │ ... │ │ │ │ nfs server ├─┼─┘ │ │ │ │ │ └──────────────────┘ │ │ │ │ │ │ │ │ │ │ │ └──────────────────────┘ └──────────┬───────┘ └──────────┬───────┘ │ │ │ ┌─────────────┐ │ └───────►│ configMap │◄─────┘ └─────────────┘核心设计要点引入 recovery-backend 服务longhorn-recovery-backend是一个由多个 recovery-backend pod 支撑的 Kubernetes Service被多个 RWX 卷共享以摊薄资源成本。在仓库的 Helm 模板中该 Service 被定义为 ClusterIP 类型端口9503targetPort 为recov-backendselector 匹配标签longhorn.io/recovery-backend: longhorn-recovery-backend参见 chart/templates/services.yamlapiVersion: v1 kind: Service metadata: name: longhorn-recovery-backend spec: type: ClusterIP selector: longhorn.io/recovery-backend: longhorn-recovery-backend ports: - name: recovery-backend port: 9503 targetPort: recov-backend同一 Service 定义也以渲染后的完整清单形式存在于 deploy/longhorn.yaml。Helm values 中还支持为 recovery backend Service 设置流量分布偏好service.recoveryBackend.trafficDistribution可选PreferSameZone、PreferSameNode见 chart/values.yaml。在 nfs-ganesha 中实现一组面向 Longhorn 的专用恢复后端操作详见下一节。数据持久化到 ConfigMap上述操作产生的数据通过 HTTP API 发送到 recovery-backend 服务最终保存到名为recovery-backend-${share-manager-pod-name}的 ConfigMap 中。网络策略隔离当networkPolicies.restrictInternalTraffic开启时Helm 模板会为 recovery-backend pod 生成 NetworkPolicy仅允许带有longhorn.io/component: share-manager标签的 pod 通过 TCP 9503 访问参见 chart/templates/network-policies/recovery-backend-network-policy.yaml对应的示例清单位于 examples/network-policy/recovery-backend-network-policy.yaml。分组件实现细节longhorn-managerNFS 客户端挂载选项从 soft 改为 hardshare-manager pod 与卷的故障切换耗时受集群设置与资源状况影响无法预知。因此原先 NFS 客户端挂载选项soft, timeo30, retrans3被替换为hard。硬挂载hard mount下客户端在 NFS 服务器恢复期间会持续重试请求而不会向应用层返回 I/O 错误从而避免故障切换窗口内的数据丢失——这也是 CHANGELOG 中“NFS client hard mode introduction will further avoid previous potential data loss”所指的改动。share-manager启用 NFSv4 宽限期与主机名标识为了让 NFSv4 客户端在 NFS 服务器故障切换后能够回收锁需要开启宽限期grace period配置如下Lease_Lifetime 60Grace_Period 90同时将NFS_Core_Param.Clustered设置为false。这样 NFS 服务器将使用hostname而不是像node0那样与 share-manager pod 名称相同的名称在恢复后端中创建对应的存储条目唯一的主机名可以避免恢复后端中的命名冲突。因此用户必须保证 Longhorn 系统中每个节点的 hostname 唯一可用hostname命令逐节点核对。nfs-ganesha五类恢复后端操作增强提案为 nfs-ganesha 定义了一套专用恢复后端操作其语义如下操作行为recovery_init创建 ConfigMaprecovery-backend-${share-manager-pod-name}用于存放客户端信息end_grace清理删除该 ConfigMaprecovery_read_clids从 ConfigMap 生成客户端认领reclaim列表add_clid将客户端 key客户端 hostname加入 ConfigMaprm_clid将客户端 key客户端 hostname从 ConfigMap 移除add_revoke_fh撤销委派revoke the delegation这些操作产生的数据通过 HTTP API 发送到 recovery-backend 服务最终持久化到recovery-backend-${share-manager-pod-name}ConfigMap。整个链路可归纳为nfs-ganesha → longhorn-nfs-recovery-backend service → recovery-backend pod → ConfigMap。专用 ConfigMap 格式恢复后端使用的 ConfigMap 命名与结构如下name: recovery-backend-${share-manager-pod-name} labels: longhorn.io/component: nfs-recovery-backend ... annotations: version: 8-bytes random id, e.g. 6SVVI1LE data: 6SVVI1LE: {….json encoded content (containing the client identity information…}提案给出的真实示例取自实际运行环境apiVersion: v1 data: 6SVVI1LE: {31:Linux NFSv4.1 rancher50-worker1:[],31:Linux NFSv4.1 rancher50-worker2:[],31:Linux NFSv4.1 rancher50-worker3:[]} kind: ConfigMap metadata: annotations: version: 6SVVI1LE creationTimestamp: 2022-12-01T01:27:14Z labels: longhorn.io/component: share-manager-configmap longhorn.io/managed-by: longhorn-manager longhorn.io/share-manager: pvc-de201ca5-ec0b-42ea-9501-253a7935fc3e name: recovery-backend-share-manager-pvc-de201ca5-ec0b-42ea-9501-253a7935fc3e namespace: longhorn-system resourceVersion: 47544 uid: 60e29c30-38b8-4986-947b-68384fcbb9ef几个值得注意的细节data 的 key 是 8 字节随机 ID如6SVVI1LE与 annotation 中的version字段一致用于标识客户端信息版本data 的 value 是 JSON 编码内容其中 key 形如31:Linux NFSv4.1 rancher50-worker1即“major/minor 版本号 客户端标识”对应 NFSv4 的 client owner 信息值为空数组在真实实现中用于承载委派/锁相关数据由于恢复后端同时服务多个 RWX 卷ConfigMap 以 share-manager pod 名称作为后缀保证多个卷之间互不干扰CHANGELOG 中还提到一个后续修复[BUG] Fix the share-manager deletion failure if the configmap is not existingCHANGELOG-1.4.0.md说明删除 share-manager 时若 ConfigMap 不存在会导致删除失败该问题已随 v1.4.0 一并修复。使用注意事项与故障切换调优必须满足的前提节点 hostname 必须全局唯一由于 NFS 服务器使用节点 hostname 在恢复后端中创建存储条目重复的 hostname 会导致命名冲突与锁回收错乱。缩短故障切换时间的可选手段确保 DNS 高可用集群中部署多个 coredns pod保证 recovery backend 始终可被解析访问调低 NFS 宽限期参数Grace_Period与Lease_Lifetime默认分别为 90 秒和 60 秒。可将二者调小以提前结束宽限期但这是以牺牲安全性为代价的——宽限期过早结束意味着尚未认领完成的锁可能被判定为过期调低 kubelet 的节点监控参数减小node-monitor-period和node-monitor-grace-period让无响应节点更快被标记为NotReady从而加速 NFS 服务器的故障切换流程。已知限制与风险原 share-manager pod 不可用时无法立即新建替代 pod客户端对 RWX 卷的 I/O 会一直挂起hang直到新的 share-manager pod 在其他节点成功创建。90 秒宽限期内锁回收失败若锁未能在宽限期内被认领这些锁将被丢弃并向客户端返回 I/O 错误客户端随后会重新建立新锁。应用需要自行处理这类 I/O 错误但并非所有应用都能妥善处理 I/O 错误可能导致 I/O 操作失败与数据丢失进而产生数据一致性问题。DNS 服务故障share-manager pod 内的 nfs-ganesha 通过服务 IPlonghorn-recovery-backendservice与恢复后端通信一旦 DNS 故障share-manager 将无法与longhorn-nfs-recovery-backend通信因此强烈建议保障 DNS 服务的高可用性。测试计划如何验证故障切换能力提案提供了三组可复现的验证方案可作为 RWX 高可用能力的验收标准。测试环境搭建使用 3 个 worker 节点的 Longhorn 集群node-1 上挂载 1 个 RWO 卷node-2 上挂载 2 个 RWO 卷node-3 上挂载 3 个 RWO 卷。测试 1多客户端并发写 节点宕机在每个 worker 节点的应用 pod 中分别创建一个 RWX 卷并执行以下命令进行持锁写入( exec 7/data/testfile-${i}; flock -x 7; while date | dd convfsync 7 ; do sleep 1; done )其中${i}为节点编号。随后关闭 share-manager 所在的节点待 share-manager pod 在其他节点重建后验证客户端侧对 RWX 卷的 I/O 会挂起直到替代 share-manager pod 在其他节点成功创建宽限期内服务器以NFS4ERR_GRACE错误拒绝 READ、WRITE 操作以及非认领non-reclaim的加锁请求即其他 LOCK 和 OPEN 操作客户端在故障切换后可以继续工作且不出现 I/O 错误锁回收过程能在 90 秒宽限期结束前完成若锁未能在宽限期内回收锁被丢弃并向客户端返回 I/O 错误客户端重新建立新锁。测试 2DaemonSet 部署 禁用自动删除工作负载 pod将 examples/rwx/rwx-nginx-deployment.yaml 中的 Deployment 改为 DaemonSet并禁用Automatically Delete Workload Pod when The Volume Is Detached Unexpectedly设置然后以 RWX 卷部署该 DaemonSet。关闭 share-manager 所在节点后验证其他活跃客户端在故障切换后不应遇到 stale handle陈旧句柄错误锁回收能在 90 秒宽限期前完成。测试 3单文件多客户端字节范围锁每个应用 pod 中的客户端通过 byte-range file locking可参考随提案提供的range_locking.c示例锁定同一文件的不同字节范围并持续向文件写入数据。关闭 share-manager 所在节点后验证客户端在服务器故障切换后继续任务无 I/O 错误或 stale handle 错误锁回收能在 90 秒宽限期前完成。相关参考关联增强提案20220727-dedicated-recovery-backend-for-rwx-volume-nfs-server.mdRWX 卷示例清单examples/rwx/rwx-nginx-deployment.yamlRecovery backend Service 定义chart/templates/services.yaml、deploy/longhorn.yamlRecovery backend 网络策略chart/templates/network-policies/recovery-backend-network-policy.yaml、examples/network-policy/recovery-backend-network-policy.yaml引入本功能的版本记录CHANGELOG-1.4.0.md注文中Grace_Period/Lease_Lifetime调优、NFSv4 协议细节、客户端锁保留所需的 NFS 服务器集群设计可进一步参考 NFSv4 协议规范RFC 7530及 SUSE 知识库中关于 NFS Ganesha 故障切换的相关文档见增强提案原文的 Reference 一节本指南不再展开外部链接。赞分享云原生存储高可用容器编排【免费下载链接】longhornCloud-Native distributed storage built on and for Kubernetes项目地址https://gitcode.com/gh_mirrors/lo/longhorn点击查看免费下载相关推荐Longhorn RWX 卷 NFS 服务器快速故障切换Fast Failover机制详解Longhorn RWX 卷 NFS 服务器快速故障切换Fast Failover机制详解 本篇技术指南以 Longhorn 增强提案 enhancemen云原生存储高可用容器编排Longhorn RWX 卷自动在线扩容share-manager FilesystemResize RPC 的设计与实现Longhorn RWX 卷自动在线扩容share manager FilesystemResize RPC 的设计与实现 本文以 Longhorn 增强提案云原生存储高可用容器编排Longhorn RWX 卷支持基于 Share Manager 与 NFS 的多节点读写架构全解析Longhorn RWX 卷支持基于 Share Manager 与 NFS 的多节点读写架构全解析 导读 本文基于 Longhorn 官方增强设计文档《RW云原生存储高可用容器编排上一篇终极指南使用UniTask实现Unity游戏存档的自动备份系统下一篇react-app-rewired与GraphQL Subscriptions集成创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表