NetBSDでPodmanからLinuxコンテナを動かす
2021年10月30日 初稿
注: 技術検証記事ではありません。
Podmanはコンテナエンジンのひとつです。Red Hat Enterprise Linuxがバージョン7から8にメジャーアップデートしたさい、Dockerから標準のコンテナエンジンとして置き換わった実績があります。Dockerと比べ裏でデーモンを動かすことなく(daemonless)、かつルート権限不要(rootless mode)で動作します。
2021年9月4日、coypuがnetbsd-usersに投稿した『Running docker containers with podman (on NetBSD!)』のとおり、pkgsrc-currentにPodmanパッケージが追加されNetBSDでもPodmanを利用できるようになりました[1]。
pkgsrc自体はNetBSDとは独立したパッケージ管理システムですから、NetBSDカーネルでOCI Runtime準拠のコンテナを動かせられるようになったというわけではありません。Podmanはpodman machine
コマンドからコンテナを動かす仮想マシン(VM)を管理できます。NetBSDにインストールされたPodmanはこの機能を活用し、QEMU-NVMMからFedoraが動くVMを用意してコンテナそのものはFedora OSの中で動作させます。
VMを経由させるので、ネイティブなLinuxディストリビューションで動かすより性能面で見劣りする可能性があります。ただしVMはNVMMでハードウェアアクセラレーションしているのでアプリケーションの開発や動作検証用途ならほとんど影響はないでしょう。またこれもほとんど問題にならないとは思いますが、NVMMの都合上アーキテクチャがx86_64に制限されます。
インストールはメールに書いてあるとおり以下の手順で完了します。podman machine
のマニュアルはhttps://docs.podman.io/en/latest/markdown/podman-machine.1.htmlで公開されています。
pkgsrc/sysutils/podman
をインストールするpodman machine init
してpodman machine start
する
既知の問題として、Podman用のLinux VMがAPIC関連のカーネルパニックを起こすことが知られています。NetBSDカーネルにoptions HZ=1000
を設定してビルドするか、VMのGRUBでブートエントリにnoapic
を与えることで回避できます。Podman用Linux VMのブートエントリを手動で編集する方法はLeonardo Taccariが返信しているメールから確認できます[2]。大まかには次のようにします。
- Podman VMのイグニションファイル(ignition file)を編集して
noapic
オプションがブートエントリに存在することを保証させる。 - Podman VMを手動で起動しブートエントリに
noapic
を追加する。
OCIコンテナのネイティブサポートでないとはいえ、PodmanのインタフェースからDocker/Podmanコンテナを使えるようになったことで別プラットフォームを対象にした開発がやりやすくなったのではないかと思います。なにか即席でアプリケーションを動かしたいときもDocker Hubからダウンロードしてきてすぐに使えるようになったのも便利でしょう。
僕のPCではCPUがNested Virtualizationに対応していないおかげでbhyveから動かしているNetBSDではコンテナの動作確認ができませんでした。というわけでこの話はもう終わりです。
参考文献
netbsd-usersに投稿されたPodmanパッケージ追加を知らせるメール全文
To: netbsd-users%netbsd.org@localhost Subject: Running docker containers with podman (on NetBSD!) From: coypu%sdf.org@localhost Date: Sat, 4 Sep 2021 21:06:02 +0000 Hi all, I added a package to pkgsrc called Podman. It's a tool for running OCI containers, and it has the same command line behaviour as the docker command line argument. There are some selling points for it over docker, but the most important for us is the fact it has a mode where it spawns a Linux VM to talk to for you, so it runs on NetBSD! One caveat is that NetBSD somewhat struggles running virtualized Linux by default. The virtualized ticks are just too slow, so it panics with: Kernel panic - not syncing: IO-APIC + timer doesn't work! Boot with apic=debug and send a report. Then try booting with the 'noapic' option. One way to work around it, convenient for this purpose, is to rebuild your kernel with "options HZ=1000" added, then you don't need to edit the command line arguments in the VM. Usage instructions: Install pkgsrc/sysutils/podman from pkgsrc-current Initialize and start a VM with: podman machine init podman machine start And then you can use it much like the docker command: > podman run -it alpine sh -c "apk add file; file -L /bin/sh" fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz (1/2) Installing libmagic (5.40-r1) (2/2) Installing file (5.40-r1) Executing busybox-1.33.1-r3.trigger OK: 13 MiB in 16 packages /bin/sh: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
Leonardo TaccariによるPodman VMのブートエントリ編集手順
To: netbsd-users%netbsd.org@localhost Subject: Re: Running docker containers with podman (on NetBSD!) From: Leonardo Taccari <leot%NetBSD.org@localhost> Date: Sun, 05 Sep 2021 22:12:53 +0200 coypu%sdf.org@localhost writes: > Hi all, > Hello coypu! > I added a package to pkgsrc called Podman. > It's a tool for running OCI containers, and it has the same command line > behaviour as the docker command line argument. > > There are some selling points for it over docker, but the most important > for us is the fact it has a mode where it spawns a Linux VM to talk to > for you, so it runs on NetBSD! > That's really nice, thank you very much for working on it! > One caveat is that NetBSD somewhat struggles running virtualized Linux > by default. The virtualized ticks are just too slow, so it panics with: > Kernel panic - not syncing: IO-APIC + timer doesn't work! Boot with > apic=debug and send a report. Then try booting with the 'noapic' option. > > One way to work around it, convenient for this purpose, is to rebuild > your kernel with "options HZ=1000" added, then you don't need to edit > the command line arguments in the VM. > [...] I was tempted to try the other workaround, i.e. append `noapic' directly at the boot but... that was a bit challenging! :) So here all the notes that I have collected. 1. Download the image via: podman machine init 2. After the image is downloaded and extracted SSH keys will be generated under ~/.ssh and there will be a Ignition config in ~/.config/containers/podman/machine/qemu/podman-machine-default.ign. In order to append `noapic' to the kernel arguments we need to adjust the following in podman-machine-default.ign: 2a. Reindent the JSON to be a bit easier to edit, e.g. via `jq .' 2b. Bump .ignition.version to "3.3.0" (it is "3.2.0") 2c. At the end, after systemd object add a comma `,' and then another JSON object: "kernelArguments": { "shouldExist": ["noapic"] } 3. Manually run the image via QEMU in order to initialize it via the ignite config so that `noapic' is appended. Assuming we are in our home directory, e.g.: qemu-system-x86_64 -accel nvmm -nographic -m 1G -smp 1 \ -fw_cfg name=opt/com.coreos/config,file=.config/containers/podman/machine/qemu/podman-machine-default.ign \ -drive if=virtio,file=.local/sif=virtio,file=.local/share/containers/podman/machine/qemu/podman-machine-default_fedora-coreos-34.20210821.1.1-qemu.x86_64.qcow2 4. In GRUB press `e' in order to edit the boot entry. In the kernel line append at the end `noapic' and press Ctrl-x to boot it 5. The ignition config will be applied and it will reboot 6. In GRUB press `c' and then `halt' in order to poweroff the machine (we're done!) 7. Start the machine as usual via `podman machine start'