如何配置 AppArmor 以便 KVM 可以启动具有备份文件链的 guest 虚拟机

如何配置 AppArmor 以便 KVM 可以启动具有备份文件链的 guest 虚拟机

我正在 Ubuntu 16.04 上尝试使用 Qemu 外部快照进行 KVM(因为它们太快了!),并进行以下设置:

  • VM 的所有文件都位于单个目录中(以来宾名称命名)。
  • 有一个head.qcow2符号链接始终指向顶部“head”qcow2 图像。这样我就不必不断更新虚拟机配置。 (维尔什编辑)。
  • 原始/底部图像称为base.qcow2

我使用以下脚本拍摄快照(创建一个新的 qcow2 图像并将其设为头部)。该脚本仅在来宾未运行时执行。

#!/bin/bash
UNIX_TIMESTAMP=$(date +%s)
CURRENT_BACKING_FILE=`readlink head.qcow2`
NEW_HEAD_FILE="`pwd`/`echo $UNIX_TIMESTAMP`.qcow2"

# Create the new "head" disk image where all future changes are made.
sudo qemu-img create \
  -f qcow2 \
  -b $CURRENT_BACKING_FILE \
  $NEW_HEAD_FILE

# Update the symlink
rm head.qcow2
ln -s $NEW_HEAD_FILE head.qcow2

当 head.qcow2 指向 base.qcow2 时,或者我运行脚本时,这将正常工作一次所以只有一个备份文件。但是,如果存在一系列备份文件(例如,一个备份文件也有一个备份文件),那么我将收到以下错误:

error: Failed to start domain template-ubuntu-docker2
error: internal error: early end of file from monitor, possible problem: 2018-04-05T19:04:55.597373Z qemu-system-x86_64: -drive file=/media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/head.qcow2,format=qcow2,if=none,id=drive-virtio-disk0: Could not open backing file: Could not open backing file: Could not open '/media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/base.qcow2': Permission denied

的输出qemu-img --backing-chain head.qcow2是:

image: head.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 196K
cluster_size: 65536
backing file: /media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/1522954330.qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

image: /media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/1522954330.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 4.1M
cluster_size: 65536
backing file: base.qcow2 (actual path: /media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/base.qcow2)
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

image: /media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/base.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 8.8G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: true
    refcount bits: 16
    corrupt: false

我尝试过删除图像或使用 qemu-img commit 来合并它们,一旦我只剩下一两个图像,来宾就会启动。

由于它看起来像是“无法打开”的权限错误,我尝试将权限设置为 777,但仍然收到相同的错误消息,因此它不应该是权限问题。

我需要做什么?

答案1

看来又和AppArmor有关了(我有一个类似问题几年前在 Ubuntu 14.04 上,我忘记了)。我能够通过以下方式让它工作:

安装 apparmor-utils

sudo apt-get install apparmor-utils

然后在最新的系统日志中找到 libvirt ID:

sudo cat /var/log/syslog | grep "apparmor" | grep "DENIED" | grep libvirt-

然后使用该 ID 和完整路径将其设置为“投诉模式”。

sudo aa-complain \
/etc/apparmor.d/libvirt/libvirt-b0cd5bdf-6dfc-4f75-bc0f-e38adff1cdd2

然后开始你的客人。

如果我必须为每位客人单独执行此操作,这感觉充其量只是一种解决方法,而且很烦人。如果有人提供更好的解决方案,我会更高兴。

答案2

在 Debian Buster 上遇到同样的问题,事实是 libvirt apparmor 配置文件是动态创建并存储在 /etc/apparmor.d/libvirt/ 下(感谢 @Programster)。在此目录中,您应该找到一个与此类似的 TEMPLATE.qemu:

#
# This profile is for the domain whose UUID matches this file.
#

#include <tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include <abstractions/libvirt-qemu>
}

您应该为配置文件中存储 qcow2 的目录添加规则:

#
# This profile is for the domain whose UUID matches this file.
#

#include <tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include <abstractions/libvirt-qemu>
  /media/ssd_storage2/kvm/vms/templates/template-ubuntu-docker2/**.qcow2 rk,
}

“r”表示读取权限,“k”表示锁定权限。

您可以使用“dmesg -w”跟踪 apparmor 审核消息,并根据缺少的权限获取类似的消息:

[ 4404.140981] audit: type=1400 audit(1566342100.488:254): apparmor="DENIED" operation="open" profile="libvirt-b24e7663-d71a-4970-9d6c-711d43629135" name="/home/libvirt/0.0.6-dev.19+20~811d1dc983b5.qcow2" pid=22384 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=64055 ouid=64055
...
[ 4652.827860] audit: type=1400 audit(1566342349.172:263): apparmor="DENIED" operation="file_lock" profile="libvirt-b24e7663-d71a-4970-9d6c-711d43629135" name="/home/libvirt/0.0.6-dev.19+20~811d1dc983b5.qcow2" pid=23085 comm="qemu-system-x86" requested_mask="k" denied_mask="k" fsuid=64055 ouid=64055

相关内容