首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
OpenShift 存储实践:通过 hostPath 手动挂载 GlusterFS 让 NGINX 使用分布式存储(or/origin 仓库 nginx_gluster_host 示例详解)
📅 2026/9/25 3:33:50
✍️ 爱科研究院
👁 阅读 3,247
测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载本文基于 or/origin 仓库OpenShift 相关示例与测试套件中examples/storage-examples/gluster-examples/nginx_gluster_host目录的官方示例文档讲解如何在 RHEL Atomic Host 上手动建立 GlusterFS 的 fuse 挂载点并通过 Pod 的hostPath卷将其映射进 NGINX 容器实现容器直接读写 GlusterFS 分布式存储。读完本文你可以完整复现该示例的每一步命令、理解volumeMounts/volumes各字段语义并明确该方案的适用边界——它是理解 Gluster 与 Atomic Host 关系的基础构建块也是 glusterfs 卷插件暂不可用时的绕行手段。一、示例定位GlusterFS 系列四个示例中的第一个在仓库的存储示例体系中storage-examples 总入口将场景分为 HostPath 与 GlusterFS 两大类。GlusterFS 系列主文档把整个系列组织成递进的四个示例示例目录存储接入方式Example 1本文nginx_gluster_host在 RHEL Atomic Host 上手动创建的 GlusterFS fuse 挂载映射为 Pod 的hostPathExample 2nginx_gluster_plugin通过 OpenShift 内置glusterfs 卷插件在 Pod 定义中自动挂载分布式存储无需 PV/PVCExample 3nginx_gluster_pvc结合PersistentVolume / PersistentVolumeClaim与 glusterfs 插件Example 4nginx_template用 OpenShiftTemplate一键部署 NGINX 应用原文档明确给出的定位说明值得强调这种方法在特定场景下可能有价值但不推荐绕过 OpenShift 内置的卷插件因为那样要求所有节点都存在这个手动挂载。它只是一个构建块示例用于展示 Gluster 与 Atomic Host 之间的关系如果 glusterfs 插件暂时不可用或出现故障它可以作为绕行workaround方案。如果只关心卷插件场景可以直接跳到 Example 2。也就是说本文示例的核心价值在于把分布式存储如何落到节点本地路径这一链路拆开来看Gluster 集群 → 节点上的 fuse 挂载目录 → 容器内目录。理解了这条链路后续 Example 2/3 中插件如何替你在每个节点自动做同样的事就一目了然。1.1 环境拓扑该系列示例的运行环境由 系列主文档定义为 4 台主机2 台 GlusterFS 节点组成 Gluster 集群gluster1.rhs与gluster2.rhs2 台运行 OpenShift 与 GlusterFS 客户端的 RHEL7 Atomic Hostose1.rhsmaster与ose2.rhsnode示例使用的 Gluster 卷信息如下摘自系列主文档属性myVol1myVol2状态StartedStartedBrick 数量22Brick1gluster1.rhs:/mnt/brick1/myVol1gluster1.rhs:/mnt/brick2/myVol2Brick2gluster2.rhs:/mnt/brick1/myVol1gluster2.rhs:/mnt/brick2/myVol2本示例使用其中的myVol1来演示一个使用分布式存储的简单 Pod。1.2 前提假设系列文档列出的 5 条前提假设必须全部满足否则示例无法复现OpenShift Enterprise v3 安装在至少两台运行 RHEL 7 Atomic Host 的节点上存在一个处于活跃状态、且 Atomic Host 可以访问的 GlusterFS 集群所有必要的安装后配置均已完成Gluster 与 OpenShift 集群均可用所有 Atomic Host全部节点已安装并启用glusterfs-client且modeprobe fuse已生效对 Docker/容器与 Kubernetes 有基本理解。此外系列文档还要求 OpenShift 已按快速安装指南装好并可从控制台 GUIhttps://master-host:8443/console登录Gluster 集群已通过与各 Atomic 节点的连通性测试。二、步骤一准备节点上的 Gluster 挂载目录前提条件满足后Gluster 卷已经在 Atomic RHEL 主机上安装并挂载本例中为myVol1与myVol2。我们要使用myVol1节点上存在一个指向 GlusterFS 服务器的 fuse 挂载/mnt/myVol1它随后会被用作 Pod 定义中的hostPath。登录 Atomic Host进入已挂载的 Gluster 卷目录并创建本示例专用的子目录cd /mnt/myVol1 mkdir glusterfs-nginx-atomichost-mount cd glusterfs-nginx-atomichost-mount ls原文档记录的输出示例显示该 Gluster 卷下已有一些来自其他实验的目录[rootose2 myVol1]# ls glusterfs-nginx glusterfs-nginx-pvc test1 test3 glusterfs-nginx-atomichost-mount helloworld.html test2注意/mnt/myVol1本身就是 fuse 挂载点在这里执行mkdir实际是在分布式存储上创建目录任何挂载了同一卷的客户端包括两台 Gluster 服务器都能立刻看到它。三、步骤二编写使用 hostPath 的 Pod 配置文件仓库中对应的清单文件是 local-nginx-gluster-pod.json。这是一个标准的 Kubernetes v1 Pod 对象容器镜像为fedora/nginx完整内容如下{ apiVersion: v1, id: local-nginx-to-gluster, kind: Pod, metadata: { name: local-nginx-to-gluster }, spec: { containers: [ { name: local-nginx-to-gluster, image: fedora/nginx, volumeMounts: [ { mountPath: /usr/share/nginx/html/test, name: localvol } ] } ], volumes: [ { name: localvol, hostPath: { path: /mnt/gvol1/glusterfs-nginx-atomichost-mount } } ] } }一处需要注意的差异文档正文叙述中使用的是/mnt/myVol1/glusterfs-nginx-atomichost-mount而仓库中实际提交的 JSON 文件里hostPath.path写的是/mnt/gvol1/glusterfs-nginx-atomichost-mount。复现时应以节点上真实存在的 fuse 挂载路径为准保证volumes[].hostPath.path指向步骤一中创建过glusterfs-nginx-atomichost-mount目录的那个挂载点。3.1 volumeMounts 字段逐项说明继承原文档mountPath: /usr/share/nginx/html/test 容器内的本地目录将映射到实际的存储路径 从容器视角看该路径会被创建出来 name: localvol 给挂载卷起的名字必须与 volumes 段中的某个卷 name 一致3.2 volumes 字段逐项说明继承原文档name: localvol 与 volumeMounts 中的 name: localvol 对应原文档注释中写作 nginxglustervol实际清单以 localvol 为准 hostPath: 卷插件可接受的值之一表示使用宿主机节点上的一个本地路径 path: 宿主机路径 实际要映射到节点上的路径本例映射到已存在的 glusterfs fuse 挂载目录例如 /mnt/myVol1/glusterfs-nginx-atomichost-mount关键点在于hostPath本身只是一个把节点本地目录挂进容器的机制它并不知道也不关心该目录背后是不是 Gluster。正是节点上/mnt/myVol1这个 fuse 挂载把本地目录变成了分布式存储的入口——两个组件组合起来才构成容器读写 GlusterFS的完整链路。四、步骤三部署 Pod 并确认运行状态使用oc客户端部署oc create -f local-nginx-gluster-pod.json原文档记录的实际执行结果id字段与metadata.name并存时的输出示例[rootose1 nginx_gluster_host]# oc create -f local-nginx-gluster-pod.json pods/local-nginx等待数分钟时间可能有差异后检查 Pod 状态oc get pods[rootose1 nginx_gluster_host]# oc get pods NAME READY STATUS RESTARTS AGE local-nginx 1/1 Running 0 3h local-nginx-to-gluster 1/1 Running 0 33s随后打开 OpenShift Console Web 界面https://your master host:8443/console文档环境使用admin/admin登录应能看到运行中的 Pod。务必记录 Pod 详情页中的 IP on node 与 Node 两个值——它们告诉你 NGINX 应用运行在哪台节点的哪个 IP 上后续写入验证与curl访问都依赖这些信息。五、步骤四从任意一端写入 helloworld.html验证数据确实落在 GlusterFS 上这是本示例最能体现分布式的一步。原文档给出两个等价的入口入口 ASSH 到承载容器的 Atomic Host直接往 fuse 挂载路径写文件echo This is being served from GlusterFS using manually created fuse mount to Gluster from the Atomic RHEL host using hostPath in the configuration...GlusterFS \ /mnt/myVol1/glusterfs-nginx-atomichost-mount/helloworld.html入口 BSSH 到任意一台 Gluster 集群服务器从 Gluster 侧的挂载点写同一文件因为目录在 Gluster 卷上从任何挂载了该卷的位置创建文件都可以[rootgluster1 glusterfs-nginx-atomichost-mount]# ls helloworld.html两个入口殊途同归无论写在哪一端文件最终都落在 Gluster 卷myVol1上并被所有挂载点同步可见。这正是后续容器内能立刻读到该文件的原因。六、步骤五进入容器验证挂载并用 curl 验证页面可访问6.1 进入容器SSH 到容器运行的 Atomic HostNode 信息来自 OpenShift Console用docker ps找到容器 IDdocker ps[rootose2 myVol1]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8dda35c5f9ad fedora/nginx /usr/sbin/nginx 6 minutes ago Up 6 minutes k8s_local-nginx-to-gluster.38f555f1_local-nginx-to-gluster_default_ca995463-45e8-11e5-ae70-52540008f001_2135479e然后exec进容器 shelldocker exec -it 8dda35c5f9ad bash6.2 容器内核对挂载内容bash-4.3# cd /usr/share/nginx/html/test/ bash-4.3# ls helloworld.html与此同时回到 Atomic Host 查看同一目录树可以看到宿主机侧与容器侧视图完全一致[rootose2 /]# cd /mnt/myVol1 [rootose2 myVol1]# ls glusterfs-nginx-atomichost-mount [rootose2 myVol1]# cd glusterfs-nginx-atomichost-mount/ [rootose2 glusterfs-nginx-atomichost-mount]# ls helloworld.html原文档的两点观察值得复述其一进入容器内 NGINX 的html/test目录时能看到整个 GlusterFS 存储挂载的内容包括glusterfs-nginx-atomichost-mount目录本身其二在其中能看到刚创建的helloworld.html。这证明容器内路径/usr/share/nginx/html/test与 Gluster 卷上的目录是同一份数据。6.3 curl 访问验证在容器内直接向 Pod IP 发起请求IP 来自 Console 中记录的 IP on node原文档示例为10.1.0.9curl http://10.1.0.9/test/helloworld.htmlbash-4.3# curl http://10.1.0.9/test/helloworld.html This is being served from GlusterFS using manually created fuse mount to Gluster from the Atomic RHEL host using hostPath in the configuration...GlusterFS返回内容正是步骤四写入的文本——NGINX 正在通过hostPath→ fuse 挂载 → GlusterFS 这条完整链路对外提供分布式存储上的网页示例闭环完成。七、原理剖析为什么这条链路能成立以及它的边界从源码与配置结构看本示例的完整挂载链路为Gluster 集群 (gluster1.rhs / gluster2.rhs, 卷 myVol1) │ fuse 协议 (glusterfs-client modeprobe fuse) ▼ Atomic Host 节点本地路径 /mnt/myVol1 ← 节点上手动 fuse 挂载 │ mkdir 出应用目录 glusterfs-nginx-atomichost-mount ▼ Pod spec.volumes[hostPath].path ← kubelet 按 hostPath 卷类型处理 │ ▼ 容器内 mountPath /usr/share/nginx/html/test ← NGINX 文档根子目录几个由仓库内容可以确认的事实与限制hostPath 卷不携带任何 Gluster 语义。清单中的volumes只有一个hostPath字段Kubernetes 只负责把该节点目录挂进容器。分布式完全由节点上预先存在的 fuse 挂载提供。这与 Example 2 的 Pod 清单形成对照——后者在volumes中声明glusterfs卷含endpoints、path、readOnly字段并配合 gluster-endpoints.json 与 gluster-service.json 由插件自动完成挂载还额外声明了securityContext.privileged: true以允许容器内建立挂载。所有节点都要有该挂载是方案的核心约束。只要 Pod 可能被调度到未建立 fuse 挂载的节点hostPath目录就会缺失内容不可见。这就是原文档不推荐绕过内置卷插件结论的直接依据也解释了为何它只适合作为构建块演示或插件故障时的临时绕行。本示例与最基础本地存储示例的差异极小。对照 host-path-examples 的 local-nginx-pod.json两者 Pod 结构完全同构唯一区别是hostPath.path指向宿主机本地目录/opt/data还是指向 Gluster 的 fuse 挂载目录——这恰好说明把本地路径换成 fuse 挂载路径就是本示例引入分布式存储的全部改动。清单中的id字段是早期 OpenShift v3.0 时代的遗留写法在 v1 API 中规范标识以metadata.name为准文档记录的pods/local-nginx输出即为该字段被接受时的产物。复现时以metadata.name为准即可。从仓库测试结构看examples_test.go 的TestExampleObjectSchemas仅对sample-app、jenkins、image-streams、db-templates等目录的 JSON 清单做运行时 schema 解码校验存储示例目录未纳入该用例表因此该 Pod 清单在仓库内主要作为可参考的静态示例存在复现仍以文档步骤为准。八、延伸阅读路径均在仓库内storage-examples 总入口HostPath / GlusterFS 示例索引GlusterFS 系列主文档环境拓扑、卷信息与四个示例的完整导航Example 2glusterfs 插件自动挂载Endpoints/Serviceglusterfs卷 privilegedsecurityContext 的完整写法Example 3PV/PVC glusterfs引入持久化声明后的完整流程Example 4OpenShift Template 一键部署本地 hostPath 基础示例本示例的无 Gluster最小对照版。按原文档的导航顺序掌握本示例后的下一步即为 nginx_gluster_plugin在那里你可以对比手动 fuse 挂载 hostPath与插件自动挂载在同一 NGINX 场景下的清单差异从而完整理解 OpenShift 卷插件到底替用户省去了哪些节点级操作。赞分享测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载相关推荐origin 仓库 OpenShift 存储示例实战HostPath 本地存储、GlusterFS 分布式存储与 Local PV 完整指南origin 仓库 OpenShift 存储示例实战HostPath 本地存储、GlusterFS 分布式存储与 Local PV 完整指南 本篇技术文章基于测试云原生质量保障OpenShift(origin) × GlusterFS 分布式存储实战hostPath、glusterfs 插件、PV/PVC 与 Template 四种接入方式OpenShift origin × GlusterFS 分布式存储实战hostPath、glusterfs 插件、PV/PVC 与 Template 四种接测试云原生质量保障如何解决RevokeMsgPatcher在微信最新版本中的兼容性问题终极指南如何解决RevokeMsgPatcher在微信最新版本中的兼容性问题终极指南 作为Windows平台微信/QQ/TIM用户你是否遇到过安装防撤回补丁后功能仍桌面应用即时通讯上一篇Android 10 按应用强制深色模式技术深度解析下一篇httparse深度解析Rust生态中最快的HTTP/1.x零拷贝解析器是如何工作的创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/25 3:28:50
oh-my-opencode-slim 内置工具与能力全景:apply_patch 救援、webfetch 增强、结构化代码搜索与后台任务控制
2026/9/25 3:28:50
AdminJS useResource Hook 完全指南:从 Redux 资源状态中按 ID 获取 ResourceJSON
2026/9/25 3:28:50
Buildah ONBUILD 实战指南:让基础镜像的触发指令自动注入派生镜像
2026/9/25 5:48:57
Embassy 在 WebAssembly 上运行:用 Rust async 编写浏览器端 ticker 应用的完整实战指南
2026/9/25 5:48:57
Orleans 9.x 升级至 10.x 迁移实战指南:包版本、行为变更、序列化状态兼容与并行集群部署
2026/9/25 5:48:57
ESPnet OWSM-CTC v4 演示应用:一个“页面不在这里“的 1B 编码器语音模型 Gradio Demo 解析
2026/9/25 5:48:57
Atlas 300V 24G推理卡部署YOLO:从ONNX到OM的完整实践
2026/9/25 5:48:57
MediaGo 下载引擎 HTTP API 全解:接口参考、SSE 事件订阅与媒体发现实战
2026/9/25 5:43:56
一个端点服务整个团队:MiniStack多账户与多区域隔离机制完全解析
2026/9/25 0:03:37
AI元人文:从工具使用到思维重构的深度探索
2026/9/25 0:03:37
Python+CNN车牌识别实战:从数据预处理到模型训练与部署
2026/9/25 0:03:37
Vim基础操作全攻略:保存退出、模式切换与高频命令实战
2026/9/25 5:41:44
深入解析Transformer多头注意力机制与工程优化
2026/9/25 5:41:44
OpenClaw 的 Skills 跑学习任务,模型通道改到 TaoToken 通道行不行?
2026/9/25 5:41:44
ChatGPT报错Oops, an error occurred! 全链路排查指南