本人有一台工控机, 5500u cpu, 8g 内存,本来是打算用来跑docker的, 但是因为要装
k8s, 虚拟机会更加合适方便,
宿主机的系统是ubuntu server 22.04.1 LTS, 没有安装GUI。 所以vmware virtualbox就不考虑了。 纯命令行估计kvm 会更加合适。 一台机当两三台机用了。
Step 1 检查cpu是否开启虚拟化
国际惯例, 首先检查cpu有没开启虚拟化。
现在市面上估计都买不到不支持虚拟化的cpu了, 问题是我们也要检查下bios上有没enable虚拟化特性。
gateman@homeserver2:~$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
Step 2 安装kvm
sudo apt update
sudo apt install qemu qemu-kvm libvirt-bin bridge-utils virt-manager
问题是 这个 libvirt-bin, 提供了virsh等命令工具帮助我们更好地管理kvm 实例。
而且比我以前用kvm时多了个系统服务libvirtd.service, 简单来讲,这个服务会用1个common的账号 libvirt 去启动kvm 实例进程。
所以我们的iso文件, 虚拟硬盘文件都必须放在能让libvirt 账号可以访问的地方。
如果是ubuntu 20.04 则有可能找不到libvirt-bin的包, 要分开安装
libvirt-daemon-system libvirt-clients
安装上面的东西后, 检查libvirtd服务有没有启动.
sudo systemctl status libvirtd.service
## if not started
sudo systemctl start libvirtd.service
sudo systemctl enable libvirtd.service
Step 3 设置桥接网卡
kvm 支持多种网络模式
桥接模式 (bridge)
NAT模式
路由模式
直接分配设备模式
…
第4种太奢侈, 而其他3种只有桥接模式能令虚拟机和局域网其他主机相互通信(ip 在同1个网段)
所以我们会选择桥接模式。
当我们用vmware virtualbox时, 桥接网卡都会自动配置好, 而kvm需要我们事先手动配置。
每个linux发型版的网络管理方式都不同, 而ubuntu 22.04.1 用的是自家的netplan 来管理的。 当然,如果我们启动用GUI, 则很可能会用NetworkManager.
既然我的机器是没有GUI的, 那就是netplan了
检查 /etc/netplan 文件夹, 是否存在yaml文件, 如果不存在, 而你台机器还能上网的话, 则肯定不是用netplan 方式。
3.1 检查netplan配置
gateman@homeserver2:/etc/netplan$ pwd
/etc/netplan
gateman@homeserver2:/etc/netplan$ ls *yaml
00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
enp1s0:
dhcp4: false
enp2s0:
dhcp4: true
version: 2
先备份和查看原来的配置文件, 可以看到, 我台机器只有两个有线端口, 其中只有1个插了网线启用的dhcp, 这里的4指的是 ip4
3.2 检查虚拟桥接设备
输入ifconfig 回车
会见到输出除了上面两个有线网卡外, 多了1个设备virbr0,这是安装完kvm后系统自动创建的
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:89:a9:72 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
其实这个virbr0 并不是一块虚拟网卡, 而是1个块虚拟桥接设备(bridge), 我们还必须基于它再创建1个虚拟桥接网卡。
3.3 编辑/etc/netplan/00-xxx.yaml 添加一个桥接网卡
before that,
我手绘了1个kvm 桥接的大概原理图, 不会是百分百准确, 将就看就行
我们需要做的是创建1个关键的虚拟桥接网卡 br0 , 如下图, 它桥接 宿主机的真正物理卡, 而且, 我们之后创建的虚拟机都会通过这个br0 桥接网卡与外部沟通。
也就是讲即使我们后面会创建多台虚拟机, 对于宿主机来讲, 1个虚拟桥接网卡就足够了。
编辑 /etc/netplan/00-xxxx.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
enp1s0:
dhcp4: false
enp2s0:
dhcp4: false # 真正的物理显卡要关闭dhcp
bridges:
br0:
interfaces: [enp2s0]
dhcp4: no
addresses: [10.0.1.107/24] # ip地址
routes:
- to: default
via: 10.0.1.1 # 路由其地址
nameservers:
addresses: [119.29.29.29, 8.8.8.8] # DNS 119.29.29.29 是疼讯的DNS
version: 2
保存后
执行
sudo netplan apply
注意这里我们不在从路由器动态申请ip, 而是设置静态ip, 如国修改前后的ip不同,我们的ssh connection会断开, 需要重新连接。
修改后我们再查看ifconfig
我们会发现
- 多了个网卡br0, 地址就是我们设置的静态ip地址
- 物理网卡没有地址, 这是正常的, 如上图, 连物理网卡也会通过这个虚拟网桥连接外部。。
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.1.107 netmask 255.255.255.0 broadcast 10.0.1.255
inet6 fe80::b4a2:82ff:fe35:d8d8 prefixlen 64 scopeid 0x20<link>
ether b6:a2:82:35:d8:d8 txqueuelen 1000 (Ethernet)
RX packets 61997 bytes 8192346 (8.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 82925 bytes 21320864 (21.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:e0:0a:f2:12:26 txqueuelen 1000 (Ethernet)
RX packets 338034 bytes 418401126 (418.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 115940 bytes 24050924 (24.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Step 4 新建虚拟硬盘
上面说了,虚拟硬盘为了要让libvirt 访问, 最好创建再公共的地方.
我在根目录创建了1个folder /kvmdisks …
命令:
qemu-img create ./kvm0.img 20G
Step 5 准备系统安装文件iso
我为了省事, 直接套娃安装ubuntu server 22.04 本身
同样地, iso 最好放在公共地方
gateman@homeserver2:/isos$ ls
ubuntu-22.04.1-live-server-amd64.iso
Step 6 编写虚拟机配置文件
对于新增加一台虚拟机, 无非修改下面几个地方
1, cpu 数量和内存大小
2. uuid 用uuid-rumtime 包下的 uuidgen命令生成
3. 修改新的随机mac地址, 自己google怎么生成 echo $RANDOM | md5sum | sed ‘s/…/&:/g’ | cut -c1-17
4. 修改虚拟机名称。
5. 修改虚拟硬盘路径
6. 反注释光驱启动那行
7. 没了
gateman@homeserver2:~/kvmxmls/vm1$ cat vm1.xml
<domain type='kvm'> //如果是Xen,则type=‘xen’
<name>vm1</name> //虚拟机名称,同一物理机唯一
<uuid>4b942306-76b0-4174-9371-a0485fdc8093</uuid> //同一物理机唯一,可用uuidgen生成
<memory>4096000</memory>
<currentMemory>2048000</currentMemory> //memory这两个值最好设成一样
<vcpu>2</vcpu> //虚拟机可使用的cpu个数,查看物理机可用CPU个数:cat /proc/cpuinfo |grep processor | wc -l
<os>
<type arch='x86_64' machine='ubuntu'>hvm</type> //arch指出系统架构类型,machine 则是机器类型,查看机器类型:qemu-system-x86_64 -M ?
<!-- 第一次运行要 反注释这行
<boot dev='cdrom'/> //启动介质,第一次需要装系统可以选择cdrom光盘启动
-->
<bootmenu enable='yes'/> //表示启动按F12进入启动菜单
</os>
<features>
<acpi/> //Advanced Configuration and Power Interface,高级配置与电源接口
<apic/> //Advanced Programmable Interrupt Controller,高级可编程中断控制器
<pae/> //Physical Address Extension,物理地址扩展
</features>
<clock offset='localtime'/> //虚拟机时钟设置,这里表示本地本机时间
<on_poweroff>destroy</on_poweroff> //突发事件动作
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices> //设备配置/
<emulator>/usr/bin/kvm</emulator> //如果是Xen则是/usr/lib/xen/binqemu-dm
<disk type='file' device='disk'> //硬盘
<driver name='qemu' type='raw'/>
<source file='/kvmdisks/kvm1.img'/>
<target dev='vda' bus='virtio'/> // if windows must ide else virtio
</disk>
<disk type='file' device='cdrom'>//光盘
<driver name='qemu' type='raw'/>
<source file='/isos/ubuntu-22.04.1-live-server-amd64.iso'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
/* 利用Linux网桥连接网络 */
<interface type='bridge'>
<mac address='40:00:02:04:19:ef'/>
<source bridge='br0'/> //配置的网桥网卡名称
<target dev='vnet0'/> //同一网桥下相同
<alias name='net0'/> //别名,同一网桥下相同
</interface>
<graphics type='vnc' port='5901' autoport='yes' listen='0.0.0.0' keymap='en-us'> //配置vnc,windows下可以使用vncviewer登录,获取vnc端口号:virsh vncdisplay vm0
<listen type='address' address='0.0.0.0'/>
</graphics>
</devices>
</domain>
Step 7 启动虚拟机
保存后. 有两种方式启动
- virsh create vm0.xml
- virsh define vm0.xml
virsh start vm0 # 主机名
第一种一旦关闭虚拟机就会消失, 建议用于测试
第二种除非 执行virsh undefine 主机名, 否则一直存在与虚拟机列表。
如果遇到错误:XML error: expected unicast mac address, found multicast ‘23:F6:7F:2B:67:5D’
那是因为所造的mac地址是组播地址,要非组播的mac地址才行,开头大于24即可
Step 8, 连接启动后的虚拟机, 安装系统
两种方式,
- 用vnc viewer(linux /win 通用)
- 在另一台linux机上安装virt-manager
不得不说virt-manager 真是个神奇, 可以在一台有GUI的linux 主机去管理另1台没有GUI的KVM 宿主机的kvm 子系统。
缺点:
3. 需要GUI
4. 没有windows 版, 硬气!
接着就可以安装系统了
Step 9, 移除cdrom启动方式, 重启
如果用virsh create vm0.xml 方式启动安装的, 安装后可以修改vm0.xml(或者另建一份copy), 把cdrom 启动注销掉
然后 再重新 virsh define …
Step 10,检查kvm虚拟机 网卡地址
如果一切顺利, 虚拟机dhcp生成的网卡会与物理机同一个网段
gateman@vm:~$ ifconfig
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.1.151 netmask 255.255.255.0 broadcast 10.0.1.255
inet6 fe80::f892:1ff:fe33:d4fa prefixlen 64 scopeid 0x20<link>
ether fa:92:01:33:d4:fa txqueuelen 1000 (Ethernet)
RX packets 2540 bytes 145750 (145.7 KB)
RX errors 0 dropped 477 overruns 0 frame 0
TX packets 423 bytes 30596 (30.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 324
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 164 bytes 14048 (14.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 164 bytes 14048 (14.0 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
其实这时就可以通过局域网物理机ssh过去了
为了方便管理, 还是建议修改虚拟机网卡设置, 设置成静态ip
gateman@vm:~$ cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens3:
dhcp4: no
addresses: [10.0.1.151/24]
gateway4: 10.0.1.1
nameservers:
addresses: [119.29.29.29, 8.8.8.8]
虚拟机网卡地址不与物理机同一网段的原因
如果发现虚拟机ip地址是192.168.122.xxx
则这时 其他局域网的主机是访问不了这些虚拟机的。
原因是vm0.xml 的网络设置错误
/* 利用Linux网桥连接网络 */
<interface type='bridge'>
<mac address='40:00:02:04:19:ef'/>
<source bridge='br0'/> //配置的网桥网卡名称
<target dev='vnet0'/> //同一网桥下相同
<alias name='net0'/> //别名,同一网桥下相同
</interface>
把上面的 source briidge = ‘virbr0’ 改回来 br0 就ok!
我把自己踩过的坑都写出来了。
virt-manager
最后再推荐一下这个神器, 它可以很方便的完成本文的step4 to step9
跟virtbox的gui 界面用起来差距不大了!