Firecrackerで自作Slackware microVMに挑戦

記事の更新日:2026/09/23 記事の文書一部修正

1.概要

この記事は2026年7月から8月にかけて検証した結果を整理したものです。以前、Firecrackerの動作検証を行い、Slackwareを利用したMicroVMを構築を踏まえて、全体を整理しました。

2026年4月にSlackwareのmicroVM作成にチャレンジする目的でrootdisk(rootfs作成)の調査をしました。その時から時間が空いてしまったのですが、もう一度、仕切り直しをして、Firecrackerで自作Slackware64 15.0のmicroVM稼働に挑戦しました。

Firecrackerで独自のmicroVMを動かすためには、microVMのkernelとrootfsが必要です。これを作成するためにはKVM環境に2つのSlackware64 15.0を作成します。1つはkernelBuildができる環境を準備します。もう一つはインストール時のモジュール選択を最低限にしたrootfs用途です。この2つの仮想マシンからFirecracker上で起動するために必要なファイルを作成して動かすことに挑戦しました。その内容を記述します。

私の評価は以下の通りです。

(1) 環境構築はKVM仮想環境を利用します
(2) minimal kernel作成は、削って作るよりも、加えて作ることが楽でした
(3) minimal rootfsは、Slackwareだから可能です。柔軟性が高いと思います
(4) Firecrackerで起動できるように設定することが案外難しい

2.詳細

(1) 環境準備

HW: i3-7100, Meomry 16GB, SSD 256GB
SW: LinuxMint 22.3

(a)kvmの導入
sudo apt -y install virt-manager qemu-system
導入後、再起動します。

(b)Slackware64 15.0のDownload
Mirrorサイトからslackware64-15.0-isoをDownloadします。
https://mirrors.slackware.com/slackware/slackware-iso/slackware64-15.0-iso/

(c)仮想マシン作成(kernelBuildができる環境)
仮想マシンは1core, Memory 4GB, Disk 10GBで作成します
具体的な導入手順は次回説明します

(d)仮想マシン作成(rootfs用途)
仮想マシンは1core, Memory 4GB, Disk 10GBで作成します

(2) Slackware microVM用kernelのbuild

(a) kernel buildの準備と確認、microVM用kernel作成

Slackware64 15.0を導入して、slackpkgでupdateを実行するとkernel-5.15.193にupgradeされます。まず、このkernelをベースにして、最新版のkernel-5.15.202に入替をして、kernel buildができることを確認します。kernel build用の仮想マシンをKVM上に構築します。仮想マシンはSlackware64 15.0をa,ap,d,l,nをインストールしました。root以外に作業用userを作成します。

kernel.orgからkernel-5.15.202をDownloadします。仮想マシンに作業用Userでloginiして作業します。
wget http://www.kernel.org/pub/linux/kernel/v5.x/linux-5.15.202.tar.gz
rootでloginして、huge kerenlのconfigを利用して、kernel buildを行います。
cd /usr/src
tar zxf ~/linux-5.15.202.tar.gz
ln -s linux-5.15.202 linux
cd /usr/src/linux
cp /boot/config-huge-5.15.193.x64 .config
make olddefconfig
make -j$(nproc)

エラーなくbuildできたので、kernelを入替えます。
cp arch/x86/boot/bzImage /boot/vmlinuz-5.15.202
cp System.map /boot/System.map-5.15.202
cp .config /boot/config-5.15.202
cd /boot
rm System.map
ln -s System.map-5.15.202 System.map
rm vmlinuz
ln -s vmlinuz-5.15.202 vmlinuz
rm config
ln -s config-5.15.202 config

/etc/lilo.confに定義を追加してboot失敗に備えます
# Linux bootable partition config ends
image = /boot/vmlinuz-huge-5.15.193
  root = /dev/vda1
  label = Linux_5.15.193
  read-only

liloを利用してbootするkernelを入替後、rebootします
lilo
reboot

