<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>dwt&#039;s life - kvm</title>
<link>https://dwt.life/tag/kvm/</link>
<atom:link href="https://dwt.life/feed/tag/kvm/" rel="self" type="application/rss+xml" />
<language>zh-CN</language>
<description></description>
<lastBuildDate>Thu, 19 Aug 2021 02:00:00 +0800</lastBuildDate>
<pubDate>Thu, 19 Aug 2021 02:00:00 +0800</pubDate>
<item>
<title>libvirt禁止每次增加新DHCP IP时写入iptables</title>
<link>https://dwt.life/archives/125/</link>
<guid>https://dwt.life/archives/125/</guid>
<pubDate>Thu, 19 Aug 2021 02:00:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[每次增加DHCP IP的时候就会增加一条iptables规则,影响其他IP的正常使用,使用hooks直接恢复mkdir /etc/libvirt/hooksfor f in daemon qem...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>每次增加DHCP IP的时候就会增加一条iptables规则,影响其他IP的正常使用,使用hooks直接恢复</p><pre><code class="lang-shell">mkdir /etc/libvirt/hooks
for f in daemon qemu lxc libxl network; do
  echo &#039;#!/bin/sh
iptables-restore &lt; /etc/sysconfig/iptables
iptables -I FORWARD -j ACCEPT&#039; &gt; &quot;/etc/libvirt/hooks/$f&quot;
  chmod +x &quot;/etc/libvirt/hooks/$f&quot;
done
service libvirtd restart</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/125/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>虚拟机镜像管理工具-- Libguestfs</title>
<link>https://dwt.life/archives/97/</link>
<guid>https://dwt.life/archives/97/</guid>
<pubDate>Thu, 05 Aug 2021 22:42:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[libguestfs是一个用来访问和修改虚拟机磁盘镜像的一个工具集libguestfs 是一组 Linux 下的 C 语言的 API ，用来访问虚拟机的磁盘映像文件。该工具包内包含的工具有vir...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<blockquote>libguestfs是一个用来访问和修改虚拟机磁盘镜像的一个工具集</blockquote><p>libguestfs 是一组 Linux 下的 C 语言的 API ，用来访问虚拟机的磁盘映像文件。该工具包内包含的工具有virt-cat、virt-df、virt-ls、virt-copy-in、virt-copy-out、virt-edit、guestfs、guestmount、virt-list-filesystems、virt-list-partitions等工具，具体用法也可以参看官网。该工具可以在不启动KVM guest主机的情况下，直接查看guest主机内的文内容，也可以直接向img镜像中写入文件和复制文件到外面的物理机，当然其也可以像mount一样，支持挂载操作。</p><h1>安装Libguestfs</h1><p><code>yum install libguestfs-tools</code></p><h1>实例</h1><h2>如何利用Libguestfs修复受损虚拟机？</h2><p>作为VMware虚拟化环境管理员，你肯定遇到过虚拟机无法启动的情况。实施排错时，你需要对虚拟机的内部进行检查。而Libguestfs Linux工具集可以在这种情况下为你提供帮助。Libguestfs允许在虚拟机上挂载任何类型的文件系统，以便修复启动故障。</p><h2>利用Libguestfs找出损坏的虚拟机文件</h2><p>使用Libguestfs，首先需要使用Libvirt。Libvirt是一个管理接口，可以和KVM、Xen和其他一些基于Liunx的虚拟机相互连接。Libguestfs的功能更加强大，可以打开Windows虚拟机上的文件。这意味着除了能够使用libguestfs，你还需要一些关于虚拟机操作系统内部架构的知识。但是首先你需要将虚拟机迁移到libguestfs可用的环境当中，也就是Linux环境。</p><h2>1. 使用guestfish操作虚拟机</h2><p>完成虚拟机磁盘镜像文件的复制之后，可以在libguestfs中使用guestfish这样的工具将其打开，这样就可以直接在vmdk文件上进行操作了。使用</p><p><code>guestfish -rw -a /path/to/windows.vmdk</code><br>命令来在虚拟机中创建一个连接到文件系统的交互式shell。在新出现的窗口中，你可以使用特定的命令来操作虚拟机文件。</p><p>第一个任务就是找到可用的文件系统：</p><pre><code>\&gt;&lt;fs&gt; run 
\&gt;&lt;fs&gt; list-filesystems 
/dev/sda1: ntfs 
/dev/sda2: ntfs </code></pre><p>当你使用guestfish shell找到可用文件系统类型之后，就可以进行挂载了。使用命令</p><p><code>mount /dev/sda2 / </code><br>来挂载二个分区的内容——在Linux中是/dev/sda2——到guestfish根目录下。在guestfish中，你不能像在其他shell环境中一样操作目录。挂载的分区就是根目录，你不能使用cd命令来切换目录，这意味着所有的路径必须是完全限定路径，从根目录开始。</p><p>在guestfish shell当中可以使用像vi、ls、cat、more、download这样的命令，来查看和下载文件以及目录，输入help可以看到完整的命令信息。</p><p>在完整所有操作之后可以使用exit来关闭guestfish shell。</p><h2>2. virt-rescue提供了直接访问方式</h2><p>在libguestfs工具中，还有许多其他可用的工具。</p><p>virt-rescue命令——是使用正常的Linux文件系统工具来实现ad-hoc变化的最佳命令——可以在安全shell中启动虚拟机。你可以在虚拟机中操作这些文件，就像对挂载的文件系统上进行操作一样，其提供了对虚拟机内容更加直接的访问方式。<br>为了在虚拟机上使用virt-rescue命令进行操作，使用</p><p><code>virt-rescure 虚拟机名</code><br>来打开virt-rescue shell，之后就进入了<br><code>&gt;&lt;rescue&gt;</code><br>模式。</p><p>如果需要在虚拟机中挂载系统文件，可以使用<br><code>fdisk -l /dev/sda</code><br>命令来查看虚拟机的分区情况，之后再使用命令</p><p><code>mount /dev/sda1 /sysroot</code><br>挂载你想要访问的分区。这样你就可以通过更改来修复虚拟机的内容了。<br>虚拟机修复之后，关闭virt-rescue shell，将虚拟机重新移动到ESXi服务器的数据存储当中。虚拟机返回原位置之后，如果之前的操作一切顺利，你就应该可以访问它了。</p><h1>其他命令：</h1><h2>virt-df</h2><blockquote>查看磁盘占用率</blockquote><pre><code>[root@localhost file]# virt-df centos.img
Filesystem                           1K-blocks       Used  Available  Use%
centos.img:/dev/sda1                    495844      31950     438294    7%
centos.img:/dev/VolGroup/lv_root      28423176     721504   26257832    3%</code></pre><h1>virt-ls</h1><blockquote>查看目录下文件</blockquote><pre><code>[root@localhost file]# virt-ls centos.img /
.autofsck
bin
boot
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
sbin
selinux
srv
sys
tmp
usr</code></pre><h2>virt-copy-out</h2><blockquote>将镜像里的文件拷贝出来</blockquote><p><code>virt-copy-out -d 虚拟机名 /etc/passwd /tmp/</code></p><h2>virt-filesystems</h2><h2>virt-list-filesystems</h2><h2>virt-list-partitions</h2><blockquote>查看分区相关信息</blockquote><pre><code>[root@localhost file]# virt-filesystems  -d 虚拟机名
/dev/sda1
/dev/VolGroup/lv_root

[root@localhost file]# virt-list-filesystems  /file/centos.img
/dev/VolGroup/lv_root
/dev/sda1

[root@localhost file]# virt-list-partitions  /file/centos.img
/dev/sda1
/dev/sda2</code></pre><h2>guestmount</h2><blockquote>分区挂载</blockquote><pre><code>[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/sda2  --rw /mnt
libguestfs: error: mount_options: /dev/sda2 on / (options: &#039;&#039;): mount: unknown filesystem type &#039;LVM2_member&#039;
guestmount: &#039;/dev/sda2&#039; could not be mounted.
guestmount: Did you mean to mount one of these filesystems?
guestmount:     /dev/sda1 (ext4)
guestmount:     /dev/VolGroup/lv_root (ext4)
guestmount:     /dev/VolGroup/lv_swap (swap)
[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/VolGroup/lv_root  --rw /mnt
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the &#039;nonempty&#039; mount option
libguestfs: error: fuse_mount: /mnt: Resource temporarily unavailable
[root@localhost ~]# ls /mnt/
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
[root@localhost ~]# umount /mnt/

[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/VolGroup/lv_root  --rw /mnt
[root@localhost ~]# ls /mnt/
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var

[root@localhost ~]# umount /mnt/</code></pre><h2>使用libguestfs访问windows系统</h2><pre><code>[root@localhost opt]# virt-ls -a /file/win7.img c:
virt-ls: no operating system was found on this disk
If using guestfish &#039;-i&#039; option, remove this option and instead
use the commands &#039;run&#039; followed by &#039;list-filesystems&#039;.
You can then mount filesystems you want by hand using the
&#039;mount&#039; or &#039;mount-ro&#039; command.
If using guestmount &#039;-i&#039;, remove this option and choose the
filesystem(s) you want to see by manually adding &#039;-m&#039; option(s).
Use &#039;virt-filesystems&#039; to see what filesystems are available.
If using other virt tools, this disk image won&#039;t work
with these tools.  Use the guestfish equivalent commands
(see the virt tool manual page).
RHEL 6 notice
-------------
libguestfs will return this error for Microsoft Windows guests if the
separate &#039;libguestfs-winsupport&#039; package is not installed. If the
guest is running Microsoft Windows, please try again after installing
&#039;libguestfs-winsupport&#039;.</code></pre><p>需要注意的是，上面的用法中，有两个错误的地方，一处是linux查看C分区，后面不能直接跟C：，而应该换用/ ；第二个错误是由于没有安装<strong>libguestfs-winsupport</strong> 。该工具也可以看接通过yum安装 。安装完该包后，再进行查看：</p><pre><code>[root@localhost opt]# virt-ls -a /file/win7.img /
$Recycle.Bin
Documents and Settings
PerfLogs
Program Files
Program Files (x86)
ProgramData
Recovery
System Volume Information
Users
Windows
pagefile.sys</code></pre><h2>利用guestmount进行挂载</h2><pre><code>[root@localhost ~]# guestmount -a /file/win7.img  -m /dev/sda2  --rw /mnt
[root@localhost ~]# ls /mnt/
Documents and Settings  pagefile.sys  PerfLogs  ProgramData  Program Files</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/97/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>通过QEMU-GuestAgent实现从外部注入写文件到KVM虚拟机内部</title>
<link>https://dwt.life/archives/92/</link>
<guid>https://dwt.life/archives/92/</guid>
<pubDate>Mon, 02 Aug 2021 10:04:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[本文将以宿主上直接写文件到VM内部为例讲解为何要注入以及如何实现为什么要“注入”到VM内部原因很简单：在VM外部无法实现，只能进入到VM内来实现KVM不像Docker(container)只是对...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>本文将以宿主上直接写文件到VM内部为例讲解为何要注入以及如何实现</p><h1>为什么要“注入”到VM内部</h1><p><strong>原因很简单：在VM外部无法实现，只能进入到VM内来实现</strong></p><p>KVM不像Docker(container)只是对进程进行cgroup隔离，KVM是全封闭的环境。</p><p>对于基于KVM的虚拟机来说，通常存在如下需求：</p><ul><li>在线修改密码</li><li>在线增加公钥</li><li>在线采集性能（如cpu使用率、负载、内存使用量等性能指标）</li><li>其他各种在线功能</li></ul><p>上述这些场景的共性：仅在VM外部是无法实现的。因此就有了多种解决方案，但无论哪种解决方案都要同时满足以下2点才能实现：</p><ul><li>通道：在VM内部与外部（宿主）之间打开一个通道，可以进行数据交互</li><li>agent：在VM内部种下一个agent，用于接收外部的指令并反馈结果</li></ul><p>在VM内部种下agent的做法可以形象地称之为"inject 注入"</p><h1>如何实现“注入”</h1><h2>第一步，打开通道</h2><p>有2类方法：</p><ul><li>走网络：会复杂一些，需要提前预插入一张管理网卡，或者利用已有网卡+特殊的路由来确保数据能走出去，这带来了较为复杂的网络拓扑</li><li>走设备：简单很多，只需在VM内部和宿主之间建立一个设备通道即可。比如为KVM虚拟机增加一个字符设备，并在宿主上映射为一个socket文件。字符设备与socket之间形成了一个channel，通过该channel就可以进行内外数据互通</li></ul><p>“走网络”不是本文想要介绍的，接下来所有内容均为“走设备”</p><h2>第二步，启动agent</h2><p>在虚拟机里启动一个agent，实时读取字符设备，实现与宿主的数据交互。</p><p>在channel中发送与接收什么样的数据，是可以自己定义的，也可以使用KVM官方实现的解决方案，称为Qemu Guest Agent，简称qemu-ga。它包含2方面：</p><ul><li>channel中传送数据的协议定义：基于JSON的格式</li><li>VM内的agent：启动一个名叫qemu-ga的守护进程，该进程将从字符设备里获取传进来的json指令，然后根据指令执行相关命令，并将结果通过字符设备返回给宿主</li></ul><p>qemu-ga的好用之处在于其封装的指令兼容了一些不同的操作系统，比如写文件指令guest-file-write，既可以用于linux也可以用于windows。</p><p>关于qemu-ga的配置与使用，笔者之前已写过一篇文章《基于QMP实现对qemu虚拟机进行交互》，详细介绍其工作原理及基本使用方法，这里附上地址</p><p><a href="https://www.toutiao.com/i6646012291059810823/">https://www.toutiao.com/i6646012291059810823/</a></p><p>由于本文主题是“注入写文件”，因此接下来将重点阐述如何写文件，不过也会将qemu-ga的部署与启用方法再次贴出。</p><h2>Step1. 为VM配置channel</h2><p>通过libvirt启动的虚拟机，可以在XML里增加一段配置</p><pre><code class="lang-xml">&lt;channel type=&#039;unix&#039;&gt;
  &lt;source mode=&#039;bind&#039; path=&#039;/tmp/channel.sock&#039;/&gt;
  &lt;target type=&#039;virtio&#039; name=&#039;org.qemu.guest_agent.0&#039;/&gt;
&lt;/channel&gt;</code></pre><p>注意：上面这段配置要放在<devices>段落中</p><h2>Step2. 部署qemu-ga</h2><p>1️⃣ 安装qemu-ga</p><p>在VM内部安装并启动qemu-ga，linux和windows均支持qemu-ga，许多linux发行商都会提供自己的qemu-ga，比如rhel/centos、fedora、ubuntu、opensuse都有提供编译好的qemu-ga，可以直接下载使用。而windows系统需要下载virtio-win，其中有包含一些virtio的win驱动以及qemu-ga安装包，也可以仅下载qemu-ga安装包</p><pre><code class="lang-shell"># rhel/centos
yum install qemu-guest-agent</code></pre><pre><code class="lang-shell"># windows，最新virtio-win iso
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/
# windows，最新qemu-ga安装包
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-qemu-ga/</code></pre><p>windows的qemu-ga安装包如图所示</p><p><img src="https://pic.8oh.com.cn/cos/2021/08/02/9575b270c9291_1627871339.png" alt="103.png" title="103.png"><br>2️⃣ 启动qemu-ga</p><p>以centos7为例</p><pre><code class="lang-shell"># 启动qemu-ga守护进程
systemctl start qemu-guest-agent

# 加入开机启动
systemctl enable qemu-guest-agent</code></pre><p>启动后通过systemctl status qemu-guest-agent应当能看到进程已启动，如图所示<br><img src="https://pic.8oh.com.cn/cos/2021/08/02/b78a356f3f14e_1627871328.png" alt="102.png" title="102.png"><br>注意：有的qemu-ga会拒绝部分指令，这是因为qemu-ga的配置文件里将某些指令给禁用了，比如在centos7里，配置文件为<code>/etc/sysconfig/qemu-ga</code></p><pre><code class="lang-shell"># 修改/etc/sysconfig/qemu-ga，将以下内容注释掉，或直接删掉
BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status

# 重启qemu-ga才能生效
systemctl restart qemu-guest-agent</code></pre><p>3️⃣ 测试qemu-ga</p><p>在VM的宿主机上，执行以下命令：</p><pre><code class="lang-shell"># ${DOMAIN}表示虚拟机名字或UUID
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-ping&quot;}&#039;</code></pre><p>如果返回以下内容则表示qemu-ga可用</p><p><code>{&quot;return&quot;:{}}</code><br>接下来查看下qemu-ga支持哪些指令</p><p><code>virsh qemu-agent-command ${DOMAIN} --pretty &#039;{&quot;execute&quot;:&quot;guest-info&quot;}&#039;</code><br>应该会看到支持很多命令，由于接下来做的实验需要用到如下命令，因此请先确认是否均支持</p><ul><li>guest-exec：执行命令（异步操作）</li><li>guest-exec-status：查看执行命令的结果</li><li>guest-file-open：打开文件，获得句柄</li><li>guest-file-write：写文件（传递base64）</li><li>guest-file-close：关闭文件</li></ul><h2>Step3. 注入操作说明</h2><p>实验目标：将RSA的公钥内容写入到<code>/root/.ssh/authorized_keys</code></p><p>这涉及到如下3个步骤：</p><ol><li>创建/root/.ssh目录且权限为700</li><li>创建/root/.ssh/authorized_keys文件且权限为600</li><li>将RSA公钥文本进行Base64编码（guest-file-write不支持明文，仅支持base64），并将编码后的内容写入<code>/root/.ssh/authorized_keys</code></li></ol><h2>Step4. Base64计算</h2><p>这里先假设RSA公钥内容为</p><pre><code class="lang-shell">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVKog04pbbLaarjbpvK7CRaIuUwWxehJIH8tqtX/oV4GYN5WGYPFa1tzsd4Vyoblm4LePX79WeI4kFHgSbH5P6H9i8l3KCTFHHeJT/g0P55/c60yDb3o6lqpWu9IKE3I4lsTp05Y/W0Ks7W27Jndr162ni0Ybthgd9CQyoiburoh35ECiPGwWUOBVJ4IEpSpOZdDUJLS/vVuSQgvEH0fq/G1DP3SOyR+DNasJ00mwonfaUKHZXmWAlH8marNwPmWapyTSQwCFKKh1HwlJEWETV4fYuFwm3iennb8cX1y4aX9AJWnA2cc35rpulivMijeXs/ssT5iFljXXGYzmkX6nR root@localhost.localdomain</code></pre><p>进行Base64编码</p><pre><code class="lang-shell">echo &#039;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVKog04pbbLaarjbpvK7CRaIuUwWxehJIH8tqtX/oV4GYN5WGYPFa1tzsd4Vyoblm4LePX79WeI4kFHgSbH5P6H9i8l3KCTFHHeJT/g0P55/c60yDb3o6lqpWu9IKE3I4lsTp05Y/W0Ks7W27Jndr162ni0Ybthgd9CQyoiburoh35ECiPGwWUOBVJ4IEpSpOZdDUJLS/vVuSQgvEH0fq/G1DP3SOyR+DNasJ00mwonfaUKHZXmWAlH8marNwPmWapyTSQwCFKKh1HwlJEWETV4fYuFwm3iennb8cX1y4aX9AJWnA2cc35rpulivMijeXs/ssT5iFljXXGYzmkX6nR root@localhost.localdomain&#039; | base64 -w 0</code></pre><p>这样就获得了base64编码内容</p><pre><code class="lang-shell">c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFEVktvZzA0cGJiTGFhcmpicHZLN0NSYUl1VXdXeGVoSklIOHRxdFgvb1Y0R1lONVdHWVBGYTF0enNkNFZ5b2JsbTRMZVBYNzlXZUk0a0ZIZ1NiSDVQNkg5aThsM0tDVEZISGVKVC9nMFA1NS9jNjB5RGIzbzZscXBXdTlJS0UzSTRsc1RwMDVZL1cwS3M3VzI3Sm5kcjE2Mm5pMFlidGhnZDlDUXlvaWJ1cm9oMzVFQ2lQR3dXVU9CVko0SUVwU3BPWmREVUpMUy92VnVTUWd2RUgwZnEvRzFEUDNTT3lSK0ROYXNKMDBtd29uZmFVS0haWG1XQWxIOG1hck53UG1XYXB5VFNRd0NGS0toMUh3bEpFV0VUVjRmWXVGd20zaWVubmI4Y1gxeTRhWDlBSlduQTJjYzM1cnB1bGl2TWlqZVhzL3NzVDVpRmxqWFhHWXpta1g2blIgcm9vdEBsb2NhbGhvc3QubG9jYWxkb21haW4K</code></pre><h2>Step5. 开始注入</h2><p>1️⃣ 创建/root/.ssh目录且权限为700</p><pre><code class="lang-shell"># mkdir /root/.ssh
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec&quot;,&quot;arguments&quot;:{&quot;path&quot;:&quot;mkdir&quot;,&quot;arg&quot;:[&quot;-p&quot;,&quot;/root/.ssh&quot;],&quot;capture-output&quot;:true}}&#039;

# 假设上一步返回{&quot;return&quot;:{&quot;pid&quot;:911}}，接下来查看结果（通常可忽略）
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec-status&quot;,&quot;arguments&quot;:{&quot;pid&quot;:911}}&#039; 

# chmod 700 /root/.ssh，此行其实可不执行，因为上面创建目录后就是700，但为了防止权限不正确导致无法使用，这里还是再刷一次700比较稳妥
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec&quot;,&quot;arguments&quot;:{&quot;path&quot;:&quot;chmod&quot;,&quot;arg&quot;:[&quot;700&quot;,&quot;/root/.ssh&quot;],&quot;capture-output&quot;:true}}&#039; 

# 假设上一步返回{&quot;return&quot;:{&quot;pid&quot;:912}}，接下来查看结果（通常可忽略）
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec-status&quot;,&quot;arguments&quot;:{&quot;pid&quot;:912}}&#039;</code></pre><p>2️⃣ 创建/root/.ssh/authorized_keys文件且权限为600</p><pre><code class="lang-shell"># touch /root/.ssh/authorized_keys
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec&quot;,&quot;arguments&quot;:{&quot;path&quot;:&quot;touch&quot;,&quot;arg&quot;:[&quot;/root/.ssh/authorized_keys&quot;],&quot;capture-output&quot;:true}}&#039;

# 假设上一步返回{&quot;return&quot;:{&quot;pid&quot;:913}}，接下来查看结果（通常可忽略）
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec-status&quot;,&quot;arguments&quot;:{&quot;pid&quot;:913}}&#039;

# chmod 600 /root/.ssh/authorized_keys，此行其实可不执行，因为上面创建文件后就是600，但为了防止权限不正确导致无法使用，这里还是再刷一次600比较稳妥
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec&quot;,&quot;arguments&quot;:{&quot;path&quot;:&quot;chmod&quot;,&quot;arg&quot;:[&quot;600&quot;,&quot;/root/.ssh/authorized_keys&quot;],&quot;capture-output&quot;:true}}&#039;

# 假设上一步返回{&quot;return&quot;:{&quot;pid&quot;:914}}，接下来查看结果（通常可忽略）
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-exec-status&quot;,&quot;arguments&quot;:{&quot;pid&quot;:914}}&#039;</code></pre><p>3️⃣ 将Base64编码写入/root/.ssh/authorized_keys</p><pre><code class="lang-shell"># 打开文件（以读写方式打开），获得句柄
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-file-open&quot;, &quot;arguments&quot;:{&quot;path&quot;:&quot;/root/.ssh/authorized_keys&quot;,&quot;mode&quot;:&quot;w+&quot;}}&#039;

# 写文件，假设上一步返回{&quot;return&quot;:1000}，1000就是句柄
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-file-write&quot;, &quot;arguments&quot;:{&quot;handle&quot;:1000,&quot;buf-b64&quot;:&quot;c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFEVktvZzA0cGJiTGFhcmpicHZLN0NSYUl1VXdXeGVoSklIOHRxdFgvb1Y0R1lONVdHWVBGYTF0enNkNFZ5b2JsbTRMZVBYNzlXZUk0a0ZIZ1NiSDVQNkg5aThsM0tDVEZISGVKVC9nMFA1NS9jNjB5RGIzbzZscXBXdTlJS0UzSTRsc1RwMDVZL1cwS3M3VzI3Sm5kcjE2Mm5pMFlidGhnZDlDUXlvaWJ1cm9oMzVFQ2lQR3dXVU9CVko0SUVwU3BPWmREVUpMUy92VnVTUWd2RUgwZnEvRzFEUDNTT3lSK0ROYXNKMDBtd29uZmFVS0haWG1XQWxIOG1hck53UG1XYXB5VFNRd0NGS0toMUh3bEpFV0VUVjRmWXVGd20zaWVubmI4Y1gxeTRhWDlBSlduQTJjYzM1cnB1bGl2TWlqZVhzL3NzVDVpRmxqWFhHWXpta1g2blIgcm9vdEBsb2NhbGhvc3QubG9jYWxkb21haW4K&quot;}}&#039;

# 关闭文件
virsh qemu-agent-command ${DOMAIN} &#039;{&quot;execute&quot;:&quot;guest-file-close&quot;, &quot;arguments&quot;:{&quot;handle&quot;:1000}}&#039;</code></pre><p>查看效果：此时到VM里查看<code>/root/.ssh/authorized_keys</code>，应该能看到新增加的一行</p><h1>附录</h1><h2>附1. qemu-ga支持的所有指令</h2><p>不同的qemu-ga版本、不同的操作系统，支持的指令都会有所差异，下面是从官网上看到的当前所有参数</p><ul><li>guest-exec</li><li>guest-exec-status</li><li>guest-file-close</li><li>guest-file-flush</li><li>guest-file-open</li><li>guest-file-read</li><li>guest-file-seek</li><li>guest-file-write</li><li>guest-fsfreeze-freeze</li><li>guest-fsfreeze-freeze-list</li><li>guest-fsfreeze-status</li><li>guest-fsfreeze-thaw</li><li>guest-fstrim</li><li>guest-get-fsinfo</li><li>guest-get-host-name</li><li>guest-get-memory-block-info</li><li>guest-get-memory-blocks</li><li>guest-get-osinfo</li><li>guest-get-time</li><li>guest-get-timezone</li><li>guest-get-users</li><li>guest-get-vcpus</li><li>guest-info</li><li>guest-network-get-interfaces</li><li>guest-ping</li><li>guest-set-memory-blocks</li><li>guest-set-time</li><li>guest-set-user-password</li><li>guest-set-vcpus</li><li>guest-shutdown</li><li>guest-suspend-disk</li><li>guest-suspend-hybrid</li><li>guest-suspend-ram</li><li>guest-sync</li><li>guest-sync-delimited</li></ul><p>具体使用方法，请参考官网文档<br><a href="https://qemu.weilnetz.de/doc/qemu-ga-ref.html">https://qemu.weilnetz.de/doc/qemu-ga-ref.html</a></p><h2>附2. 配置多个channel</h2><p>1️⃣ 可以在XML里配置多个channel，这样就可以创建多个设备通道</p><pre><code class="lang-xml">&lt;channel type=&#039;unix&#039;&gt;
  &lt;source mode=&#039;bind&#039; path=&#039;/tmp/channel.sock&#039;/&gt;
  &lt;target type=&#039;virtio&#039; name=&#039;org.qemu.guest_agent.0&#039;/&gt;
&lt;/channel&gt;
&lt;channel type=&#039;unix&#039;&gt;
  &lt;source mode=&#039;bind&#039; path=&#039;/tmp/channel.sock-1&#039;/&gt;
  &lt;target type=&#039;virtio&#039; name=&#039;org.qemu.guest_agent.1&#039;/&gt;
&lt;/channel&gt;</code></pre><p>2️⃣ 在VM里要启动2个qemu-ga守护进程，可以将原有的service文件拷贝一份出来进行修改</p><pre><code class="lang-shell">cd /usr/lib/systemd/system
cp qemu-guest-agent.service qemu-guest-agent-1.service</code></pre><p>然后修改<code>qemu-guest-agent-1.service</code><br><img src="https://pic.8oh.com.cn/cos/2021/08/02/160c5b121ae49_1627871276.png" alt="101.png" title="101.png"><br>3️⃣ 启动服务</p><pre><code class="lang-shell">systemctl start qemu-guest-agent-1</code></pre><h1>参考文档</h1><ul><li>qemu-ga介绍与使用：QEMU Guest Agent</li><li>qemu-ga完整参数：<a href="https://qemu.weilnetz.de/doc/qemu-ga-ref.html">https://qemu.weilnetz.de/doc/qemu-ga-ref.html</a></li><li>笔者另一篇相关文章《基于QMP实现对qemu虚拟机进行交互》：<a href="https://www.toutiao.com/i6646012291059810823/">https://www.toutiao.com/i6646012291059810823/</a></li></ul>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/92/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>hetzner centos kvm 网卡桥接</title>
<link>https://dwt.life/archives/86/</link>
<guid>https://dwt.life/archives/86/</guid>
<pubDate>Thu, 29 Jul 2021 20:46:49 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[首先装两个依赖：yum -y install net-tools bridge-utils新建一个br0网卡：vi /etc/sysconfig/network-scripts/ifcfg-br...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>首先装两个依赖：</p><p><code>yum -y install net-tools bridge-utils</code><br>新建一个br0网卡：</p><p><code>vi /etc/sysconfig/network-scripts/ifcfg-br0</code><br>写入：</p><pre><code>DEVICE=br0
TYPE=Bridge
BOOTPROTO=none
IPADDR=服务器的公网IP
NETMASK=子网掩码
SCOPE=&quot;peer 网关IP&quot;
ONBOOT=yes
DELAY=0
IPV6INIT=yes</code></pre><p>然后再新建一个路由：</p><p><code>vi /etc/sysconfig/network-scripts/route-br0</code><br>写入：</p><pre><code>ADDRESS0=0.0.0.0
NETMASK0=0.0.0.0
GATEWAY0=网关IP</code></pre><p>重要！现在就重启你的网卡：</p><p><code>/etc/init.d/network restart</code><br>重启完成之后，编辑主网卡配置文件：</p><p><code>vi /etc/sysconfig/network-scripts/ifcfg-enp3s0</code><br>写入：</p><pre><code>DEVICE=enp3s0
HWADDR=服务器MAC地址
IPV6INIT=yes
ONBOOT=yes
BRIDGE=br0</code></pre><p>然后再重启一遍网卡：</p><p><code>/etc/init.d/network restart</code><br>如果没有意外，你做完这些事情之后，你的服务器依旧可以联网。</p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/86/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>安裝winsrv2016在CentOS KVM上</title>
<link>https://dwt.life/archives/85/</link>
<guid>https://dwt.life/archives/85/</guid>
<pubDate>Wed, 28 Jul 2021 16:41:29 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[https://www.cnblogs.com/silvermagic/p/7666153.htmlhttps://blog.skywebster.com/install-winsrv2016-...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><a href="https://www.cnblogs.com/silvermagic/p/7666153.html">https://www.cnblogs.com/silvermagic/p/7666153.html</a><br><a href="https://blog.skywebster.com/install-winsrv2016-on-centos-kvm/">https://blog.skywebster.com/install-winsrv2016-on-centos-kvm/</a></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/85/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>KVM Cgroup</title>
<link>https://dwt.life/archives/83/</link>
<guid>https://dwt.life/archives/83/</guid>
<pubDate>Wed, 21 Jul 2021 11:40:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[mkdir /sys/fs/cgroup/cpu/vmaecho 10339 &gt; /sys/fs/cgroup/cpu/vma/cgroup.procscat  /sys/fs/cgrou...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>mkdir /sys/fs/cgroup/cpu/vma
echo 10339 &gt; /sys/fs/cgroup/cpu/vma/cgroup.procs
cat  /sys/fs/cgroup/cpu/vma/
cat  /sys/fs/cgroup/cpu/vma/cpu.cfs_period_us 
echo 30000 &gt; /sys/fs/cgroup/cpu/vma/cpu.cfs_quota_us</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/83/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>kvm环境预安装</title>
<link>https://dwt.life/archives/80/</link>
<guid>https://dwt.life/archives/80/</guid>
<pubDate>Tue, 20 Jul 2021 15:16:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[#先安装 qemu-kvm-rhevecho &quot;[qemu-kvm-rhev]name=oVirt rebuilds of qemu-kvm-rhevbaseurl=http://re...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>#先安装 qemu-kvm-rhev
echo &quot;[qemu-kvm-rhev]
name=oVirt rebuilds of qemu-kvm-rhev
baseurl=http://resources.ovirt.org/pub/ovirt-3.5/rpm/el7Server/
mirrorlist=http://resources.ovirt.org/pub/yum-repo/mirrorlist-ovirt-3.5-el7Server
enabled=1
skip_if_unavailable=1
gpgcheck=0
&quot; &gt; /etc/yum.repos.d/qemu-kvm-rhev.repo
yum install bridge-utils qemu-kvm-rhev centos-release-qemu-ev qemu-img virt-manager libvirt libvirt-daemon-kvm libvirt-python virt-manager libvirt-client virt-install virt-viewer libguestfs libguestfs-tools libguestfs-winsupport -y
yum install -y libvirt-devel gcc
export LIBGUESTFS_BACKEND=direct
service libvirtd start
systemctl enable libvirtd
systemctl start libvirtd
firewall-cmd  --permanent --zone=trusted --add-port=1234/tcp --permanent
firewall-cmd --reload
wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo -O /etc/yum.repos.d/virtio-win.repo

yum install virtio-win</code></pre><p>更新：<br>关于hz的出口，不可以直接绑定br0<br>创建public<br>支持ipv4转发<br>1.临时开启，（写入内存，在内存中开启）</p><p>echo "1" &gt; /proc/sys/net/ipv4/ip_forward</p><p>2.永久开启，（写入内核）</p><p>在 vim /etc/sysctl.conf 下</p><p>加入此行 net.ipv4.ip_forward = 1</p><p>sysctl -p      # 加载一下，使之生效</p><p>3.防火墙放通转发（以iptables为例）</p><p>iptables -I FORWARD -j ACCEPT</p><p>service iptables save</p><p>如果save不存在，则</p><p>首先停止防火墙</p><p>1.systemctl stop firewalld</p><p>2.systemctl mask firewalld<br>然后安装iptables-services</p><p>3.yum install iptables-services<br>设置开机启动防火墙</p><p>4.systemctl enable iptables<br>可以使用下面命令管理iptables</p><p>5.systemctl [stop|start|restart] iptables<br>这时可以保存防火墙规则了</p><p>6.service iptables save<br>or<br>/usr/libexec/iptables/iptables.init save</p><p>如果存在网络异常，则systemctl restart network</p><p>更新<br>Windows server 2016存在蓝屏问题，解决方法：</p><pre><code>echo 1 &gt; /sys/module/kvm/parameters/ignore_msrs
echo 0 &gt; /sys/module/kvm/parameters/report_ignored_msrs
echo &quot;options kvm ignore_msrs=1 report_ignored_msrs=N&quot; | sudo tee /etc/modprobe.d/kvm-ignore-msrs.conf</code></pre><p>supervisor</p><pre><code>yum install supervisor -y
systemctl enable supervisord
echo &quot;
[program:node]
directory = /root/node/ ; 程序的启动目录
command = /root/node/node ; 启动命令，可以看出与手动在命令行启动的命令是一样的
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 5        ; 启动 5 秒后没有异常退出，就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数，默认是 3
redirect_stderr = true  ; 把 stderr 重定向到 stdout，默认 false
stdout_logfile_maxbytes = 20MB  ; stdout 日志文件大小，默认 50MB
stdout_logfile_backups = 20     ; stdout 日志文件备份数
stdout_logfile = /root/node/stdout.log
&quot; &gt; /etc/supervisord.d/node.ini

mkdir /etc/libvirt/hooks
for f in daemon qemu lxc libxl network; do   echo &#039;#!/bin/sh
iptables-restore &lt; /etc/sysconfig/iptables
iptables -I FORWARD -j ACCEPT&#039; &gt; &quot;/etc/libvirt/hooks/$f&quot;;   chmod +x &quot;/etc/libvirt/hooks/$f&quot;; done

service libvirtd restart</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/80/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
<item>
<title>kvm 网卡桥接设置</title>
<link>https://dwt.life/archives/79/</link>
<guid>https://dwt.life/archives/79/</guid>
<pubDate>Tue, 20 Jul 2021 10:08:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[桥接设置相当于将br0作为交换机，eth/ens以及kvm作为主机连接到br0上。/etc/sysconfig/network-scripts/ifcfg-br0TYPE=BridgeBOOTP...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>桥接设置相当于将br0作为交换机，eth/ens以及kvm作为主机连接到br0上。<br>/etc/sysconfig/network-scripts/ifcfg-br0</p><pre><code>TYPE=Bridge
BOOTPROTO=static
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.119.22
GATEWAY=192.168.119.2
NETMASK=255.255.255.0</code></pre><pre><code>DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BRIDGE=br0</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/79/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/kvm/</wfw:commentRss>
</item>
</channel>
</rss>