K8s Lab 把当前仓库文档整理成一个可阅读的网页站点

Repository Reading Site

存储 — NFS 动态 Provisioning

| 概念 | 类比 | 说明 | |------|------|------| | **PV** (PersistentVolume) | 磁盘 | 一块实际的存储空间 | | **PVC** (PersistentVolumeClaim) | 购买请求 | "我要 10Gi 的 ReadWriteOnce 存储" | | **StorageClass**

Markdownphase-2/02-storage-nfs.md2026年4月9日 12:01

存储 — NFS 动态 Provisioning

K8s 存储模型

应用声明需求(PVC)→ StorageClass 匹配 → Provisioner 自动创建 PV → Pod 挂载使用

三个核心概念

概念 类比 说明
PV (PersistentVolume) 磁盘 一块实际的存储空间
PVC (PersistentVolumeClaim) 购买请求 "我要 10Gi 的 ReadWriteOnce 存储"
StorageClass 磁盘类型目录 "NFS 动态/本地 SSD/云盘"

静态 vs 动态 Provisioning

方式 流程 场景
静态 管理员手动创建 PV → PVC 绑定现有 PV 遗留存储、特殊硬件
动态 PVC 引用 StorageClass → Provisioner 自动创建 PV 生产首选,自动化

我们的 NFS 存储架构

Worker-4 (154.219.104.66, 150G 磁盘)
  └── /srv/nfs/k8s          ← NFS 导出目录
        ├── pvc-xxx-prometheus/  ← 自动创建的子目录
        ├── pvc-xxx-grafana/
        ├── pvc-xxx-loki/
        └── pvc-xxx-harbor/

NFS Server 配置

# Worker-4 上
apt-get install -y nfs-kernel-server
mkdir -p /srv/nfs/k8s
echo '/srv/nfs/k8s *(rw,sync,no_subtree_check,no_root_squash)' > /etc/exports
exportfs -ra

参数解释:

  • * — 允许所有客户端挂载
  • rw — 读写
  • sync — 写操作同步到磁盘后才返回(数据安全)
  • no_subtree_check — 不检查父目录权限(性能优化)
  • no_root_squash — 允许客户端 root 权限(容器需要)

NFS CSI Provisioner

helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
  --set nfs.server=10.10.0.5 \
  --set nfs.path=/srv/nfs/k8s \
  --set storageClass.name=nfs-dynamic \
  --set storageClass.defaultClass=true    # 设为默认 StorageClass

安装后,任何 PVC 不指定 storageClassName 就会使用 nfs-dynamic

当前 PVC 使用情况

Prometheus:    10Gi  (monitoring/prometheus-xxx)
Alertmanager:   2Gi  (monitoring/alertmanager-xxx)
Grafana:        5Gi  (monitoring/monitoring-grafana)
Loki:          10Gi  (monitoring/loki)
Harbor:        20Gi+ (harbor/多个组件)
Gitea:          5Gi  (gitea/postgresql + gitea-storage)
共计约 16 个 PVC,全部自动分配

Access Modes

Mode 含义 适用存储
ReadWriteOnce (RWO) 单节点读写 云盘、本地磁盘
ReadWriteMany (RWX) 多节点读写 NFS、CephFS
ReadOnlyMany (ROX) 多节点只读 静态内容分发

NFS 支持 RWX,这是它的优势——多个 Pod 可以同时挂载同一个 PVC。

Reclaim Policy

PVC 删除后 PV 怎么办?

Policy 行为
Delete PV 和底层存储一起删除(我们的默认)
Retain PV 保留,数据不删,需要手动清理

面试题:为什么 StatefulSet 的 PVC 缩容后不删?

StatefulSet 缩容(3→2)时,web-2 的 PVC 保留。这是数据安全设计——万一是误操作,扩回来后 PVC 自动重新绑定,数据不丢。要真删需要手动 kubectl delete pvc

03-ingress-networkpolicy.md