仮想マシン起動後、linuxを選択して新しいkernelで起動します。

(b)huge kernelから不要な項目を取り除く

仮想マシンにloginして、現状のkernel parameter設定状況を確認にします。
cd /boot
cat config-5.15.202 | grep "=m" | wc -l
4396
cat config-5.15.202 | grep "=y" | wc -l
2495

上記設定を"=y"を1000以下、"=m"をゼロにする必要があります。
これが難しい。項目を参照して設定を試したのですが、この方式では無理と判断しました。

(c)kvmゲスト用のkernelに項目を加える

全体のパラメータ設定をNにして、kvmゲスト用の設定でbuildしました
make allnoconfig
make kvm_guest.config
make olddefconfig
make -j$(nproc)

今度はパラメータ数が少なくてbuildエラーになります。

(d)必要最低限の設定を追加する

make allnoconfig
make kvm_guest.config

# CPU最適化
./scripts/config --enable CONFIG_64BIT
./scripts/config --enable CONFIG_MKABYLAKE
./scripts/config --set-val CONFIG_NR_CPUS 4
./scripts/config --enable CONFIG_PREEMPT_NONE

# ファイルシステム
./scripts/config --enable CONFIG_EXT4_FS
./scripts/config --enable CONFIG_EXT4_USE_FOR_EXT2
./scripts/config --enable CONFIG_EXT4_FS_POSIX_ACL
./scripts/config --enable CONFIG_EXT4_FS_SECURITY
./scripts/config --enable CONFIG_MSDOS_PARTITION
./scripts/config --enable CONFIG_EFI_PARTITION
./scripts/config --enable CONFIG_NET_9P
./scripts/config --enable CONFIG_NET_9P_VIRTIO
./scripts/config --enable CONFIG_9P_FS
./scripts/config --enable CONFIG_9P_FS_POSIX_ACL
./scripts/config --enable CONFIG_9P_FS_SECURITY

# CUI 必須機能
./scripts/config --enable CONFIG_UNIX
./scripts/config --enable CONFIG_INET
./scripts/config --enable CONFIG_DEVTMPFS
./scripts/config --enable CONFIG_DEVTMPFS_MOUNT
./scripts/config --enable CONFIG_TMPFS
./scripts/config --enable CONFIG_TMPFS_POSIX_ACL
./scripts/config --enable CONFIG_BINFMT_ELF
./scripts/config --enable CONFIG_PROC_FS
./scripts/config --enable CONFIG_SYSFS

# VirtIO & シリアルコンソール
./scripts/config --enable CONFIG_VIRTIO
./scripts/config --enable CONFIG_VIRTIO_PCI
./scripts/config --enable CONFIG_VIRTIO_BLK
./scripts/config --enable CONFIG_VIRTIO_NET
./scripts/config --enable CONFIG_VIRTIO_CONSOLE
./scripts/config --enable CONFIG_SERIAL_8250
./scripts/config --enable CONFIG_SERIAL_8250_CONSOLE

# 軽量化
./scripts/config --disable CONFIG_DRM
./scripts/config --disable CONFIG_FB
./scripts/config --disable CONFIG_SOUND
./scripts/config --disable CONFIG_SND
./scripts/config --disable CONFIG_INPUT_MOUSE
./scripts/config --disable CONFIG_WLAN

# TTY
./scripts/config --enable CONFIG_TTY
./scripts/config --enable CONFIG_UNIX98_PTYS
./scripts/config --enable CONFIG_LEGACY_PTYS

# クロック
./scripts/config --enable CONFIG_HYPERVISOR_GUEST
./scripts/config --enable CONFIG_KVM_GUEST
./scripts/config --enable CONFIG_PTP_1588_CLOCK_KVM

# ELF
./scripts/config --enable CONFIG_BLOCK
./scripts/config --enable CONFIG_BLK_DEV
./scripts/config --enable CONFIG_PARTITION_ADVANCED
./scripts/config --enable CONFIG_MSDOS_PARTITION

