在容器 (podman) 中运行虚拟机 (QEMU/KVM, libvirt)

2024-08-28 22:04

本文主要是介绍在容器 (podman) 中运行虚拟机 (QEMU/KVM, libvirt),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

虚拟机 (virtual machine) 是一种计算机的虚拟化技术, 容器 (container) 是一种更轻量级的虚拟化技术. 虚拟机可以套娃 (嵌套, nest), 也就是在虚拟机中运行虚拟机. 容器也可以套娃, 比如 Docker in Docker, Podman in Podman, Podman in Docker 等. 容器和虚拟机也可以互相套娃, 比如在虚拟机中运行容器, 是可以的.

那么, 反过来, 在容器中运行虚拟机呢 ?

这里是 穷人小水滴, 专注于 穷人友好型 低成本技术. (本文为 57 号作品. )


参考资料:

  • https://www.redhat.com/sysadmin/podman-inside-container
  • https://libvirt.org/uri.html
  • https://github.com/virt-manager/virt-manager/issues/333
  • https://github.com/virt-manager/virt-manager/issues/592
  • https://virt-manager.org/
  • https://www.qemu.org/

相关文章:

  • 《QEMU/KVM 虚拟机显卡透传 (vfio-pci)》 https://blog.csdn.net/secext2022/article/details/141473097
  • 《香橙派: 在容器 (podman) 中运行 x11 图形界面》 https://blog.csdn.net/secext2022/article/details/141304112
  • 《自制神之嘴: fish-speech 容器镜像 (文本转语音 AI 大模型)》 https://blog.csdn.net/secext2022/article/details/141224704
  • 《基于 sftp 的 NAS (局域网文件存储服务器)》 https://blog.csdn.net/secext2022/article/details/140305630
  • 《安装 Fedora CoreOS 操作系统》 https://blog.csdn.net/secext2022/article/details/139805083

目录

  • 1 制作容器镜像
  • 2 运行测试
  • 3 总结与展望

1 制作容器镜像

使用的 Dockerfile 内容如下:

# alpine-qemu-libvirt
FROM quay.io/jitesoft/alpine:latestRUN sed -i 's/ftp.halifax.rwth-aachen.de/mirrors.sjtug.sjtu.edu.cn/g' /etc/apk/repositoriesRUN apk update && apk upgrade && \apk add curl bridge-utils \qemu qemu-block-curl qemu-block-ssh qemu-bridge-helper qemu-img qemu-system-x86_64 qemu-tools \libvirt libvirt-daemon libvirt-qemu && \apk cache cleanRUN cp /etc/libvirt/libvirtd.conf /etc/libvirt/libvirtd.conf.old && \cp /etc/libvirt/qemu.conf /etc/libvirt/qemu.conf.old
COPY ./libvirtd.conf /etc/libvirt/libvirtd.conf
COPY ./qemu.conf /etc/libvirt/qemu.conf# libvirt 默认端口
EXPOSE 16509# VOLUME /var/lib/libvirt/imagesCMD /usr/sbin/virtlogd -d && /usr/sbin/libvirtd -l
#CMD /bin/ash

其中配置文件 libvirtd.conf:

listen_tls = 0
listen_tcp = 1# !! 警告: 仅用于测试, 这个设置不安全 !! !
auth_tcp = "none"

其中配置文件 qemu.conf:

# 修复: Unable to set XATTR trusted.libvirt.security.dac on /var/lib/libvirt/qemu/domain-1-*/master-key.aes: Operation not permitted
# https://github.com/virt-manager/virt-manager/issues/333
remember_owner = 0

构建命令:

podman build -t alpine-qemu-libvirt .

保存镜像:

podman save alpine-qemu-libvirt | zstd > alpine-qemu-libvirt-20240828.tar.zst

在服务器上加载镜像:

fc-test@MiWiFi-RA74-srv:~$ ls -l alpine-qemu-libvirt-20240828.tar.zst
-r--r--r--. 1 fc-test fc-test 60481128 Aug 27 17:08 alpine-qemu-libvirt-20240828.tar.zst
fc-test@MiWiFi-RA74-srv:~$ podman load < alpine-qemu-libvirt-20240828.tar.zst

加载的镜像:

