在 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
最佳实践建议
- 日常维护/有网环境:优先使用 SCP / SFTP 或 rsync。
- 频发/大文件数据同步:配置 Virtiofs 共享目录。
- 无网且救砖/修改配置:优先考虑
qm guest exec管道传输(免关机)或关闭 VM 后使用guestmount操作。