2022-12-05 /
@syui
arch
, docker
/ arch
archlinuxでsystemd-nspawnを使いcontinerを立ててみた
botに複数の仮想環境を構築する必要があったので、今回はsystemd-nspawnを採用してみることにしました。
結論から言うと、systemd-nspawnはとっつきにくいですが、一度使えるようになっておくと、本格的に便利だと感じました。
ただ、とっつきにくさがすごい。コマンドも複数あって混乱を招くと思われます。
archwikiの最初の説明が以下です。
$ mkdir -p ~/arch
$ sudo pacstrap -c ~/arch base
# -D : chroot
$ sudo systemd-nspawn -D ~/arch
$ passwd
$ logout
# -b : コンテナ起動
$ sudo systemd-nspawn -b -D ~/arch
# -n : ネットワーク
$ sudo systemd-nspawn -b -D ~/arch -n
これは色んな意味で正しいのですが、私の環境では動作しません。
設定したpasswordでloginできない。なお、設定していないと空なのでenterでloginできるはず(たぶん)。ttyのsecurityが働いているからです。
Arch Linux 6.0.11-arch1-1 (pts/1)
arch login:
arch-nspawn login: root
Login incorrect
ここでホストから~/arch/etc/securetty
を編集し、ここではpts/1
でloginしようとしているため、これを追記します。pts/0
ならpts/0
ですし、その他ならそのttyを記述してください。
$ sudo vim ~/arch/etc/securetty
さて、loginできたとしましょう。
一旦、poweroff
して仮想環境(continer)を落とします。
$ poweroff
$ machinectl list
次に、本来のsystemd-nspawnの一般的な使い方を説明します。
$ machinectl --help
$ sudo mv ~/arch /var/lib/machines/
$ sudo machinectl list-images
$ sudo machinectl start arch
$ sudo machinectl login arch
# vmの削除
$ sudo machinectl remove arch
# vmにshell
# loginはおすすめしません。Ctrl+Dで抜けられません。shellの場合はexitできます。continerはupしたままになります。
$ sudo machinectl shell arch
# vmをdown
$ sudo machinectl poweroff arch
$ sudo machinectl terminate arch
/var/lib/machines
においたcontiner image(dir)をmachinectlで呼び出します。
これは、systemctl
のsystemd-nspawn@arch
でも同じようなことができます。
# archというcontinerをstart
$ sudo systemctl start systemd-nspawn@arch
$ sudo machinectl start arch
# archというccontinerをPC起動時に立ち上げる
$ sudo systemctl enable systemd-nspawn@arch
$ sudo machinectl enable arch
$ sudo systemctl daemon-reload
machinectl, systemd-nspawn, systemctlのどれを使ってもいいですが、個人的にはmachinectlをおすすめします。しかし、それぞれが使い方に微妙な違いを含んでいます。
machinectlは主にvm操作で、pacstrapはarchの構築、systemctlはホスト環境の構築、systemd-nspawnはdir(chroot)操作です。
正直、わかりづらい。
dockerのほうが遥かにわかりやすいですね。
ですが、archer(archlinuxを普段使いしる人)にとっては、慣れると扱いやすいし、便利そうだと感じています。
# イメージのダウンロード
$ sudo machinectl pull-tar --verify=no http://localhost:8000/arch.tar.gz arch
# アーカイブ
$ sudo machinectl export-tar --format=[gz, bzip2, xz] [コンテナ名] [ファイル名]
# xz でマルチスレッド圧縮をする例 (一番お勧め!)
$ maxz() { machinectl export-tar $1 $1.tar && nice -n 20 xz -z -f -T $(nproc) -vv $1.tar; }
$ maxz gbase
# インポート
$ sudo machinectl import-tar [ファイル名] [コンテナ名]
# docker imgをインポート
$ sudo docker export $(docker create debian:latest) | machinectl import-tar - debian
# hostのnetworkを使う, VirtualEthernetもconfiguredにすると有効
$ networkctl
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 eth0 ether routable configured
3 ve-arch ether no-carrier configuring
$ sudo vim /etc/systemd/nspawn/arch.nspawn
[Network]
VirtualEthernet=no
# ssh接続
$ ssh-keygen -f ~/.ssh/test
$ sudo cat ~/.ssh/test.pub >> /var/lib/machines/arch/root/.ssh/authorized_keys
$ sudo machinectl shell arch
$ pacman -S openssh
$ vim /etc/ssh/sshd_config
$ systemctl enable sshd
$ systemctl start ssh
$ exit
$ ssh root@localhost -p xxx -i ~/.ssh/test
bot運用をどうするか
例えば、botに一つの仮想環境をあてがい、その中で使える機能を限定して、1日に1回、もしくは呼び出すごとにresetされるように運用するのがいいかも。
その場合、cronとcloneを駆使してやるとよさそう。
$ sudo machinectl clone arch backup
$ sudo machinectl poweroff arch
$ sudo machinectl remove arch
$ sudo machinectl clone backup arch
ref
https://wiki.archlinux.org/title/systemd-nspawn
https://blog.usaturn.net/contents/2016/manage_spawn_container/
https://blog.n-z.jp/blog/2022-09-27-systemd-nspawn.html