• 搭建 KVM 虚拟化系统


    最近阅读了韦易笑(Github/知乎)专栏我爱命令行中的三篇文章:

    这三篇文章介绍了 KVM 虚拟化的搭建和家庭 NAS 方案,看得我心痒痒的。恰好自己在学校有动态公网 IP,就从咸鱼买了两条 16G 内存,加上一块 2T 监控硬盘,把台式机虚拟化作服务器。

    我在 Debian10 上搭建 KVM 虚拟化环境,在虚拟机中创建 OpenMediaVault(NAS)和 Windows10 。这里主要有三个问题:

    • 如何管理虚拟机?使用 WebVirtCloud 图形化地管理虚拟机。
    • 如何管理存储?使用 mapped 模式让虚拟机共享物理机硬盘。
    • 如何管理网络?使用桥接模式实现虚拟机联网。

    物理机仅用于虚拟化和为虚拟机提供硬盘,不做多余的事情。

    机器配置

    • CPU: AMD Ryzen 3 3200GE
    • GPU: 核显
    • 硬盘:512G SSD 和 2T HDD
    • 主板:迫击炮 PRO A MAX

    安装 Debian10

    因为 WebVirtCloud 支持在 Debian10 上自动安装,并且 Debian 是最重要的开源项目之一,所以这里选择 Debian10。

    安装无 GUI 版本即可,这样可以节约系统资源。使用 GUI 安装器安装,在设置磁盘分区时,选择“仅使用一个分区”,使用 btrfs 文件系统。事实上,btrfs 支持在不分区上的硬盘上安装,但是 Debian10 没有提供这个安装选项。安装完成后,如果确实想要类似于分区的效果,可以再为 home 等目录创建 btrfs 子卷。

    以下是我的 OS 信息。

           _,met$$$$$gg.
        ,g$$$$$$$$$$$$$$$P.
      ,g$$P"     """Y$$.".
     ,$$P'              `$$$.
    ',$$P       ,ggs.     `$$b:
    `d$$'     ,$P"'   .    $$$
     $$P      d$'     ,    $$P    root@Thursday
     $$:      $$.   -    ,d$$'    -------------
     $$;      Y$b._   _,d$P'      OS: Debian GNU/Linux 10 (buster) x86_64
     Y$$.    `.`"Y$$$$P"'         Host: MS-7C52 1.0
     `$$b      "-.__              Kernel: 4.19.0-18-amd64
      `Y$$                        Uptime: 5 hours, 50 mins
       `Y$$.                      Packages: 1000 (dpkg)
         `$$b.                    Shell: bash 5.0.3
           `Y$$b.                 Terminal: /dev/pts/3
              `"Y$b._             CPU: AMD Ryzen 3 3200GE (4) @ 2.770GHz
                  `"""            GPU: AMD ATI Picasso
                                  Memory: 19689MiB / 30097MiB
    

    配置 ssh

    安装完成后首先要配置 ssh 服务器,以便远程登录操作。默认情况下,Debian 已经启用了 ssh 服务器,如果没有,请用以下命令安装:

    apt install -y openssh-server
    

    然后启用 ssh 服务器:

    systemctl restart ssh # 重启 ssh 服务
    systemctl enable ssh # 开机自动启动 ssh 服务
    ssytemctl status ssh # 查看 ssh 服务状态
    

    安装 Debian 时,自动创建了普通用户账户,但物理机仅用于虚拟化,不做多余事情,不使用这个账户。所以直接使用 ssh 登录 root 账户进行系统管理。如果 ssh 不允许登录 root 账户,请取消 /etc/ssh/sshd_config 中以下代码的注释:

    # PermitRootLogin yes
    

    ssh 默认允许通过密码验证登录,这会给系统带来安全风险,配置好密码登录的 ssh 后,配置密钥验证,然后禁止密码验证。

    在本地计算机(你的笔记本或台式机)执行以下命令:

    ssh-keygen # 如果有密钥就不用再生成了
    ssh-copy-id root@服务器ip地址
    

    输入 root 账户的密码验证成功后,就可以通过密钥验证登录了。取消 /etc/ssh/sshd_config 中这样注释,禁止密码验证登录。

    # PasswordAuthentication no
    

    只允许密钥验证登录就意味着假如密钥丢失,将永远不可能通过 ssh 登录服务器,所以要妥善保管密钥。如果还需要更强的 ssh 安全性,可以参考如何配置安全的 SSH 服务?(OpenSSH 安全必知必会)

    最后,完成 ssh 安全性最重要的一步配置——神兽护体。在 /etc/issue.net 添加以下字符画,下次登录就会有神兽护体,永不宕机。

             ┌─┐       ┌─┐
          ┌──┘ ┴───────┘ ┴──┐
          │                 │
          │       ───       │
          │  ─┬┘       └┬─  │
          │                 │
          │       ─┴─       │
          │                 │
          └───┐         ┌───┘
              │         │
              │         │
              │         │
              │         └──────────────┐
              │                        │
              │                        ├─┐
              │                        ┌─┘
              │                        │
              └─┐  ┐  ┌───────┬──┐  ┌──┘
                │ ─┤ ─┤       │ ─┤ ─┤
                └──┴──┘       └──┴──┘
                      神兽保佑
                      永不宕机
    
    

    安装 KVM

    执行以下命令安装 KVM 所需的包。

    apt-get install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system dnsmasq
    

    KVM 整套解决方案一般分三层:

    • KVM:内核级别的虚拟化功能,主要模拟指令执行和 I/O
    • QEMU:提供用户操作界面,VNC/SPICE 等远程终端服务
    • Libvirtd:虚拟化服务,运行在 Hypervisor 上提供 TCP 接口用于操作虚拟机的创建和启停

    安装完 KVM 后,需要配置 libvirtd 和 qemu。

    首先配置 libvirtd,使用 UNIX socket 连接 libvirtd,禁止安全验证(本地连接没有安全问题),禁止监听 TLS,并将 socket 所有组设置为 libvirt。在 /etc/libvirt/libvirtd.conf 中找到并修改以下配置:

    -p /home/data/kvm/imagei
    mkdir -p /home/data/kvm/isounix_sock_group = "libvirt"
    unix_sock_ro_perms = "0777"
    unix_sock_rw_perms = "0770"
    unix_sock_admin_perms = "0700"
    unix_sock_dir = "/var/run/libvirt"
    auth_unix_ro = "none"
    auth_unix_rw = "none"
    listen_tls = 0
    

    然后将 www-data 用户添加到 libvirt 组。

    usermod www-data -G libvirt
    

    最后让 qemu 由用户 libvirt-qemu(所属用户组为 libvirt-qemu)启动。在 /etc/libvirt/qemu.conf 中找到并修改以下配置。

    user = "libvirt-qemu"
    group = "libvirt-qemu"
    

    由于使用 WebVirtCloud 在浏览器中管理虚拟机,必须要让用户 www-data 可以连接 libvirt 的三个 socket,还要将这三个 socket 的所有者修改为 www-data。

    chown www-data:libvirt /var/run/libvirt/libvirt*
    

    设置桥接模式

    KVM 有好几种网络模式,比如 NAT 模式、桥接模式等。

    NAT 模式中,物理机相当于一个具有 NAT 功能的路由器,虚拟机处于这个子网中,拥有子网内的私有地址,虚拟机通过物理机向外连接互联网,所有虚拟机在外界看来都使用物理机的 IP 地址。这种网络模式可能导致端口冲突,只有私网 IP 的话可以使用这种模式。

    桥接模式中,物理机相当于一个网桥(一种数据链路层设备),将物理机和虚拟机桥接起来,虚拟机有自己独立的 IP 地址,在外界看来每个虚拟机都是独立的网络设备。这种网络模式比较适合有多个公网 IP 的情况,每个虚拟机都有公网 IP,不会导致端口冲突。桥接模式仅适用于以太网。

    参考 Debian 手册 BridgeNetworkConnections 一节配置网桥。先安装网桥管理的包:

     apt install -y bridge-utils
    

    再创建虚拟网桥 br0 并将物理网卡桥接上去。网卡名字通过ip a查看。

    brctl addbr br0
    brctl addif br0 网卡名字
    

    完成之后可以通过ip a看到系统中多了一个网络接口br0。修改网络接口配置文件 /etc/network/interfaces.d。

    source /etc/network/interfaces.d/* #
    
    auto lo                            # 启动时激活
    iface lo inet loopback             # 本地回环
    
    auto enp37s0                       # 启动时激活以太网接口
    iface enp37s0 inet manual          # Debian 手册推荐使用 maunal
    
    auto br0                           # 启动时激活网桥
    iface br0 inet dhcp                # 通过 DHCP 获取 IP 地址
    	bridge_ports enp37s0           # 将以太网接口桥接到网桥
    	bridge_stp off                 # Debian 手册推荐的调优配置
    	bridge_waitport 0
    	bridge_fd 0
    

    /etc/network/interface.d/ 中有一个配置文件 setup,其中激活了网卡 eth0,电脑上没有这个网卡的话删除这个文件。

    修改内核参数,将以下配置写入 /etc/sysctl.d/99-netfilter-bridge.conf。

    net.bridge.bridge-nf-call-ip6tables = 0
    net.bridge.bridge-nf-call-iptables = 0
    net.bridge.bridge-nf-call-arptables = 0
    

    加载 br_netfilter 内核模块并重启 network 服务。

    modprobe br_netfilter
    systemctl restart network
    

    创建 KVM 目录

    mkdir -p /home/data/kvm
    mkdir -p /home/data/kvm/image
    mkdir -p /home/data/kvm/iso
    chown www-data:www-data /home/data/kvm/iso
    

    挂载机械硬盘

    mkdir -p /home/data/kvm/hdd
    mkfs.btrfs -l hdd /dev/sdx # 硬盘号使用 lsblk 查看
    mount -t btrfs -o subvol='/' LABEL=hdd /home/data/kvm/hdd/
    

    创建 /home/data/kvm/hdd,将机械硬盘挂载上去。尝试挂载:

    mount -t btrfs -o subvol='/' /home/data/kvm/hdd
    

    在 /etc/fstab 中添加以下设置,实现自动挂载:

    LABEL=hdd /home/data/kvm/hdd btrfs subvol=/ 0 0
    

    安装 WebVirtCloud

    使用官方安装脚本自动安装配置。如果不能FQ就从 hub.fastgit.org 中下载安装脚本,并将将脚本中的 github.com 改为 hub.fastgit.org。

    进入 WebVirtCloud(端口 8080),初始用户名 admin,初始密码 admin。在“计算节点”-->“存储”中配置 ISO 池(/home/data/kvm/iso)和 image 池(/home/data/kvm/image)。

    WebVirtCloud

    共享目录

    通过设置共享目录让宿主机和虚拟机共享机械硬盘。编辑 KVM 虚拟机配置文件(也可以在 WebVirtCloud 中编辑 XML 配置):

    virsh edit --domain 虚拟机名字
    

    <device>...</device>中添加以下代码:

    <filesystem type='mount' accessmode='mapped'>
          <source dir='/home/data/kvm/hdd/omv'/> # 分配给该虚拟机的目录在物理机中的路径
          <target dir='hdd'/> # 虚拟机中设备的名字,当成硬盘挂载
    </filesystem>
    

    上面的代码片段中,宿主机创建了 /home/data/kvm/hdd/omv 并将这个目录映射到虚拟机的硬盘 omv,在虚拟机中当成一般的硬盘挂载即可。在虚拟机中设置 /etc/fstab 实现开机自动挂载。

    hdd       /mnt/omv     9p    trans=virtio   0    0
    

    重启后发现系统无法挂载,这是因为 systemd unit 之间的依赖有问题。mnt-hdd.mount 依赖于 9pnet_virtio 模块,这个模块在 kmod 之后才会加载。所以修改 mnt-hdd.mount 文件,在Unit中添加Requires=kmod.service强制在 kmod 加载后才挂载 mnt-hdd。

    安装配置 Windows10

    Windows10 默认不支持 virtio,所以在 WebVirtCloud 中创建实例时,不要勾选任何和 virtio 有关的东西。创建完成后,在实例的“设置”-->“磁盘”-->“实例卷”-->“编辑卷”(一个图标)-->“高级”-->“总线”中将 virtio 修改为 SATA。

    Debian10 默认没有安装 acpi,导致 Windows10 无法相应 libvirt 的关机指令。关机时会出现libvirt-guests.sh: Waiting for guest OMV to shut down 的报错,安装 acpi 就可以解决。

    apt install -y acpi acpid
    

    Windows10 虚拟机在我的电脑上只有两个核心,性能非常差。通过 host-passthrough 解决这个问题,详细信息参考 Domain XML format,使用这个模式后虚拟机可以直接使用物理机 CPU,但丧失了在不同平台迁移的能力。

    <cpu mode='host-passthrough' check='none'>
        <topology sockets='1' cores='4' threads='1'/>
    </cpu>
    

    sockets 是 CPU 数量,cores 是核心数,threads 是每个核的线程数。

    安装配置 OpenMediaVault

    OpenMediaVault(简称 OMV) 是基于 Debian 的 NAS 系统,详细信息可以参考韦易笑的知乎专栏文章OpenMediaVault:你的开源 NAS 系统

    参考本文上面介绍的挂载机械硬盘和共享目录,在机械硬盘上创建一个目录给 OMV。安装好 OMV 后,服务的主要服务都跑在 OMV 中。

    安装 OMV-Extras(OMV 插件管理器):

    apt update -y && apt --no-install-recommends -y install dirmngr gnupg && wget http://omv-extras.org/openmediavault-omvextrasorg_latest_all5.deb && dpkg -i openmediavault-omvextrasorg_latest_all5.deb
    

    安装完毕后,进入 OMV 的 Web 管理界面,在 OMV-Extras 中安装 docker。

    搭建应用服务

    到这里,我们就有了自己的 NAS 和私有云,可以方便的创建销毁虚拟机,还可以利用服务器(虚拟机)搭建各种应用。Github 上有一个项目 awesome-selfhosted 收集了各种可以在服务器上搭建的项目,知乎上也有不少回答很有价值。

    calibre-web

    搭建 calibre-web 个人图书馆。直接通过 pip3 安装 calibre-web。

    apt install -y python3-setuptools xz-utils python3-pip imagemagick
    pip3 install wheel
    pip3 install "Jinja2>3"
    pip3 install calibreweb[
    pip3 install calibreweb[{oauth,metadata,comics}]
    
    

    安装 calibre 来获取电子书转换功能。

    wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin
    

    电子书转换器位置在 /opt/calibre/calibre-convert,在 web 中设置转换器位置。

    通过calibre-web-double实现从豆瓣下载元数据。将这个项目中的 NewDouban.py 拷贝到 /usr/local/lib/python3.7/dist-packages/calibreweb/cps/metadata_provider 并重启 calibre-web 即可。

    编写 systemd 服务开启自动启动。

    # /etc/systemd/system/calibre.service
    [Unit]
    Description=Calibre web service
    
    [Service]
    ExecStart=/usr/local/bin/cps
    
    # /etc/systemd/system/calibre.timer
    [Unit]
    Description=Run calibre-web everyday
    
    [Timer]
    OnBootSec=1m
    
    [Install]
    WantedBy=multi-user.target
    

    硬件问题

    sp5100-tco watchdog hardware is disabled

    这是因为主板不支持这个功能,/etc/modprobe.d/sp5100_tco.conf 添加以下配置,将 sp5100-tco 假如黑名单。

    blacklist sp5100_tco
    

    AMD Vi error: unable to write to iommu perf counter

    在 /etc/default/grub 中修改GRUB_CMDLINE_LINIXiommu=soft,然后执行update-grub更新 grub。

  • 相关阅读:
    git爬坑不完全指北(二):failed to push some refs to ‘XXX’的解决方案
    javascript精雕细琢(三):作用域与作用域链
    javascript精雕细琢(二):++、--那点事
    git爬坑不完全指北(一):Permission to xxx.git denied to user的解决方案
    深入浅出CSS(三):隐藏BOSS大盘点之默认属性小总结
    读书笔记
    MPP5运维手册
    HTML自闭合(self-closing)标签
    Mysql JDBC的通信协议(报文的格式和基本类型)
    详解 & 0xff 的作用
  • 原文地址:https://www.cnblogs.com/kongj/p/15756159.html
Copyright © 2020-2023  润新知