操作系统版本信息
代码语言:javascript复制NAME="openEuler"
VERSION="22.03 (LTS-SP1)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP1)"
ANSI_COLOR="0;31"
查看服务器是否支持虚拟化
代码语言:javascript复制grep -E -o 'vmx|svm' /proc/cpuinfo
vmx
vmx
vmx
vmx
确保BIOS里开启虚拟化功能,即查看是否加载KVM模块
代码语言:javascript复制lsmod |grep kvm
kvm_intel 397312 5
kvm 983040 1 kvm_intel
irqbypass 16384 4 kvm
如果没有加载,运行以下命令
代码语言:javascript复制modprobe kvm
modprobe kvm-intel
内核模块导出了一个名为/dev/kvm的设备,该设备将虚拟机的的地址空间独立于内核或者任何应用程序的地址空间
代码语言:javascript复制ll /dev/kvm
crw-rw---- 1 root kvm 10, 232 Feb 5 15:56 /dev/kvm
安装kvm软件包
代码语言:javascript复制dnf install libvirt qemu-kvm qemu-img virt-install bridge-utils libguestfs-tools
启动libvirtd 服务
代码语言:javascript复制systemctl start libvirtd && systemctl enable libvirtd
查看虚拟机的相关环境
代码语言:javascript复制virsh -c qemu:///system list
Id Name State
----------------------------------------------------
查看virsh的版本
代码语言:javascript复制[root@openEuler-node1 ~]# virsh --version
6.2.0
查看 virt-install工具的版本
代码语言:javascript复制virt-install --version
2.1.0
查看qemu-kvm版本
代码语言:javascript复制创建软连接
ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-kvm
查看qemu-kvm版本信息
qemu-kvm -version
QEMU emulator version 6.2.0 (qemu-6.2.0-65.oe2203sp1)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
手动创建虚拟网桥
创建br0网桥
cat /etc/sysconfig/network-scripts/ifcfg-ens33
代码语言:javascript复制TYPE=Ethernet
BOOTPROTO=static
NAME=ens33
DEVICE=ens33
ONBOOT=yes
BRIDGE=br0
cat /etc/sysconfig/network-scripts/ifcfg-br0
代码语言:javascript复制DEVICE=br0
NAME=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.10.225
NETMASK=255.255.255.0
GATEWAY=192.168.10.1
DNS1=114.114.114.114
重启网络
代码语言:javascript复制nmcli connection reload
nmcli connection up ens33
nmcli connection up br0
查看网桥br0
代码语言:javascript复制ip add show
查看网桥
代码语言:javascript复制brctl show
添加网卡到网桥
代码语言:javascript复制brctl addif br0 vnet0
创建虚拟机
创建虚拟磁盘
代码语言:javascript复制qemu-img create -f qcow2 /kvm/img/zabbix.qcow2 50G
查看虚拟磁盘信息
代码语言:javascript复制qemu-img info /kvm/img/zabbix.qcow2
virt-install 创建虚拟机
virt-install --name=zabbix-openeuler --memory=4096 --vcpus=2 --disk path=/kvm/img/zabbix.qcow2,format=qcow2,bus=virtio --cdrom /mnt/openEuler-22.03-LTS-SP1-x86_64-dvd.iso --network bridge=br0,model=virtio --noautoconsole --accelerate --graphics vnc,listen=0.0.0.0 --video cirrus
创建虚拟机参数介绍
- --virt-type kvm 指定虚拟化类型(qemu/kvm)
- --os-type=linux 系统类型
- --os-variant rhel8 系统版本
- --name zabbix-openeuler 虚拟机的名字
- --memory 4096 内存大小
- --vcpus 2 处理器数量
- 硬盘类型(qcow2,raw),存放位置,以及大小(G) --disk /mnt/openeuler.qcow2,format=raw,size=6 --disk path=/kvm/img/zabbix.qcow2,format=qcow2,bus=virtio
- 指定光驱文件 --cdrom /mnt/openEuler-22.03-LTS-SP1-x86_64-dvd.iso
- 指定网络类型,默认是nat模式 --network bridge=br0,model=virtio
- --graphics vnc,listen=0.0.0.0 指定终端输出设备
- --noautoconsole 不自动尝试连接到客户端控制台
- --accelerate 内核加速器,选项默认参数
- --video cirrus 指定video类型
VNC控制台登录虚拟机
代码语言:javascript复制virsh vncdisplay zabbix-openeuler
:0
virsh qemu-img qemu-kvm 命令不补全
代码语言:javascript复制dnf install bash-completion
重启系统生效
虚拟机操作
console log
当操作系统内核崩溃时会报出内核系统crash出错信息,通常启动的时候一闪而过, 而此时系统还没有起来,不能通过远程工具(比如ssh)进入系统查看,通过配置grub,把日志重定向到Serial Console中,通过Serial console来访问错误信息。
方法1
grubby --update-kernel 命令不会更新`/etc/default/grub`文件
代码语言:javascript复制grubby --update-kernel=ALL --args="console=tty0 console=ttyS0,115200n8"
重启系统生效
方法2
编辑/etc/default/grub文件
代码语言:javascript复制GRUB_CMDLINE_LINUX="crashkernel=auto console=tty0 console=ttyS0,115200n8"
执行grub2-mkconfig 加载生效grub配置
grub2-mkconfig -o /boot/grub2/grub.cfg
代码语言:javascript复制Legacy模式:grub2-mkconfig -o /boot/grub2/grub.cfg
UEFI模式:grub2-mkconfig -o /boot/efi/EFI/openEuler/grub.cfg
重启系统生效
console控制台登录虚拟机
代码语言:javascript复制virsh console zabbix-openeuler
acpid 部署
acpid是一个用户空间的服务进程, 用来处理电源相关事件,比如将kernel中的电源事件转发给应用程序,告诉应用程序安全的退出,防止应用程序异常退出导致数据损坏。
安装acpid软件包,并设置开机启动服务
代码语言:javascript复制dnf install -y acpid
systemctl start acpid && systemctl enable acpid
qemu-guest-agent部署
QEMU Guest Agent是运行在虚拟机内部的一个守护程序(qemu-guest-agent.service),用它来辅助Hypervisor实现对Guest的管理。QEMU为宿主机和虚拟机提供了一个数据通道(channel),libvirt会在本地创建一个unix socket,模拟为虚拟机内部的一个串口设备,从而实现了宿主机与虚拟机通信,不依赖于TCP/IP网络。libvrit提供了专门的 virDomainQemuAgentCommand API(对应virsh qemu-agent-command命令)来和qemu-guest-agent通讯,另外libvirt内置api也可以支持qga,例如reboot、shutdown等。
宿主机可以发送指令写到socket文件中,虚拟机内部的qemu-guest-agent会轮询查看这个串行设备是否有指令,一旦接收到指令就可以执行对应的脚本,从而实现了宿主机控制虚拟机执行命令的功能。
宿主机编辑虚拟机(虚拟机关闭操作)
代码语言:javascript复制virsh edit zabbix-openeuler
XML文件<devices>模块中增加如下配置
代码语言:javascript复制<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0'/>
</channel>
开启虚拟机
代码语言:javascript复制virsh start zabbix-openeuler
虚拟机安装qemu-guest-agent
代码语言:javascript复制dnf install -y qemu-guest-agent
systemctl restart qemu-guest-agent && systemctl enable qemu-guest-agent
异常问题1
systemctl enable qemu-guest-agent 提示如下报错
代码语言:javascript复制systemctl enable qemu-guest-agent
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
编辑 /usr/lib/systemd/system/qemu-guest-agent.service 在结尾增加install单元节点后再重新执行命令即可正常。
代码语言:javascript复制[Install]
WantedBy=multi-user.target
增加后内容如下
异常问题2
systemctl enable qemu-guest-agent 提示如下报错
代码语言:javascript复制[567.210087][T3518]systemd-rc-local-generator[3518]: /etc/rc.d/rc.local is not marked executable, skipping.
添加执行权限
代码语言:javascript复制sudo chmod x /etc/rc.d/rc.local
qemu-guest-agent功能验证
1,宿主机libvirt修改虚拟机密码
代码语言:javascript复制virsh set-user-password zabbix-openeuler --user root --password 'root@123'
2,宿主机命令测试
代码语言:javascript复制virsh qemu-agent-command zabbix-openeuler '{"execute":"guest-info"}'
virsh qemu-agent-command zabbix-openeuler '{"execute":"guest-network-get-interfaces"}'
virsh qemu-agent-command zabbix-openeuler '{"execute":"guest-ping"}'
growpart部署
虚拟机制作镜像时指定了根分区大小,为了使虚拟机能够自动调整为flavor disk指定的根磁盘大小,即自动扩容, 需要安装glowpart工具
代码语言:javascript复制dnf install -y cloud-utils-growpart
安装cloud-init
cloud-init是虚拟机第一次启动时执行的脚本,主要负责从metadata服务中拉取配置信息,完成虚拟机的初始化工作,比如设置主机名、初始化密码以及注入密钥等。阿里云、AWS、Azure和OpenStack等主流云平台均支持cloud-init。
cloud-init 安装时会将以下 4 个阶段执行的任务以服务的形式注册到系统中,比如在 systemd 的环境下,能够看到这4个阶段分别对应的服务
- local - cloud-init-local.service
- init - cloud-init.service
- config - cloud-config.service
- final - cloud-final.service
虚拟机安装cloud-init
代码语言:javascript复制dnf install cloud-init -y
cloud-init4个阶段对应的服务
代码语言:javascript复制[root@localhost system]# ls /etc/systemd/system/cloud*
cloud-config.service cloud-final.service cloud-init-local.service cloud-init.service
检查Cloud-Init工具相关配置是否成功
执行以下命令,无错误发生,说明Cloud-Init配置成功
代码语言:javascript复制cloud-init init --local
Cloud-init v. 19.4 running 'init-local' at Sun, 12 Jun 2022 08:13:55 0000. Up 2258404.99 seconds.
注意:在多次使用cloud-init 初始化虚拟机需要提前删除虚拟机/var/lib/cloud目录下产生的旧数据,否则cloud-init 初始化无法重新执行。
创建 ssh 密钥
生成名为"id_rsa"和"id_rsa.pub"的文件
代码语言:javascript复制ssh-keygen -t rsa -b 4096 -f id_rsa -C kvm -N "" -q
ssh-keygen 常用参数
- -t:指定生成密钥的类型,默认使用SSH2d的rsa
- -f:指定生成密钥的文件名,默认id_rsa(私钥id_rsa,公钥id_rsa.pub)
- -P:提供旧密码,空表示不需要密码(-P ‘’)
- -N:提供新密码,空表示不需要密码(-N ‘’)
- -b:指定密钥长度(bits),RSA最小要求768位,默认是2048位;DSA密钥必须是1024位(FIPS 1862标准规定)
- -C:提供一个新注释
- -R hostname:从known_hosta(第一次连接时就会在家目录.ssh目录下生产该密钥文件)文件中删除所有属于hostname的密钥
ssh client访问测试
代码语言:javascript复制ssh root@127.0.0.1 -i /mnt/id_rsa
创建云初始化配置文件
代码语言:javascript复制#cloud-config
#主机名
hostname: host-
#DNS
fqdn: 223.5.5.5
manage_etc_hosts: true
#创建用户
users:
- name: openeuler
sudo: ALL=(ALL) NOPASSWD:ALL
groups: where
home: /home/openeuler
shell: /bin/bash
lock_passwd: false
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZXq7
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZXq7
#修改用户信息
# only cert auth via ssh (console access can still login)
ssh_pwauth: true
disable_root: false
chpasswd:
list: |
root:newpasswd
centos:newpasswd
expire: False
#安装软件包
package_update: true
packages:
- vim-enhanced
- net-tools
- tcpdump
- sysstat
timezone: Asia/Shanghai
# manually set BOOTPROTO for static IP
# older cloud-config binary has bug?
runcmd:
- [ sh, -c, 'sed -i s/BOOTPROTO=static/BOOTPROTO=dhcp/ /etc/sysconfig/network-scripts/ifcfg-eth0' ]
- [ sh, -c, 'ifdown eth0 && sleep 1 && ifup eth0 && sleep 1 && ip a' ]
# written to /var/log/cloud-init.log, /var/log/messages
final_message: "The system is finally up, after $UPTIME seconds"
查看cloud-init日志
代码语言:javascript复制sudo less /var/log/cloud-init.log
sudo grep cloud-init /var/log/messages
禁用cloud-init初始化系统
主机名、网络配置、软件包初始化完成后,在虚拟机中禁用 cloud-init服务
代码语言:javascript复制# flag that signals that cloud-init should not run
sudo touch /etc/cloud/cloud-init.disabled
# optional, remove cloud-init completely
sudo dnf remove cloud-init
# shutdown VM so CDROM seed can be ejected
sudo shutdown -h now
宿主机操作
移除虚拟机本地信息
代码语言:javascript复制virt-sysprep -d zabbix-openeuler
压缩虚拟机镜像
代码语言:javascript复制virt-sparsify --compress /kvm/img/zabbix.qcow2 /kvm/img/openeuler.qcow2
虚拟机管理命令
代码语言:javascript复制virsh list --all 查看所有的虚拟机
virsh start zabbix-openeuler 启动虚拟机
virsh shutdown zabbix-openeuler 正常关机虚拟机
virsh destroy zabbix-openeuler 强制关机(拔电源)
virsh reboot zabbix-openeuler 重启
virsh domrename zabbix-openeuler openeuler 虚拟机重命名
virsh suspend openeuler 挂起虚拟机
virsh resume openeuler 从挂起状态恢复
virsh autostart openeuler 设置kvm虚拟机开机自启动
virsh autostart --disable openeuler 取消虚拟机开机自启动
虚拟机配置文件管理命令
代码语言:javascript复制导出虚拟机配置文件
virsh dumpxml openeuler >/data/openeuler.xml
virsh define /data/openeuler.xml 导入虚拟机
virsh undefine openeuler 删除虚拟机
virsh edit openeuler 修改虚拟机的配置文件
virt-install 创建虚拟机报错
unsupported configuration: domain configuration does not support 'video model' value 'qxl'
注意:欧拉系统virt-install 创建虚拟机video类型默认使用qxl,但系统默认不支持qxl导致创建虚拟报错,virt-install 创建虚拟机使用 "--video cirrus" 指定video类型
video支持的类型
qemu最新版已经支持 cirrus,std,qxl,vmware,virtio,none 。