在 Proxmox VE (PVE) 环境下,KVM 虚拟机(VM) 与 LXC 容器不同——KVM 拥有完全独立的操作系统、内核和虚拟磁盘,因此无法像 LXC 那样直接通过宿主机的 rootfs 目录自由复制文件。

根据 KVM 的运行状态(开机/关机)和网络环境(有网/隔离),在 PVE 和 KVM 之间传输文件的方法总结如下:


方案概览对比

传输场景推荐方法核心优势依赖条件 / 限制
开机 + 有网络SCP / SFTP / rsync简单通用、传输速度快虚拟机需配置 IP 且开启 SSH 选项
开机 + 隔离网络Virtiofs 共享目录原生磁盘级性能、实时同步PVE 8+,虚拟机需安装并挂载 virtiofs
开机 + 临时传小文件QEMU Guest Agent绕过网络限制,CLI 极速调用虚拟机需安装并启用 qemu-guest-agent
关机状态 (镜像文件)guestmount 工具零开销直接挂载 VM 虚拟磁盘虚拟机必须关机(开机挂载会导致文件系统损坏)
大规模/自动化批量临时 ISO 镜像注入适合初始部署/无网裸机注入需要重新挂载 CD/DVD 驱动器

具体实现方法详解

方法一:网络传输协议(SCP / SFTP / rsync)—— 最标准常用

只要虚拟机配有 IP,且 PVE 与 VM 之间网络可达(无论是桥接网卡、NAT 还是 Host-Only):

# 1. 从 PVE 传文件到 KVM 虚拟机
scp /path/to/host_file.txt root@<虚拟机_IP>:/path/to/target/

# 2. 从 KVM 虚拟机拉取文件到 PVE
scp root@<虚拟机_IP>:/path/to/vm_file.txt /path/to/host_target/

方法二:Virtiofs 共享目录 —— 最高效的持久化共享

PVE 8.x 支持通过 Virtiofs 在 PVE 宿主机和 Linux KVM 虚拟机之间建立近乎零损耗的共享文件夹。

1. PVE 宿主机端设置:

在 PVE 命令行或 qm set 中增加共享目录:

# 语法:qm set <VMID> -virtio0 /pve/host/dir,fsdevid=share_name
qm set 100 -shared0 path=/var/shares,fsid=shares

2. KVM 虚拟机内部挂载:

# 创建挂载点并挂载
mkdir -p /mnt/pve_share
mount -t virtiofs shares /mnt/pve_share

方法三:QEMU Guest Agent 管道流 —— 绕过网络的 CLI 传输

如果虚拟机没有配置网络,但安装并启用了 qemu-guest-agent:

1. PVE 宿主机 ➔ 发送文件到 KVM 虚拟机:

# 将 PVE 本地文件 Base64 编码后通过 agent 管道写入 VM 内部
base64 /path/to/host_file.txt | qm guest exec 100 -- bash -c "base64 -d > /path/to/vm_file.txt"

2. KVM 虚拟机 ➔ 提取文件到 PVE 宿主机:

# 读取 VM 内部文件并解码回 PVE 本地
qm guest exec 100 -- base64 /path/to/vm_file.txt | jq -r '.["out-data"]' | base64 -d > /path/to/host_file.txt

方法四:关机离线挂载(guestmount / qemu-nbd)—— 磁盘级直接读写

⚠️ 警告:必须先关闭 KVM 虚拟机! 在开机状态下强行挂载 VM 磁盘镜像会导致虚拟磁盘逻辑损坏。

利用 libguestfs-tools 可以在 PVE 宿主机上直接挂载 qcow2、raw 或 ZFS 卷:

1. 安装工具(PVE 宿主机):

apt-get update && apt-get install -y libguestfs-tools

2. 挂载与复制:

# 1. 确保 VM (ID: 100) 处于 stopped 状态
qm stop 100

# 2. 挂载 VM 虚拟磁盘到 PVE 宿主机的临时目录
mkdir -p /mnt/vm_disk
guestmount -a /dev/zvol/rpool/data/vm-100-disk-0 -i --ro /mnt/vm_disk  # --ro 表示只读保护

# 3. 直接使用 cp 拷贝文件
cp /mnt/vm_disk/etc/nginx/nginx.conf /root/

# 4. 传输完毕后必须卸载
guestunmount /mnt/vm_disk

方法五:打包 ISO 镜像注入 —— 无网全新 VM 初始化

对于没有安装任何 Agent、没有配置网络的完全隔离虚拟机:

# 1. 在 PVE 宿主机上将需要传输的文件打包成临时 ISO 镜像
genisoimage -o /var/lib/vz/template/iso/data_transfer.iso /path/to/transfer_dir/

# 2. 将该 ISO 挂载到 KVM 虚拟机的虚拟光驱中
qm set 100 -ide2 local:iso/data_transfer.iso,media=cdrom

# 3. 进入 KVM 虚拟机挂载光驱提取数据
mount /dev/cdrom /mnt

最佳实践建议

  1. 日常维护/有网环境:优先使用 SCP / SFTP 或 rsync。
  2. 频发/大文件数据同步:配置 Virtiofs 共享目录。
  3. 无网且救砖/修改配置:优先考虑 qm guest exec 管道传输(免关机)或关闭 VM 后使用 guestmount 操作。