Wener Notes

Firecracker

约 5 分钟阅读

Firecracker 限制

  • 没有电源管理,因此不支持重启,会直接退出
  • alpine 内核需要 boot-source.initrd_path => initramfs-virt
  • alpine netboot 的 initramfs-virt 没有 ext4
  • 系统内 poweroff 或 halt 不会退出 - reboot 会
  • 可以发送 SendCtrlAltDel 退出
  • 不支持 QCOW2 格式,可以考虑配合 NDB 使用

alpine

bash
# download
latest=$(basename $(curl -fsSLI -o /dev/null -w  %{url_effective} https://github.com/firecracker-microvm/firecracker/releases/latest))
curl -LOJ https://github.com/firecracker-microvm/firecracker/releases/download/${latest}/firecracker-${latest}-$(uname -m).tgz
mkdir out
tar zxvf firecracker-${latest}-$(uname -m).tgz --strip-components=1 -C out
cp out/firecracker-${latest}-$(uname -m) firecracker
chmod +x firecracker

# rootfs
# =========
# qemu-img create -f raw alpine.rootfs.ext4 1G
fallocate -l 1G alpine.rootfs.ext4
mkfs.ext4 ./alpine.rootfs.ext4
mkdir -p /tmp/rootfs
sudo mount alpine.rootfs.ext4 /tmp/rootfs

curl -OJ https://mirrors.aliyun.com/alpine/v3.19/releases/x86_64/alpine-minirootfs-3.19.8-x86_64.tar.gz
sudo tar zxvf alpine-minirootfs-3.19.8-x86_64.tar.gz -C /tmp/rootfs/
# for mirror
sudo cp /etc/apk/repositories /tmp/rootfs/etc/apk/repositories
sudo cp /etc/resolv.conf /tmp/rootfs/etc
sudo chroot /tmp/rootfs/ /bin/sh

apk add alpine-base util-linux linux-virt haveged
rc-update add haveged
echo root:root | chpasswd
for svc in devfs procfs sysfs; do ln -fs /etc/init.d/$svc /etc/runlevels/boot; done

ln -s agetty /etc/init.d/agetty.ttyS0
echo ttyS0 > /etc/securetty
rc-update add agetty.ttyS0 default

exit

# curl -LO https://mirrors.aliyun.com/alpine/latest-stable/releases/x86_64/netboot/initramfs-virt
# curl -LO https://mirrors.aliyun.com/alpine/latest-stable/releases/x86_64/netboot/vmlinuz-virt
# this initramfs contain required ext4 module
sudo cp /tmp/rootfs/boot/initramfs-virt initramfs-virt
sudo cp /tmp/rootfs/boot/vmlinuz-virt vmlinuz-virt

sudo umount /tmp/rootfs

# kernel
# ==========
curl -LOC- https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux
chmod +x extract-vmlinux
sudo apk add grep
# uncompress
./extract-vmlinux $PWD/vmlinuz-virt > vmlinux-virt

# config & start
# ==========
cat <<CONF > alpine.json
{
  "boot-source": {
    "initrd_path": "initramfs-virt",
    "kernel_image_path": "vmlinux-virt",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off modules=virtio_mmio,ext4 rootfstype=ext4"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "alpine.rootfs.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 1,
    "mem_size_mib": 1024,
    "ht_enabled": false
  }
}
CONF

./firecracker --api-sock /tmp/firecracker.socket --config-file alpine.json

# exit
# ==========
# api request
curl --unix-socket /tmp/firecracker.socket -i \
    -X PUT "http://localhost/actions" \
    -H  "accept: application/json" \
    -H  "Content-Type: application/json" \
    -d '{"action_type": "SendCtrlAltDel"}'
# in vm
reboot

# 检测 KVM 支持
[ -r /dev/kvm ] && [ -w /dev/kvm ] && echo "OK" || echo "FAIL"

# vm 内清除缓存 firecracker 也不会收回内存,因为不支持 balloon
echo 3 > /proc/sys/vm/drop_caches

# 类似 qemu - 但 qemu 更容易添加网络且支持 vnc
# firecracker 默认会添加 root=/dev/vda
# 启动后约 130 MB 额外内存占用 - firecracker 约 70 MB
# pci=off qemu 无法启动
qemu-system-x86_64 \
  -smp 1 -m 1024 -cpu host \
  -M pc,accel=kvm \
  -no-acpi \
  -device virtio-rng-pci -device virtio-balloon -serial stdio \
  -kernel vmlinux-virt \
  -initrd initramfs-virt \
  -append "console=ttyS0 reboot=k panic=1 modules=virtio_mmio,virtio_blk,ext4 rootfstype=ext4 root=/dev/vda" \
  -drive file=alpine.rootfs.ext4,if=virtio,cache=writeback

ubuntu

bash
curl -LO http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-amd64.tar.gz

fallocate -l 1G ubuntu.rootfs.ext4
sudo mkfs.ext4 ubuntu.rootfs.ext4

mkdir /tmp/rootfs
sudo mount ubuntu.rootfs.ext4 /tmp/rootfs
sudo tar -xzvf ubuntu-base-20.04.1-base-amd64.tar.gz -C /tmp/rootfs
sudo cp /etc/resolv.conf /tmp/rootfs/etc/
sudo chroot /tmp/rootfs/ /bin/bash

apt update
apt install linux-image-kvm -y
apt install init -y
update-initramfs -u
echo root:root | chpasswd
echo ttyS0 > /etc/securetty
systemctl enable [email protected]

exit

sudo cp /tmp/rootfs/boot/initrd.img .
sudo cp /tmp/rootfs/boot/vmlinuz .

sudo umount /tmp/rootfs

sudo chown $USER vmlinuz
./extract-vmlinux $PWD/vmlinuz > vmlinux

cat <<CONF > ubuntu.json
{
  "boot-source": {
    "initrd_path": "initrd.img",
    "kernel_image_path": "vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off modules=virtio_mmio,ext4 rootfstype=ext4"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "alpine.rootfs.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 1,
    "mem_size_mib": 1024,
    "ht_enabled": false
  }
}
CONF

./firecracker --api-sock /tmp/firecracker.socket --config-file ubuntu.json
bash
# https://packages.debian.org/sid/linux-image-amd64

centos

bash
# https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/images/pxeboot/
curl --remote-name-all -OC- https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/images/pxeboot/{initrd.img,vmlinuz}

extract-vmlinux ./vmlinuz > vmlinux

cat <<CONF > centos.json
{
  "boot-source": {
    "initrd_path": "initrd.img",
    "kernel_image_path": "vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off modules=virtio_mmio,ext4 rootfstype=ext4"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "centos.rootfs.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 1,
    "mem_size_mib": 1024,
    "ht_enabled": false
  }
}
CONF

rm /tmp/firecracker.socket;firecracker --api-sock /tmp/firecracker.socket --config-file centos.json

firectl

network

firecracker-microvm/firecracker/docs/network-setup.mdGitHub Filefirecracker-microvm/firecracker/docs/network-setup.md

接口

  • api_server/swagger/firecracker.yamlGitHub Filefirecracker-microvm/firecracker/src/api_server/swagger/firecracker.yaml
  • /actions
    • {"action_type":""}
    • FlushMetrics,InstanceStart,SendCtrlAltDel
  • /boot-source - 仅启动前
  • /drives/{drive_id} - 仅启动前
  • /logger
  • /machine-config
  • /metrics
  • /mmds - Microvm Metadata Service
  • /mmds/config - 配置 MMDS - 仅启动前
  • /network-interfaces/{iface_id} - 仅启动前
  • /snapshot/create - 创建为暂停状态的虚拟机创建快照
  • /snapshot/load - 加载快照 - 新启动的 Firecracker
  • /vm - 虚拟机状态管理
    • {"state":""}
    • Paused, Resumed
  • /vsock - vsock 设备管理
yaml
boot-source:
  initrd_path: initrd.img
  kernel_image_path: vmlinux
  boot_args: console=ttyS0 reboot=k panic=1 pci=off modules=virtio_mmio,ext4 rootfstype=ext4
drives:
  - drive_id: rootfs
    path_on_host: centos.rootfs.ext4
    is_root_device: true
    is_read_only: false
    # 可选 - is_root_device 时的启动分区 UUID
    partuuid: 00000000-0000-0000-0000-000000000000
    # 可选 - 访问速率限制
    rate_limiter:
      bandwidth: # 带宽
        one_time_burst: 0
        refill_time: 0
        size: 0
      ops: # 操作
# 日志配置
logger:
  log_path: '' # 必须
  # Error, Warning, Info, Debug
  level: Warning
  show_level: false
  show_log_origin: false
# 机器配置
machine-config:
  # 1-32 - 1 或 1-32 之间偶数
  vcpu_count: 1
  mem_size_mib: 1024
  # Hyperthreading
  ht_enabled: false
  # C3, C2
  # cpu_template: C3
  # 启用后可对内存创建增量快照
  # track_dirty_pages: false

metrics:
  # 存储 JSON 格式 metric 的路径
  metrics_path: ''

network-interfaces:
  - allow_mmds_requests: false # 启用后会响应 HTTP GET 请求 MMDS
    guest_mac: ''
    host_dev_name: ''
    iface_id: ''
    rx_rate_limiter: ''
    tx_rate_limiter: ''

vsock:
  guest_cid: 3
  # UNIX domain socket
  uds_path: ''
  vsock_id: ''

网络

bash
# 假设需要桥接的 virbr0 已经存在
ip tuntap add dev fc0 mode tap
ip li set fc0 master virbr0
ip li set fc0 up


sudo ip link add name br0 type bridge
sudo ip addr add 172.20.0.1/24 dev br0
sudo ip link set dev br0 up
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables --table nat --append POSTROUTING --out-interface enp3s0 -j MASQUERADE
sudo iptables --insert FORWARD --in-interface br0 -j ACCEPT
json
{
  "network-interfaces": [
    {
      "iface_id": "if0",
      "host_dev_name": "fc0"
    }
  ]
}

FAQ

mount: mounting /dev/vda on /sysroot failed: No such device

  • 可能不支持 ext4
  • cat /proc/filesystems

关联信息

反向链接、本文链接的其他页面和外部资料。

反向链接

  • WSL
    笔记 · firecracker

    WSL2 为完整虚拟机 - kernel+rootfs · 跨 OS FS 性能不太好 - 建议项目直接放到 VM 里 · vsc 和 jetbrain 支持直接打开 wsl 里 fs · 等同于 macOS 下的 lima · 约等于 firecracker 效果

References

GitHub9 条
其他外链1 条
最近更新commit 7c3df6dEdit

On this page