Skip to content

KubeVirt 虚拟机使用商用 NAS 存储:方案与落地

日期: 2026-09-03 环境: RKE2 v1.35.6(6 节点)+ KubeVirt v1.9.0 + CDI v1.60.4 入口节点: root@192.168.122.31关联文档: cdi-offline-deployment-guide.mdkubevirt-storage-ha-guide.mdrke2-kubevirt-deployment-guide.md


目录

  1. 结论与现网证据
  2. 三种接入方式对比
  3. qcow2 放哪里:镜像库与活动磁盘分离
  4. 镜像库 → 导入 → 金盘克隆
  5. NAS 容量与虚拟机数量限制
  6. NFS 关键注意事项
  7. 落地实施:vm-nas StorageClass
  8. 验证清单

1. 结论与现网证据

结论:完全可行,且是生产环境最常见方案之一。 KubeVirt 的虚拟机磁盘本质是一个 PVC(RWO 即可),任何能通过 StorageClass/CSI 供应 PVC 的存储后端都可以承载,商用 NAS 提供的 NFS / iSCSI 天然符合。

现网集群(192.168.122.31)已有的证据:

  • 已存在基于 NFS 的 VM 磁盘 PVC:sza001-rootdisk(SC=nfs)、vm1-rootdisk(SC=nfs-nvme
  • NFS 由 nfs-subdir-external-provisioner 供应,服务端当前是实验机 192.168.122.1/mnt/xfs/rancher/*/srv/nfs-nvme/*)——换成商用 NAS 只需把 NFS_SERVER/NFS_PATH 指向 NAS 导出目录,架构不用变

2. 三种接入方式对比

方式适用优点限制
NFS(推荐起步)所有商用 NAS(Synology/QNAP/NetApp/华为/新华三等)通用,nfs-subdir-external-provisioner 现成;天然 RWX,支持热迁移延迟高于块存储;导出版本/权限要调对
厂商 CSI(NetApp Trident、Synology CSI、华为 OceanStor CSI 等)中高端商用 NAS快照、在线扩容、精简配置、QoS需装厂商组件,确认与 RKE2/K8s 版本兼容
iSCSI对 IOPS/延迟敏感块级性能最好节点需配 initiator;RWO 单挂载 → 不能热迁移;配置复杂

一般建议:NFS 起步,有性能/快照诉求再上厂商 CSI。CDI 导入流程与后端无关, CDI 会为每个新 StorageClass 自动生成 StorageProfile(默认 Filesystem + RWO),无需额外配置。


3. qcow2 放哪里:镜像库与活动磁盘分离

"qcow2 存 NAS、容器直接跑"要先分清两个角色:

3.1 方案 A:qcow2 只做镜像库,活动磁盘走 PVC(推荐,已验证)

NAS/文件服务器上的 qcow2 → CDI DataVolume 导入 → PVC 上的 disk.img(raw) → VM 启动
        镜像仓库                  一次性转换              真正的虚拟机磁盘
  • 即现网已跑通链路(cdi-offline-deployment-guide.md §6)
  • CDI 导入时会把 qcow2 转成 raw(Filesystem PVC 上固定为 disk.img
  • 运行中的 VM 只依赖 PVC,镜像库只在创建新 VM 时被用到(导入完成后源镜像 所在服务宕机不影响任何存量 VM)
  • 镜像库与活动磁盘可合并在同一台商用 NAS 上(两个目录而已)

3.2 方案 B:NAS 挂进 Pod,VM 直接读写 NAS 上的 qcow2 文件(不推荐)

KubeVirt 技术上能识别 PVC 里现成的 qcow2 文件(自动检测格式),但:

  1. qcow2 是元数据密集型格式(L1/L2 表、引用计数频繁小写),叠加 NFS 延迟性能差
  2. 绕开了平台的单写者保护,两个 Pod 指到同一文件 = 磁盘损坏
  3. 失去在线扩容、preallocation、StorageProfile 调优、克隆能力

3.3 方案 C:绕开 KubeVirt,普通容器跑 qemu(仅临时用途)

Deployment 里跑 qemu-kvm -drive file=/mnt/nas/vm.qcow2 可以工作,但要自己解决 /dev/kvm 暴露、网络接入、VNC、重启策略,等于放弃 KubeVirt/dashboard 全部平台能力。


4. 镜像库 → 导入 → 金盘克隆

4.1 导入源说明

CDI 支持的导入源:http/httpss3registrygcspvc(克隆)、uploadblank不支持 nfs:// 直接导入——商用 NAS 上的 qcow2 需要用 HTTP 暴露 (NAS 自带 Web 服务,或沿用文件服务器方式)。

4.2 golden image + 克隆(批量建同类 VM)

让源 qcow2 只被导入一次,之后全部从"金盘"派生:

yaml
# ① 金盘:导入一次
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: golden-rocky9
spec:
  source:
    http:
      url: "http://<nas-or-fileserver>/images/rocky9-server-root.qcow2"
  pvc:
    storageClassName: vm-nas
    accessModes: [ReadWriteMany]     # 需要热迁移时用 RWX
    resources:
      requests:
        storage: 20Gi
---
# ② 每台新 VM:从金盘克隆(不再碰镜像库)
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: vm001-rootdisk
spec:
  source:
    pvc:
      namespace: default
      name: golden-rocky9
  pvc:
    storageClassName: vm-nas
    accessModes: [ReadWriteMany]
    resources:
      requests:
        storage: 20Gi
  • 商用 NAS 配了厂商 CSI 时,克隆可走 CSI 快照,秒级开盘
  • 也可用 DataSource + DataImportCron 做定时刷新的金盘(适合镜像版本管理)

4.3 故障域视角

故障影响
镜像库服务宕机不能导入/新建,存量 VM 无感
VM 盘所在存储宕机挂在该盘上的 VM 受影响(这是需要保 HA 的一侧,见 kubevirt-storage-ha-guide.md

5. NAS 容量与虚拟机数量限制

NAS 没有显式的"虚拟机数量"配额——NAS 眼里只有 NFS 导出目录里的磁盘文件。 真正的限制全部是性能型约束,取决于 NAS 档次:

约束说明谁先撑爆
随机 IOPSVM 磁盘典型 4K 随机读写;HDD 单盘 ~100-150 IOPS,RAID 后线性叠加机械盘 NAS
带宽1GbE ≈ 110MB/s,10GbE ≈ 1GB/s,所有 VM 共享大吞吐负载
协议栈 CPU/内存NFSv4 会话/锁处理消耗控制器 CPU入门级弱 CPU
挂载连接数K8s 每节点每个在用 PV 各挂一次;企业级支持数千连接SOHO 机型
Boot storm多 VM 同时开机的瞬时随机读风暴无 SSD 缓存的 NAS

部分厂商对 iSCSI 有显式限制(最大 LUN 数、并发连接数,如 Synology 按型号 10~128 LUN / 512 连接),走 NFS 基本不触碰此类硬限制。

各档次实际承载经验值(NFS + 通用型 VM):

NAS 档次典型配置能撑的 VM 量级
SOHO/入门(4 盘位,HDD,1GbE)无 SSD 缓存5~15 台轻量级
中端(8~24 盘位,SSD 缓存,10GbE)Synology SA/UC、QNAP TS-h 等几十到一两百台
企业级(NetApp/华为 OceanStor/Dell Unity/PowerScale)全闪或混合多控数百到数千台

判断方法:看规格书的 IOPS 和延迟,不看"支持多少虚拟机"

估算步骤:

bash
# ① 从任一 K8s 节点对 NAS 导出实测
fio --name=nas --rw=randrw --bs=4k --iodepth=16 --numjobs=4 \
    --runtime=60 --time_based --filename=/挂载点/fio.dat --size=4G --direct=1

# ② 算需求:普通业务 VM 稳态约 1~10 IOPS/台,开机瞬间 100~500 IOPS
#    总 IOPS ÷ 开机峰值 ≈ 可承载台数上限

# ③ 上线后盯延迟:NFS 读写延迟 <2ms 健康,>10ms 已过载(nfsiostat / NAS 面板)

抗 boot storm:VM 分批启动 + NAS 加 SSD 缓存/SSD 分层。


6. NFS 关键注意事项

  1. 权限/uid 映射:virt-launcher 里 qemu 以非 root(uid 107)运行。 NAS 导出若开 root_squashanonuid 不匹配,会出现 VM 启动时磁盘写失败 (Permission denied)。K8s 专用导出目录建议 no_root_squash
  2. NFS 版本:用 4.1+(挂载 nfsvers=4.1),v3 文件锁问题可能影响磁盘一致性。
  3. 热迁移:需要磁盘可共享 → DV 用 accessModes: [ReadWriteMany](NFS 天然支持); iSCSI/RWO 无法热迁移。
  4. 文件格式:CDI 导入产物是 raw(性能优于 qcow2);不要手工往 PVC 里塞 qcow2。
  5. 容量开销:Filesystem 模式 CDI 默认预留 5.5%(CDIConfig.filesystemOverhead)。
  6. 挂载健壮性:VM 盘必须 hard 挂载(NAS 故障时 IO 挂起等待恢复,不产生静默错误), 详见 kubevirt-storage-ha-guide.md

7. 落地实施:vm-nas StorageClass

沿用现网已验证的 nfs-subdir-external-provisioner,指向商用 NAS:

yaml
# provisioner Deployment 关键环境变量(其余沿用现有部署)
env:
  - name: NFS_SERVER
    value: "<商用NAS IP>"
  - name: NFS_PATH
    value: "/exports/kubevirt"
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vm-nas
provisioner: cluster.local/nfs-subdir-external-provisioner   # 与 Deployment 的 PROVISIONER_NAME 一致
reclaimPolicy: Retain          # VM 盘建议 Retain,防误删
allowVolumeExpansion: true
mountOptions:
  - nfsvers=4.1
  - hard
  - timeo=600
  - retrans=5
  - noatime

NAS 侧配置:创建导出 /exports/kubevirt,选项 rw,sync,no_root_squash,no_subtree_check

两个集群的落地建议:

集群建议
现网 122.31复制现有 provisioner 部署指向商用 NAS,建 vm-nas SC;新 VM 磁盘与 CDI 导入目标都用它
目标 RKE2(uat1)当前无动态存储(只能手工 hostPath PV);装好 vm-nas SC 后 KubeVirt + CDI 直接可用,可不再依赖 local-path

8. 验证清单

  • [ ] 各节点手动挂载 NAS 导出成功:mount -t nfs4 <nas>:/exports/kubevirt /mnt/t
  • [ ] vm-nas SC 创建 PVC 秒级 Bound,写文件无 Permission denied
  • [ ] 小镜像 DataVolume 导入 Succeeded(先小后大)
  • [ ] VM 从 NAS PVC 启动,重启后数据保留
  • [ ] (如需热迁移)DV 用 RWX,kubectl virt migrate 成功且业务不中断
  • [ ] fio 实测结果记录存档,作为容量规划基线