# fsck
./scripts/config --enable CONFIG_BINFMT_ELF
./scripts/config --enable CONFIG_BINFMT_SCRIPT
./scripts/config --enable CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
./scripts/config --enable CONFIG_RTC_LIB
./scripts/config --enable CONFIG_RTC_CLASS
./scripts/config --enable CONFIG_RTC_DRV_CMOS

# keyin
./scripts/config --enable CONFIG_INPUT
./scripts/config --enable CONFIG_INPUT_KEYBOARD
./scripts/config --enable CONFIG_VIRTIO_INPUT
./scripts/config --enable CONFIG_VT
./scripts/config --enable CONFIG_VT_CONSOLE
./scripts/config --enable CONFIG_HW_CONSOLE

# login respose
./scripts/config --enable CONFIG_HW_RANDOM
./scripts/config --enable CONFIG_HW_RANDOM_VIRTIO
./scripts/config --enable CONFIG_CRYPTO_RNG
./scripts/config --enable CONFIG_CRYPTO_RNG2
./scripts/config --enable CONFIG_CRYPTO_ANSI_CPRNG
./scripts/config --enable CONFIG_HYPERVISOR_GUEST
./scripts/config --enable CONFIG_PARAVIRT
./scripts/config --enable CONFIG_KVM_GUEST
./scripts/config --enable CONFIG_PARAVIRT_CLOCK
./scripts/config --enable CONFIG_X86_HV_CALLBACK_VECTOR
./scripts/config --enable CONFIG_PACKET
./scripts/config --enable CONFIG_VIRTIO_MMIO
./scripts/config --enable CONFIG_VIRTIO_NET

# cgroup
./scripts/config --enable CONFIG_CGROUPS
./scripts/config --enable CONFIG_CGROUP_FREEZER
./scripts/config --enable CONFIG_CGROUP_PIDS
./scripts/config --enable CONFIG_CGROUP_DEVICE
./scripts/config --enable CONFIG_CGROUP_CPUACCT
./scripts/config --enable CONFIG_CGROUP_SCHED
./scripts/config --enable CONFIG_CPU_CGROUP_SCHED
./scripts/config --enable CONFIG_MEMCG

# Firecracker
./scripts/config --enable CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES

# ipv6 disable
./scripts/config --disable CONFIG_IPV6

make olddefconfig
make -j$(nproc)

これでbuildできました。kernelを入替えて、liloで起動を確認

(e) kernel-5.15.203へ入替え

新しいkernelがリリースされていたので入替えをしました。
cat config-5.15.203 | grep "=y" | wc -l
639
cat config-5.15.203 | grep "=m" | wc -l
ゼロです。

(3) microVM用のrootfs作成

Slackware-Minimal Installに記載されている情報をベースにします。しかし、この情報はSlackware64-13.37がベースになっています。今回はSlackware64-15.0なのでkernelも異なります。Slackwareの導入経験がある方は、a-ap-l-nの最小構成を選択して導入すると良いはずです。

Slackware64-15.0を動かすためには、"REQUIRE"と指定された項目が必要でした。bootはlilo利用です。vimが好きなので選択しました。これ以外にもelogindが必要でした。modulesとkernel-firmwarはhuge kernelを利用すると不要なはずですが、ここでは1.5GB程度の容量を必要とするkernel-firmwareのみ削除しました。これで645MBになりました。実際にmicroVMを作成する時に更に削ることをします。

a/aaa_base
a/aaa_glibc-solibs
a/aaa_libraries
a/aaa_terminfo
a/acl
a/attr
a/bash
a/bin
a/bzip2
a/coreutils
a/cracklib
a/dcron
a/devs
a/dialog
a/e2fsprogs
a/elogind
a/elvis
a/etc
a/eudev
a/findutils
a/gawk
a/grep
a/gzip
a/hostname
a/kernel-generic
a/kernel-huge
a/kernel-modules
a/kmod
a/less
a/libgudev
a/libpwquality
a/lilo
a/logrotate
a/openssl-solibs
a/pam
a/pkgtools
a/procps
a/sed
a/shadow
a/sharutils
a/sysklogd
a/sysvinit
a/sysvinit-functions
a/sysvinit-scripts
a/tar
a/util-linux-ng
a/which
a/xz
ap/diffutils
ap/slackpkg
ap/vim
l/glibc
n/dhcpcd
n/gnupg
n/iputils
n/net-tools
n/network-scripts
n/openssh
n/wget

(4) Firecrackerを利用したSlackware microVMの起動

Slackware64 15.0を利用したminimal root-filesystem(root disk)とSlackware64で稼働するkernel-5.15.203のminimalのkernel-fileが準備できました。これらを利用してFirecrackerでmicroVMを起動します。

mkdir ~/FIrecracker
cd ~/FIrecracker
このディレクトリで作業します

(a)rootfsの作成
KVM上に存在するminimal slackware64 15.0からfirecracker用のrootfsを作成します。

(a-1) qcow2からtarアーカイブを作成します
sudo modprobe nbd
sudo qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/slackware15firmless.qcow2
sudo mount /dev/nbd0p1 /mnt
sudo tar czf slackware15firmless.tar.gz ./
sudo umount /mnt
sudo qemu-nbd --disconnect /dev/nbd0

(a-2) rootfs.imgを作成します
dd if=/dev/zero of=rootfs.img bs=1M count=10240
mkfs.ext4 rootfs.img
sudo mount -o loop rootfs.img /mnt
sudo tar -xpf slackware15firmless.tar.gz -C /mnt

cp /mnt/etc/inittab   inittab
sed -i -e 's/#s1/s1/' inittab
sudo mv inittab       /mnt/etc/inittab

sudo rm -rf /mnt/boot/*
sudo rm -rf /mnt/lib/modules/*
sudo rm -rf /mnt/usr/share/doc/*
sudo rm -rf /mnt/usr/share/man/*

sudo ls -l /mnt/dev/vda*
sudo mknod -m 660 /mnt/dev/vda b 254 0
sudo mknod -m 660 /mnt/dev/vda1 b 254 1
sudo chown root:disk /mnt/dev/vda*
sudo ls -l /mnt/dev/vda*

sudo ls -l /mnt/dev/console
sudo ls -l /mnt/dev/ttyS0
sudo ls -l /mnt/dev/null

sudo umount /mnt

これでrootfsのslack_flat.imgができました

(b) kernel iamge
minimal kernelを作成した仮想マシンの/usr/src/linux/vmlinuxをcopy
scpを利用して仮想マシンからvmlinuxをコピーします

(c) Firecracker最新版のdownload
https://github.com/firecracker-microvm/firecracker/releases
上記URLからfirecracker-v1.15.1-x86_64.tgzをdownloadして、firecracker-v1.15.1-x86_64を解凍

(d) config作成
config.jsonで下記定義ファイルを作成
{
  "boot-source": {
    "kernel_image_path": "vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda1 rw"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "rootfs.img",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 1,
    "mem_size_mib": 256,
    "smt": false
  }
}

(e) 実行
rm -f /tmp/firecracker.socket
./firecracker-v1.15.1-x86_64 --api-sock /tmp/firecracker.socket --config-file config.json

Slackware64 15.0のmicroVMにrootでloginできます

3.所見

この記事は温めた期間がとても長かったと思います。FC2からBloggerへ移行が中々思うように行かず、記事の公開を躊躇っていました。いつまでも過去の記事をリライトしているばかりでは駄目だと思い、本記事を公開することにしました。

Blogの更新手順に誤りがあり、最新記事が一番古くなってしまいました。誤りを修正しました。

参考

 

コメント