ᕕ( ᐛ )ᕗ Jimyag's Blog

使用 qemu 创建 ubuntu 虚拟机

安装依赖的工具

sudo apt update
sudo apt install cloud-image-utils  qemu-system qemu-kvm net-tools socat

桥接网络

# 创建 TAP 接口
sudo ip tuntap add dev tap0 mode tap

# 激活 TAP 接口
sudo ip link set dev tap0 up

# 将 TAP 接口添加到网桥 br0
sudo ip link set dev tap0 master br0

# TODO 设置 TAP 接口的 ip 地址

准备 cloud-init 镜像和系统镜像

# 下载系统cloud image 
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

# 创建系统镜像 ,系统磁盘 50G
qemu-img create -f qcow2 -o backing_file=jammy-server-cloudimg-amd64.img,backing_fmt=qcow2 ubuntu.qcow2 50G
touch user-data meta-data
cat meta-data
instance-id: jvm-1
local-hostname: jvm-1
# 生成 ssh-key
ssh-keygen -t ed25519 -C "jvm-1" -f ~/.ssh/id_ed25519 -N ""

# 获取 ssh-key
cat ~/.ssh/id_ed25519.pub
# 生成 密码
openssl passwd -6 '123456'
cat user-data
#cloud-config
ssh_pwauth: true

users:
  - name: jimyag
    lock_passwd: false
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    ssh_authorized_keys:
      - "ssh-ed25519 <ssh-key> all"
    passwd: $6$f6eb3bzvu5D6pJli$WlaqEPDkjiwWber5wvyr8d/VFNhlbv5GSQIYsy4rM3CsGb4N7sJNq1AYAiYRGPfEhMaA744ZX7vUVocoD/vWW.

chpasswd:
  expire: false

disable_root: false

runcmd:
  - userdel -r ubuntu
  - sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
  - sed -i 's/#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config
  - sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
  - sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config
  - rm -rf /etc/ssh/sshd_config.d/*
  - systemctl restart sshd
# 创建 cloud-init 镜像
cloud-localds init.img user-data meta-data

启动虚拟机

sudo qemu-system-x86_64 \
  -uuid 01962579-e75c-74e6-8283-5a2fe002c31d \
  -cpu host,hv_passthrough \
  -nographic \
  -no-user-config \
  -sandbox on,obsolete=deny,elevateprivileges=allow,spawn=allow,resourcecontrol=deny \
  -readconfig /home/jimyag/jvp/m6-1/qemu.conf \
  -pidfile /home/jimyag/jvp/m6-1/qemu.pid \
  -D /home/jimyag/jvp/m6-1/qemu.log \
  -netdev tap,id=net0,ifname=tap0,script=no,downscript=no \
  -device virtio-net-pci,netdev=net0 \
  -spice unix=on,disable-ticketing=on,addr=/home/jimyag/jvp/m6-1/qemu.spice \
  -runas nobody \
  -vnc unix:/home/jimyag/jvp/m6-1/qemu.vnc
cat qemu.conf
# Machine
[machine]
graphics = "off" # 关闭图形界面
type = "q35" # 使用 Q35 架构
accel = "kvm" # 使用 KVM 加速
usb = "off" # 关闭 USB

[global]
driver = "ICH9-LPC"
property = "disable_s3"
value = "1"

[global]
driver = "ICH9-LPC"
property = "disable_s4"
value = "1"

[boot-opts]
strict = "on" # 严格模式

# Memory
[memory]
size = "1024M" # 内存大小

# CPU
[smp-opts]
cpus = "1" # 核心数
maxcpus = "4" # 最大核心数

[object "mem0"]
qom-type = "memory-backend-memfd" # 内存类型
size = "1024M" # 内存大小
share = "on" # 共享


# Qemu control
[chardev "monitor"]
backend = "socket"
path = "/home/jimyag/jvp/m6-1/qemu.monitor"
server = "on"
wait = "off"

[mon]
chardev = "monitor"
mode = "control"

# Console
[chardev "console"]
backend = "socket"
path = "/home/jimyag/jvp/m6-1/qemu.console"
server = "on"
wait = "off"


[device "virtio-serial0"]
driver = "virtio-serial"

[device "console"]
driver = "virtserialport"
chardev = "console"
name = "org.qemu.guest_agent.0"

# Random number generator
[object "qemu_rng"]
qom-type = "rng-random"
filename = "/dev/urandom"

# Drive
[drive "ubuntu.qcow2"]
file = "/home/jimyag/jvp/m6-1/ubuntu.qcow2"
if = "virtio"
format = "qcow2"

[drive "init.img"]
file = "/home/jimyag/jvp/m6-1/init.img"
if = "virtio"
format = "raw"

前台运行 使用 -nographic,不能与 -display none 和 -daemonize 一起使用

使用 vnc 连接

# 启动 vnc 服务
sudo socat TCP-LISTEN:5900,fork UNIX-CONNECT:/home/jimyag/jvp/m6-1/qemu.vnc

可以使用 vncviewer 或者 novnc 连接

incus 启动虚拟机的命令

/usr/bin/qemu-system-x86_64 -S -name <name> -uuid <uuid> -daemonize -cpu host,hv_passthrough -nographic -serial chardev:console -nodefaults -no-user-config -sandbox on,obsolete=deny,elevateprivileges=allow,spawn=allow,resourcecontrol=deny -readconfig /run/incus/<name>/qemu.conf -spice unix=on,disable-ticketing=on,addr=/run/incus/<name>/qemu.spice -pidfile /run/incus/<name>/qemu.pid -D /var/log/incus/<name>/qemu.log -smbios type=2,manufacturer=LinuxContainers,product=Incus -runas nobody

连接虚拟机

# 连接虚拟机
ssh [email protected]

修改虚拟机密码

sudo virt-customize -a ubuntu.qcow2  --password ubuntu:password:123456

TODO

  1. pid 文件存储在哪里
  2. 使用 qmp 协议管理虚拟机

https://arianfm.medium.com/create-virtual-machine-with-cloud-image-and-cloud-init-config-using-qemu-kvm-8080ee6e7f05

#qemu #kvm