241時間以上の大遅刻をしました。
この記事は NITKC ProLab Advent Calendar 2020 の6日目として執筆されました。
前日は宮野さんの ヤフオクで買ったパソコンを魔改造する話 でした。
翌日は虎太郎さんの 性格ツンデレと展開ツンデレの違い です。
皆様こんばんわ、KPです。
一応自己紹介をしておきますと、Misskeyによく出没するプロラボの老害(OB)です。
今回はsystemd-nspawnというDockerとはちょっと違うコンテナの布教をします。
ことの発端は2020/06/10に行われたOuranosのリリースでした。 このツイートを見て、このイラストにはアナログ時計が似合いそうだな、と思ったKPは善は急げと環境構築に取り掛かりました。 しかしLaravelをベースに構築されたOuranosは普通に構築するとそこそこの環境汚染が発生します。 ちょっとフロントを弄りたいだけのKPは、面倒を避けるため環境をsystemd-nspawnのコンテナ内に隔離することにしたのでした。
systemd-nspawn は chroot コマンドに似ていますが、chroot を強化したものです。 - Arch Wiki
systemd-nspwawnは、"システムコンテナ"を志向したコンテナ技術です。 Dockerと同様、Linuxカーネルの機能であるnamespaceとcgroupsを利用して隔離された環境を提供しますが、隔離の単位や目的が大きく異なります。 Dockerはプロセス単位で隔離を行い、ステートレスなインフラを提供するコンテナ技術ですが、一方でsystemd-nspawnはシステム単位で隔離を行い、VMとほぼ同等のゲストシステムを提供します。 今回のように内部に開発環境を構築する等、通常のシステムの延長線上の隔離環境として非常に有用です。
OS: Arch Linux x86_64
Kernel: 5.9.13-arch1-1
Systemd: 247.1-3-arch
- 所定の位置にコンテナの実体となるディレクトリを作成します
後に使用する管理ツール(machinectl
)のため/var/lib/machines
に作成しますが、/tmp
等で作業してからmv
しても構いません。
# on host
sudo mkdir /var/lib/machines/ouranos
- Archをインストールするのとおなじ要領でベースシステムを作成します
もちろんお好みに応じてパッケージを足すことも可能ですが、ホストシステムのカーネルが共用される(ゲストはホストのユーザランド内で実行される)ため、カーネルパッケージは不要です。 Archのbaseにはエディタが含まれないため、なにかしらのエディタを入れておくと良いでしょう。(catやsedでコンフィグを書くのであれば別ですが)
# on host
sudo pacstrap -c -d /var/lib/machines/ouranos base base-devel
- コンテナ内でシェルを立ち上げます
この段階ではコンテナ内のsystemdは起動しておらず、chrootのような状態です。ps
を使用するとシェルのPIDが1である(ホストのPID空間から隔離されている)ことが確認できます。
# on host
sudo systemd-nspawn -D /var/lib/machiens/ouranos
- ゲストシステムを設定します
ネットワーク周りとユーザの設定をします。 作業が終了したら、exit
でコンテナを抜けます。
# on guest
echo 'ouranos' >> /etc/hostname
systemctl enable systemd-networkd systemd-resolved
echo 'DNS=8.8.8.8 8.8.4.4' >> /etc/systemd/resolved.conf
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
visudo
useradd -m -G wheel alice
exit
- ゲストシステムを起動します
/var/lib/machines
以外で作業している場合は、machinectl
の実行前にディレクトリを移動します。 無事に成功すれば、見慣れたCLIログインが表示されているはずです。
# on host
sudo machinectl start ouranos
sudo machinectl login ouranos
- sshサーバをセットアップします
手順4で設定したアカウントでログインします。 作業が終了したら、exit
でログインに戻った後、^]
を3回入力してコンテナを抜けます。
# on guest
sudo pacman -Syu openssh
sudo $EDITOR /etc/ssh/sshd_config # お好みで適当に
sudo systemctl enable sshd
sudo systemctl start sshd
- コンテナにsshします
ホストからゲストはコンテナ名(/var/lib/machines/
のディレクトリ名)で名前解決が可能です。 無事sshが通れば隔離環境の完成です。 あとは個々の需要に合わせて好きに環境構築しましょう。 ホストからの開発はVSCode Remote SSH
がいい感じでおすすめです。
# on host
ssh ouranos
- さいごに
用が済んだら後片付けも忘れずに。
# on host
sudo machinectl poweroff ouranos
今回はDockerとは少し違うコンテナ技術を紹介しました。 systemd-nspawnのコンテナは仮想マシンとほぼ同等に扱えるため、開発環境の隔離に便利です。 特にコンテナ内で無理なく複数プロセスを起動できるのは、Dockerと比較した際の大きな強みとなるでしょう。 Docker同様使い方次第でいろいろな遊び方ができますので、みなさんも是非触れてみましょう。
それでは、 Happy Hacking!