fc-test@MiWiFi-RA74-srv:~$ podman images
REPOSITORY                       TAG       IMAGE ID      CREATED       SIZE
localhost/alpine-qemu-libvirt    latest    3e1b75a9c069  12 hours ago  168 MB

2 运行测试

首先检查服务器 KVM 功能是否开启:

fc-test@MiWiFi-RA74-srv:~/tmp-libvirt$ id
uid=1002(fc-test) gid=1002(fc-test) groups=1002(fc-test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
fc-test@MiWiFi-RA74-srv:~/tmp-libvirt$ ls -l /dev/kvm
crw-rw-rw-. 1 root kvm 10, 232 Aug 18 03:01 /dev/kvm

在服务器上运行容器:

podman run --rm --device /dev/kvm --device /dev/net/tun -v .:/var/lib/libvirt/images:z -p 16509:16509 -p 5900:5900 alpine-qemu-libvirt

在本机尝试连接服务器的 libvirtd:

> virsh -c qemu+tcp://fc-server.test/system listId   名称   状态
-------------------

其中 fc-server.test 是服务器的 IP 地址.


在本机启动 virt-manager:

在这里插入图片描述

点击添加连接:

在这里插入图片描述

选择自定义 URI, 输入 qemu+tcp://fc-server.test/system, 确定:

在这里插入图片描述

成功连接:

在这里插入图片描述


创建虚拟机:

在这里插入图片描述

选择系统安装光盘 iso 文件:

在这里插入图片描述

注意勾选 在安装前自定义配置, 完成:

在这里插入图片描述

如图所示进行配置, 注意删除网卡 (NIC), 配置 VNC 服务器的端口号:

在这里插入图片描述


点击开始安装:

在这里插入图片描述

这是 ArchLinux 安装光盘的启动界面.

在这里插入图片描述

启动进入系统, 注意 KVM (/dev/kvm) 是启用的.

在这里插入图片描述

执行 lscpu 命令, 注意鼠标指针指向的位置. 这表示系统在 QEMU/KVM 虚拟机中运行, 同时开启了 嵌套虚拟化 (也就是可以在虚拟机中运行虚拟机, 同样可以使用 KVM 硬件加速).

至此, 在容器 (podman) 中运行 QEMU/KVM 虚拟机, 测试成功.

3 总结与展望

本文验证了在容器中运行 QEMU/KVM 虚拟机是可行的, 可以正常使用 Linux 内核的 KVM 硬件加速. podman 可以普通用户运行, 无需 root 权限, 所以普通用户也可以运行 QEMU/KVM 虚拟机.

但是 libvirt 不太适应容器内的环境 (也可能是不适应没有 root 权限), BUG 和报错一大堆, 比如虚拟机的关机/重启功能严重故障, 直接卡死. 这个也可能是配置和使用方式不太对, 需要进一步分析具体的原因. 同时因为没有 root 权限, 虚拟机的网络功能也无法使用 (无法连网), 这个问题还没解决.

后续可以考虑不使用 libvirt, 直接使用 qemu-system 来运行虚拟机, 或许可以解决上述问题. 不过, 虚拟机和容器的互相疯狂套娃, 这里是达成了, 撒花 ~


本文使用 CC-BY-SA 4.0 许可发布.

这篇关于在容器 (podman) 中运行虚拟机 (QEMU/KVM, libvirt)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116003

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Python如何精准判断某个进程是否在运行

《Python如何精准判断某个进程是否在运行》这篇文章主要为大家详细介绍了Python如何精准判断某个进程是否在运行,本文为大家整理了3种方法并进行了对比,有需要的小伙伴可以跟随小编一起学习一下... 目录一、为什么需要判断进程是否存在二、方法1:用psutil库(推荐)三、方法2:用os.system调用

Python运行中频繁出现Restart提示的解决办法

《Python运行中频繁出现Restart提示的解决办法》在编程的世界里,遇到各种奇怪的问题是家常便饭,但是,当你的Python程序在运行过程中频繁出现“Restart”提示时,这可能不仅仅是令人头疼... 目录问题描述代码示例无限循环递归调用内存泄漏解决方案1. 检查代码逻辑无限循环递归调用内存泄漏2.

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM