长期支持版本

    社区创新版本

      1 虚拟化管理面无感卸载

      1.1 简介

      虚拟化管理面,即libvirtd,而虚拟化管理面卸载,即是将libvirtd卸载到虚拟机所在机器(以下称为host)之外的另一台机器(以下称为DPU)上运行。

      我们使用了qtfs将host的一些与虚拟机运行相关的目录挂载到DPU上,使得虚拟化管理面工具可以访问到这些目录,为kvm虚拟机准备运行所需要的环境,此处,因为需要挂载远端的proc和sys,所以,我们创建了一个专门的rootfs以作为libvirtd的运行环境(以下称为/another_rootfs)。

      并且通过rexec执行虚拟机的拉起、删除等操作,使得可以将虚拟化管理面和虚拟机分离在不同的两台机器上,远程对虚拟机进行管理。

      1.2 相关组件介绍

      1.2.1 rexec介绍

      rexec是一个用c语言开发的远程执行组件,分为rexec client和rexec server。server端为一个常驻服务进程,client端为一个二进制文件,client端被执行后会基于udsproxyd服务与server端建立uds连接,并由server常驻进程在server端拉起指定程序。在libvirt虚拟化卸载中,libvirtd卸载到DPU上,当它需要在HOST拉起虚拟机qemu进程时调起rexec client进行远程拉起。

      2 操作环境

      物理机操作系统: openEuler 22.03 LTS 及之后的版本

      libvirt版本: libvirt-6.9.0

      qemu版本:6.2.0

      文件下载列表:

      git clone https://gitee.com/openeuler/dpu-utilities.git
      cd dpu-utilities/qtfs/rexec/
      make
      yes | cp ./rexec* /usr/bin/
      
        1. DPU 机器上下载对应软件包和库文件 qtfs.ko, libvirt-6.9.0.tat.xz
        1. host 机器上安装qemu
      yum install qemu
      

      3 虚拟化管理面卸载操作指南

      说明:

      1. 在host端和DPU端,都要拉起rexec_server;host侧可使用 [dpu IP]:[dpu rexec端口号] 远程操作DPU上的二进制,反之亦然;
      2. host端拉起rexec_server,主要是用于DPU创建虚拟机时用rexec拉起qemu-kvm;

      3.1 拉起rexec_server

      3.1.1 拷贝二进制文件

      rexec_server安装到DPU和host上

      cp rexec_server /usr/bin/
      chmod +x rexec_server
      

      3.1.2 配置rexec_server服务

      为方便起见,可以将rexec_server作为一个systemd服务;

      1. 同时在DPU和host上的/usr/lib/systemd/system/目录下,添加rexec.service服务文件,内容如下:

      /usr/lib/systemd/system/rexec.service,service文件中的<端口号>根据用户的意愿自行分配

      [Unit]
      Description=Rexec_server Service
      After=network.target
      
      [Service]
      Type=simple
      Environment=CMD_NET_ADDR=tcp://0.0.0.0:<端口号>
      ExecStart=/usr/bin/rexec_server
      ExecReload=/bin/kill -s HUP $
      KillMode=process
      
      [Install]
      WantedBy=multi-user.target
      
      1. 通过systemctl start rexec,拉起rexec_server服务。
      systemctl daemon-reload
      systemctl enable --now rexec
      

      3.1.3 rexec操作示例

      配置好rexec_server服务后,如果要在DPU上调用host上的二进制,可先将rexec拷贝到/usr/bin下面,再使用如下命令远程执行对端服务器上的二进制;

      CMD_NET_ADDR=tcp://<host ip>:<host端rexec_server端口号> rexec [要执行的指令]
      

      例如,在DPU上操作host(假设ip为192.168.1.1,rexec端口号为6666)上的ls指令:

      CMD_NET_ADDR=tcp://192.168.1.1:6666 rexec /usr/bin/ls
      

      补充说明:

      如果不想systemd服务的形式拉起rexec_server,可使用命令手动拉起。

      例如,在host端执行CMD_NET_ADDR=tcp://0.0.0.0:<端口号> rexec_server 命令,可拉起rexec_server进程;

      3.2 准备libvirtd运行的rootfs

      注:本步骤仅需在DPU上执行

      在下面的文档中,我们将这个rootfs称为/another_rootfs(具体的目录名称,可以根据自己的需求进行调整)

      rootfs可使用如下3.2.1或3.2.2两种方案之一,推荐使用openEuler官方qcow2镜像。在准备好rootfs后,按照3.2.3中的方式,向/another_rootfs中安装软件包

      3.2.1 拷贝根目录

      一般来说,只需要将根目录直接拷贝到这个文件夹即可

      请使用如下命令操作拷贝动作

      mkdir /another_rootfs
      cp -r /usr /another_rootfs
      cp -r /sbin /another_rootfs
      cp -r /bin /another_rootfs
      cp -r /lib64 /another_rootfs
      cp -r /lib /another_rootfs
      mkdir /another_rootfs/boot
      mkdir /another_rootfs/dev
      mkdir /another_rootfs/etc
      mkdir /another_rootfs/home
      mkdir /another_rootfs/mnt
      mkdir /another_rootfs/opt
      mkdir /another_rootfs/proc
      mkdir /another_rootfs/root
      mkdir /another_rootfs/run
      mkdir /another_rootfs/var
      mkdir /another_rootfs/etc
      mkdir /another_rootfs/sys
      mkdir /another_rootfs/local_proc
      

      3.2.2 使用openEuler官方qcow2镜像

      如果根目录并非完全干净的新环境,可以使用openEuler官方提供的qcow2镜像,来准备一个新的rootfs:

      3.2.2.1 工具安装

      需要用yum安装xz、kpartx、qemu-img

      yum install xz kpartx qemu-img
      

      3.2.2.2 下载qcow2镜像

      在openEuler官网获取22.03版本openEuler-x86虚拟机镜像(x86架构),或者22.03版本openEuler-arm64虚拟机镜像(ARM架构)。

      3.2.2.3 解压qcow2镜像

      使用xz -d解压为openEuler-22.03-LTS-.qcow2文件, 以x86镜像为例

      xz -d openEuler-22.03-LTS-x86_64.qcow2.xz
      

      3.2.2.4 挂载qcow2镜像并拷贝文件

      1. 使用modprobe nbd maxpart=<任意数字>来加载nbd模块
      2. qemu-nbd -c /dev/nbd0 <虚拟机镜像的路径>
      3. 创建任意文件夹/random_dir
      4. 执行挂载mount /dev/nbd0p2 /random_dir
      5. 拷贝文件
      mkdir /another_rootfs
      cp -r /random_dir/* /another_rootfs/
      

      此时,虚拟机镜像便已经挂载到当前文件夹中了;

      3.2.2.5 卸载qcow2

      在准备好rootfs后,需要卸载qcow2文件,此时,需要执行如下指令:

      umount /random_dir
      qemu-nbd -d /dev/nbd0
      

      3.3 在host侧拉起qtfs_server

      创建容器管理面所需要的文件夹,然后插入qtfs_server.ko,并拉起engine进程。

      可以用如下脚本来执行此操作,如果执行错误,可能需要dos2unix来将此脚本的格式转换(如下所有脚本皆同理)。注意,在最后两行,需要将qtsf_server.ko和engine的路径填写为存放这两个组件的路径。

      #!/bin/bash
      mkdir /var/lib/libvirt
      
      insmod <ko路径>/qtfs_server.ko qtfs_server_ip=0.0.0.0 qtfs_log_level=INFO #此处需要自行修改ko的路径
      <engine路径>/engine 4096 16 #此处需要自行修改engine的路径
      

      3.4 UDSPROXYD服务部署

      3.4.1 简介

      udsproxyd是一个跨主机的unix domain socket代理服务,需要分别部署在host和dpu上,在host和dpu上的udsproxyd组件是对等的关系,可以实现分布在host与dpu上的2个进程之间的uds通信,通信进程是无感的,也就是说如果这两个进程在同一主机内通过uds正常通信的功能,拉远到host和dpu之间也可以,不需要做代码适配,只需要作为client的一端加一个环境变量LD_PRELOAD=libudsproxy.so

      3.4.2 部署方式

      首先,在dpu-utilities工程内编译udsproxyd:

      cd qtfs/ipc
      
      make && make install
      

      当前最新版本下,qtfs server侧的engine服务已经整合了udsproxyd的能力,所以server侧若部署了qtfs后不需要再额外启动udsproxyd。client侧则单独拉起udsproxyd服务:

      nohup /usr/bin/udsproxyd <thread num> <addr> <port> <peer addr> <peer port> 2>&1 &

      参数解释:

      thread num: 线程数量,目前只支持单线程,填1.
      
      addr: 本机使用的ip
      
      port:本机占用的port
      
      peer addr: udsproxyd对端的ip
      
      peer port: 对端port
      

      示例:

      nohup /usr/bin/udsproxyd 1 192.168.10.10 12121 192.168.10.11 12121 2>&1 &

      如果未拉起qtfs的engine服务,想单独测试udsproxyd,则在server端也对等拉起udsproxyd即可:nohup /usr/bin/udsproxyd 1 192.168.10.11 12121 192.168.10.10 12121 2>&1 &

      然后将libudsproxy.so拷贝到libvirt的chroot目录下的/usr/lib64中以提供给libvirtd服务使用,这一步在后面介绍。

      3.5 挂载host上依赖目录至DPU

      3.5.1 安装软件包

      3.5.2.1 在根目录的安装

      1. 在/another_rootfs中安装libvirt-client
      yum install libvirt-client
      

      3.5.2.2 another_rootfs环境配置

      1. /another_rootfs中,安装libvirtd;
      cd /another_rootfs
      tar -xf <path_to>/libvirtd-6.9.0.tar.xz #此处需要改动libvirtd-6.9.0.tar.xz的路径
      cd libvirtd-6.9.0
      patch -p1 < 0001-libvirt_6.9.0_1201_offload.patch #此处需要改动path_to_patch的路径为libvirt的patch路径,并按顺序一个一个打入patch
      patch -p1 < 0003-fix-get-affinity.patch #此处需要改动path_to_patch的路径为libvirt的patch路径,并按顺序一个一个打入patch
      patch -p1 < 0004-qmp-port-manage.patch #此处需要改动path_to_patch的路径为libvirt的patch路径,并按顺序一个一个打入patch
      chroot /another_rootfs
      yum groupinstall "Development tools" -y
      yum install -y vim meson qemu qemu-img strace edk2-aarch64 tar
      
      yum install -y rpcgen python3-docutils glib2-devel gnutls-devel libxml2-devel libpciaccess-devel libtirpc-devel yajl-devel systemd-devel dmidecode glusterfs-api numactl
      
      cd /libvirtd-6.9.0
      
      CFLAGS='-Wno-error=format -Wno-error=int-conversion -Wno-error=implicit-function-declaration -Wno-error=nested-externs -Wno-error=declaration-after-statement -Wno-error=unused-result -Wno-error=missing-prototypes -Wno-error=int-conversion -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=pointer-sign -Wno-error=discarded-qualifiers -Wno-error=unused-function' meson build --prefix=/usr -Ddriver_remote=enabled -Ddriver_network=enabled -Ddriver_qemu=enabled -Dtests=disabled -Ddocs=enabled -Ddriver_libxl=disabled -Ddriver_esx=disabled -Dsecdriver_selinux=disabled -Dselinux=disabled
      
      ninja -C build install
      exit
      
      1. 并需要将rexec拷贝到/another_rootfs/usr/bin下面,并对其添加可执行权限
      cp rexec /another_rootfs/usr/bin
      chmod +x /another_rootfs/usr/bin/rexec
      
      1. /another_rootfs中,通过如下脚本创建脚本/usr/bin/qemu-kvm, /usr/libexec/qemu-kvm,此脚本需要将<host的ip>和<rexec server端口>改为host的ip和host上rexec_server的端口号
      chroot /another_rootfs
      touch /usr/bin/qemu-kvm
      touch /usr/libexec/qemu-kvm
      cat > /usr/bin/qemu-kvm <<EOF
      #!/bin/bash
      host=<host的ip>
      port=<rexec server端口>
      CMD_NET_ADDR=tcp://\$host:\$port exec /usr/bin/rexec /usr/bin/qemu-kvm \$*
      EOF
      cat > /usr/libexec/qemu-kvm <<EOF
      #!/bin/bash
      host=<host的ip>
      port=<rexec server端口>
      CMD_NET_ADDR=tcp://\$host:\$port exec /usr/bin/rexec /usr/bin/qemu-kvm \$*
      EOF
      chmod +x /usr/libexec/qemu-kvm
      chmod +x /usr/bin/qemu-kvm
      exit
      

      3.5.2.3 目录挂载

      在DPU上执行如下的脚本,将libvirtd所需要的host目录挂载到DPU。

      并且,需要确保在以下脚本 prepare.sh 中被挂载的远程目录在host和DPU都存在。

      #!/bin/bash
      insmod <qtfs.ko路径>/qtfs.ko qtfs_server_ip=<server ip> qtfs_log_level=INFO #此处需要改动qtfs.ko的路径,并改动<server ip>
      
      systemctl stop libvirtd
       
      mkdir -p /var/run/rexec/pids
      cat >/var/run/rexec/qmpport << EOF
      <qmp端口号>
      EOF
      cat > /var/run/rexec/hostaddr <<EOF
      <服务端ip>
      EOF
      cat > /var/run/rexec/rexecport << EOF
      <rexec端口号>
      EOF
      
      rm -f `find /var/run/libvirt/ -name "*.pid"`
      rm -f /var/run/libvirtd.pid
      
      if [ ! -d "/another_rootfs/local_proc" ]; then
          mkdir -p /another_rootfs/local_proc
      fi
      if [ ! -d "/another_rootfs/local" ]; then
          mkdir -p /another_rootfs/local
      fi
      mount -t proc proc /another_rootfs/local_proc/
      mount -t proc proc /another_rootfs/local/proc
      mount -t sysfs sysfs /another_rootfs/local/sys
      mount --bind /var/run/ /another_rootfs/var/run/
      mount --bind /var/lib/ /another_rootfs/var/lib/
      mount --bind /var/cache/ /another_rootfs/var/cache
      mount --bind /etc /another_rootfs/etc
      
      mkdir -p /another_rootfs/home/VMs/
      mount -t qtfs /home/VMs/ /another_rootfs/home/VMs/
      
      mount -t qtfs /var/lib/libvirt /another_rootfs/var/lib/libvirt
      
      mount -t devtmpfs devtmpfs /another_rootfs/dev/
      mount -t hugetlbfs hugetlbfs /another_rootfs/dev/hugepages/
      mount -t mqueue mqueue /another_rootfs/dev/mqueue/
      mount -t tmpfs tmpfs /another_rootfs/dev/shm
      
      mount -t sysfs sysfs /another_rootfs/sys
      mkdir -p /another_rootfs/sys/fs/cgroup
      mount -t tmpfs tmpfs /another_rootfs/sys/fs/cgroup
      list="perf_event freezer files net_cls,net_prio hugetlb pids rdma cpu,cpuacct memory devices blkio cpuset"
      for i in $list
      do
              echo $i
              mkdir -p /another_rootfs/sys/fs/cgroup/$i
              mount -t cgroup cgroup -o rw,nosuid,nodev,noexec,relatime,$i /another_rootfs/sys/fs/cgroup/$i
      done
      
      ## common system dir
      mount -t qtfs -o proc /proc /another_rootfs/proc
      echo "proc"
      
      mount -t qtfs /sys /another_rootfs/sys
      echo "cgroup"
      mount -t qtfs /dev/pts /another_rootfs/dev/pts
      mount -t qtfs /dev/vfio /another_rootfs/dev/vfio
      

      3.6 拉起libvirtd

      在DPU上,打开一个窗口,并且chroot到/another_rootfs

      chroot /another_rootfs
      

      用如下的命令先拉起virtlogd,后拉起virtlogd

      #!/bin/bash
      virtlogd -d
      libvirtd -d
      

      因为我们已经将/var/run//another_rootfs/var/run/绑定在了一起,所以,我们可以在正常的rootfs下,通过virsh来访问libvirtd,从而管理容器。

      4 环境恢复

      如果需要卸载相关的目录,需要执行如下指令

      #!/bin/bash
      
      umount /root/p2/dev/hugepages
      umount /root/p2/etc
      umount /root/p2/home/VMs
      umount /root/p2/local_proc
      umount /root/p2/var/lib/libvirt
      umount /root/p2/var/lib
      umount /root/p2/*
      umount /root/p2/dev/pts
      umount /root/p2/dev/mqueue
      umount /root/p2/dev/shm
      umount /root/p2/dev/vfio
      umount /root/p2/dev
      rmmod qtfs
      
      umount /root/p2/sys/fs/cgroup/*
      umount /root/p2/sys/fs/cgroup
      umount /root/p2/sys
      

      文档捉虫

      “有虫”文档片段

      问题描述

      提交类型 issue

      有点复杂...

      找人问问吧。

      PR

      小问题,全程线上修改...

      一键搞定!

      问题类型
      规范和低错类

      ● 错别字或拼写错误;标点符号使用错误;

      ● 链接错误、空单元格、格式错误;

      ● 英文中包含中文字符;

      ● 界面和描述不一致,但不影响操作;

      ● 表述不通顺,但不影响理解;

      ● 版本号不匹配:如软件包名称、界面版本号;

      易用性

      ● 关键步骤错误或缺失,无法指导用户完成任务;

      ● 缺少必要的前提条件、注意事项等;

      ● 图形、表格、文字等晦涩难懂;

      ● 逻辑不清晰,该分类、分项、分步骤的没有给出;

      正确性

      ● 技术原理、功能、规格等描述和软件不一致,存在错误;

      ● 原理图、架构图等存在错误;

      ● 命令、命令参数等错误;

      ● 代码片段错误;

      ● 命令无法完成对应功能;

      ● 界面错误,无法指导操作;

      风险提示

      ● 对重要数据或系统存在风险的操作,缺少安全提示;

      内容合规

      ● 违反法律法规,涉及政治、领土主权等敏感词;

      ● 内容侵权;

      您对文档的总体满意度

      非常不满意
      非常满意
      提交
      根据您的反馈,会自动生成issue模板。您只需点击按钮,创建issue即可。
      文档捉虫
      编组 3备份