Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kp54/3298a2b1499269aeb014313882afcb91 to your computer and use it in GitHub Desktop.
Save kp54/3298a2b1499269aeb014313882afcb91 to your computer and use it in GitHub Desktop.
NITKC ProLab Advent Calendar 2020

systemd-nspawn で快適な開発体験を得る話

241時間以上の大遅刻をしました。

#pragma begin preamble

この記事は NITKC ProLab Advent Calendar 2020 の6日目として執筆されました。
前日は宮野さんの ヤフオクで買ったパソコンを魔改造する話 でした。
翌日は虎太郎さんの 性格ツンデレと展開ツンデレの違い です。

#pragma end preamble

皆様こんばんわ、KPです。
一応自己紹介をしておきますと、Misskeyによく出没するプロラボの老害(OB)です。 今回はsystemd-nspawnというDockerとはちょっと違うコンテナの布教をします。

あらまし

ことの発端は2020/06/10に行われたOuranosのリリースでした。 このツイートを見て、このイラストにはアナログ時計が似合いそうだな、と思ったKPは善は急げと環境構築に取り掛かりました。 しかしLaravelをベースに構築されたOuranosは普通に構築するとそこそこの環境汚染が発生します。 ちょっとフロントを弄りたいだけのKPは、面倒を避けるため環境をsystemd-nspawnのコンテナ内に隔離することにしたのでした。

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

コンテナをつくる

  1. 所定の位置にコンテナの実体となるディレクトリを作成します
    後に使用する管理ツール(machinectl)のため /var/lib/machines に作成しますが、 /tmp 等で作業してから mv しても構いません。
# on host
sudo mkdir /var/lib/machines/ouranos
  1. Archをインストールするのとおなじ要領でベースシステムを作成します
    もちろんお好みに応じてパッケージを足すことも可能ですが、ホストシステムのカーネルが共用される(ゲストはホストのユーザランド内で実行される)ため、カーネルパッケージは不要です。 Archのbaseにはエディタが含まれないため、なにかしらのエディタを入れておくと良いでしょう。(catやsedでコンフィグを書くのであれば別ですが)
# on host
sudo pacstrap -c -d /var/lib/machines/ouranos base base-devel
  1. コンテナ内でシェルを立ち上げます
    この段階ではコンテナ内のsystemdは起動しておらず、chrootのような状態です。 ps を使用するとシェルのPIDが1である(ホストのPID空間から隔離されている)ことが確認できます。
# on host
sudo systemd-nspawn -D /var/lib/machiens/ouranos
  1. ゲストシステムを設定します
    ネットワーク周りとユーザの設定をします。 作業が終了したら、 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
  1. ゲストシステムを起動します
    /var/lib/machines 以外で作業している場合は、 machinectl の実行前にディレクトリを移動します。 無事に成功すれば、見慣れたCLIログインが表示されているはずです。
# on host
sudo machinectl start ouranos
sudo machinectl login ouranos
  1. sshサーバをセットアップします
    手順4で設定したアカウントでログインします。 作業が終了したら、 exit でログインに戻った後、 ^] を3回入力してコンテナを抜けます。
# on guest
sudo pacman -Syu openssh
sudo $EDITOR /etc/ssh/sshd_config  # お好みで適当に
sudo systemctl enable sshd
sudo systemctl start sshd
  1. コンテナにsshします
    ホストからゲストはコンテナ名( /var/lib/machines/のディレクトリ名)で名前解決が可能です。 無事sshが通れば隔離環境の完成です。 あとは個々の需要に合わせて好きに環境構築しましょう。 ホストからの開発は VSCode Remote SSH がいい感じでおすすめです。
# on host
ssh ouranos
  1. さいごに
    用が済んだら後片付けも忘れずに。
# on host
sudo machinectl poweroff ouranos

まとめ

今回はDockerとは少し違うコンテナ技術を紹介しました。 systemd-nspawnのコンテナは仮想マシンとほぼ同等に扱えるため、開発環境の隔離に便利です。 特にコンテナ内で無理なく複数プロセスを起動できるのは、Dockerと比較した際の大きな強みとなるでしょう。 Docker同様使い方次第でいろいろな遊び方ができますので、みなさんも是非触れてみましょう。

それでは、 Happy Hacking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment