nfs挂载pv,pvc

非常好!你希望从 最开始的完整流程 来复盘整个过程 ------ 从创建 NFS 共享目录、配置 /etc/exports、部署 PV/PVC、Pod 启动失败,到最终通过修改权限修复问题。

下面我将为你 系统性地还原整个操作链条,并解释每一步的作用和背后的原理,形成一份清晰、可复用的"NFS + RabbitMQ 部署排错全记录"。


🧩 全流程复盘:从零搭建 NFS 存储 → RabbitMQ Pod 成功运行


第一步:在 NFS 服务器上创建持久化目录

复制代码
# 登录 NFS 服务器(192.168.10.214)
ssh admin@192.168.10.214

# 创建项目根目录
sudo mkdir -p /mnt/sdd/ctjt-zsa-prod/nfs

# 为 RabbitMQ 创建子目录(对应两个实例)
sudo mkdir -p /mnt/sdd/ctjt-zsa-prod/nfs/zsa-rabbitmq-biz
sudo mkdir -p /mnt/sdd/ctjt-zsa-prod/nfs/zsa-rabbitmq-web

# 可选:设置初始属主(非必须,但建议)
sudo chown -R nobody:nogroup /mnt/sdd/ctjt-zsa-prod/nfs

✅ 目的:为 Kubernetes 的 PV 提供后端存储路径。

🔒 此时目录为空,.erlang.cookie 尚未生成。


第二步:配置 NFS 导出(/etc/exports)

编辑 NFS 导出配置:

复制代码
sudo vim /etc/exports

添加如下行(关键!):

复制代码
/mnt/sdd/ctjt-zsa-prod/nfs  *(rw,sync,no_subtree_check,no_root_squash)

/mnt/sdd/ctjt-zsa-prod/nfs/zsa-redis-biz    192.168.10.0/24(rw,sync,no_root_squash,no_subtree_check)

🔑 关键参数说明:

  • rw:读写权限
  • sync:同步写入(更安全)
  • no_subtree_check:提升性能
  • no_root_squash允许客户端 root 用户在服务端保留 root 权限 ← 这是后续能 chown 999 的前提!

然后重载 NFS 配置:

复制代码
sudo exportfs -ra
sudo systemctl reload nfs-kernel-server   # 或 nfs-server,取决于系统

✅ 目的:让 K8s 节点能挂载该目录,并具备修改文件属主的能力。


第三步:在 Kubernetes 中创建 PV 和 PVC

你创建了类似如下的 PV(静态供给):

复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: zsa-rabbitmq-biz
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.10.214
    path: "/mnt/sdd/ctjt-zsa-prod/nfs/zsa-rabbitmq-biz"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zsa-rabbitmq-biz
  namespace: ctjt-zsa
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

✅ 目的:将 NFS 目录映射为 K8s 可用的存储卷。


第四步:部署 RabbitMQ Deployment(挂载整个目录)

你的 Deployment 大概如下:

复制代码
volumeMounts:
- name: data
  mountPath: /var/lib/rabbitmq   # ← 挂载整个目录!
volumes:
- name: data
  persistentVolumeClaim:
    claimName: zsa-rabbitmq-biz

⚠️ 问题根源就在这里:挂载了整个 /var/lib/rabbitmq 目录 ,导致 .erlang.cookie 也会被写入 NFS。


第五步:Pod 启动失败(典型报错)

当你执行:

复制代码
kubectl apply -f rabbitmq-deployment.yaml

Pod 卡在 CrashLoopBackOff,日志显示:

复制代码
Cookie file /var/lib/rabbitmq/.erlang.cookie must be accessible by owner only
原因分析:
  1. RabbitMQ 容器启动时,发现 /var/lib/rabbitmq 是空的(因为 NFS 目录刚创建)
  2. 自动创建 .erlang.cookie
  3. 但由于 NFS 默认行为(即使有 no_root_squash,容器内 UID=999 可能无权设 600),文件权限变成 644
  4. Erlang 安全机制拒绝启动

第六步:手动修复 .erlang.cookie 权限(关键转折)

你回到 NFS 服务器,执行:

复制代码
# 进入 biz 目录
cd /mnt/sdd/ctjt-zsa-prod/nfs/zsa-rabbitmq-biz

# 删除可能已存在的错误 cookie
sudo rm -f .erlang.cookie

# 创建新 cookie(内容任意,但集群需一致)
echo "CTJT_ZSA_RABBITMQ_COOKIE" | sudo tee .erlang.cookie

# 设置严格权限 ← 核心!
sudo chmod 600 .erlang.cookie
sudo chown 999:999 .erlang.cookie   # RabbitMQ 容器 UID=999

# 同样处理 web 实例
cd ../zsa-rabbitmq-web
echo "CTJT_ZSA_RABBITMQ_COOKIE" | sudo tee .erlang.cookie
sudo chmod 600 .erlang.cookie
sudo chown 999:999 .erlang.cookie

✅ 成功前提:

  • NFS 配置了 no_root_squash → 允许 chown 999
  • 你在 NFS 服务端 操作 → 修改的是真实文件

第七步:重启 Pod,验证成功

复制代码
kubectl delete pod -n ctjt-zsa -l app=zsa-rabbitmq-biz
kubectl delete pod -n ctjt-zsa -l app=zsa-rabbitmq-web

新 Pod 启动后:

  • 挂载 NFS 目录
  • 发现已存在合法的 .erlang.cookie(600 + UID=999)
  • Erlang 通过安全检查
  • RabbitMQ 正常启动 ✅

📌 全流程关键点总结

表格

阶段 操作 作用 风险/注意
1. 准备存储 创建 NFS 子目录 提供 PV 后端路径 目录需可写
2. 导出配置 /etc/exports + no_root_squash 允许权限修改 缺少则 chown 失败
3. K8s 部署 PV/PVC + 挂载 /var/lib/rabbitmq 持久化数据 但连带持久化了 cookie
4. 启动失败 Pod CrashLoop 因 cookie 权限不安全 典型 Erlang 报错
5. 手动修复 在 NFS 服务端设 600 + 999:999 满足安全策略 必须在服务端操作
6. 重启验证 删除 Pod 触发重建 加载合法 cookie 成功运行

🔚 最终建议:如何避免下次再踩坑?

虽然你现在成功了,但这个方案 依赖手动干预,不适合自动化或大规模部署。

✅ 推荐长期方案:只挂载 /mnesia 子目录

修改 Deployment:

复制代码
volumeMounts:
- name: data
  mountPath: /var/lib/rabbitmq/mnesia   # ← 不挂整个目录!

这样:

  • .erlang.cookie 在容器层生成(权限永远正确)
  • 消息数据仍在 NFS(mnesia 目录包含队列、交换器等)
  • 无需手动创建 cookie,无需改权限,天然兼容 NFS

这是官方推荐做法,也是 Helm Chart 的默认行为。


相关推荐
Cyber4K3 小时前
【Kubernetes专项】K8s集群1.31版本安装手册
linux·docker·云原生·容器·kubernetes
bentengjiayou7 小时前
K8S是用来解决什么问题的?
云原生·容器·kubernetes
2501_901164417 小时前
我们如何把“配环境一天”缩短到“3秒启动”?
kubernetes
oMcLin9 小时前
如何在Debian 11上使用Kubernetes网络策略,确保多租户环境下的网络安全与流量隔离?
kubernetes·debian
伞啊伞9 小时前
k8s(五)集群调度与PV和PVC
云原生·容器·kubernetes
海鸥819 小时前
K8s 的 command/args 会覆盖 Dockerfile 的 CMD/ENTRYPOINT
云原生·容器·kubernetes
db_cy_20629 小时前
Docker+Kubernetes企业级容器化部署解决方案(阶段二)
运维·docker·容器·kubernetes
youxiao_909 小时前
kubernetes(三)-Rancher管理k8s集群
容器·kubernetes·rancher
robch10 小时前
k8s service deployment pod 的 label
云原生·容器·kubernetes