
2026/10/24 5:37
systemd-nspawn コンテナのブリーフィングツアー
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
systemd-nspawn は、Linux の名前空間を活用した軽量な VM 並みの隔離を提供し、書き込み可能なルートファイルシステムを /var/lib/machines に格納します。GPU の共有や仮想化のオーバーヘッド(ネステッド VM など)を回避することが必要で、Docker の直接ファイルアクセスに関する制限が課題となるハードウェア制約のある環境において最適なソリューションです。この技術は「強化された chroot」のように機能しますが、厳格なリソース制限と UID/GID の隔離により、より優れたセキュリティを提供します。
実装方法はディストリビューションによって異なります:Debian 系では
debootstrap を用いてルート FS を作成し、RHEL 系では dnf を使用し、Alpine Linux では主機 /dev のマウントなど危険なデフォルトを回避するためにカスタムスクリプト (alpine-nspawn-install) を必要とします。特に、Alpine のセットアップは Debian (338M) または Fedora (507M) に比べて著しく小さい(16M)ことが確認されており、これは最小限の依存関係によるものです。
管理は
/etc/systemd/nspawn/ 内の systemd ユニットファイルを介して machinectl を用いて行われます。ネットワーク設定については、ホストアクセス、ブリッジリング、NAT のいずれかを選択でき、NAT の場合は RFC 1918 などのカスタムサブネットと iptables MASQUERADE ルールが必要となります。ハードウェア共有(例:NVIDIA GPU)は、virtiofs ドライバーを必要とせずにデバイスノード (/dev/nvidia*) を直接バインドすることで実現されます。安定性を確保するためには、リソース枯渇を防ぐためにサービスユニットファイル内に厳格な CPU クォータ、メモリ制限、I/O バンドWIDTH 上限を設定するべきです。本文
systemd-nspawn で LLM 実行環境を構築・管理する方法:完全ガイド
本稿では、
を利用した軽量コンテナ技術の導入方法と、独自ホストの大規模言語モデル(LLM)や Open WebUI の実行環境として活用する手順について解説します。Docker の代替手段として、VM に近い動作特性を活かしながらハードウェアリソースを共有できる「強化版 chroot」の使い方を詳述します。systemd-nspawn
修正ノート (2025-05-19): Alpine Linux 用のコンテナ作成手順をより安全なものに変更し、Alpine Linux コンテナの設定に関する追加ガイドを追加しました。
概要と使用ケース
systemd-nspawn と Docker の違い
- Docker:
でイメージを事前に構築・配布する「読み取り専用」モデル。Dockerfile - systemd-nspawn: 書き込み可能なルートファイルシステムを使用するため、仮想マシン(VM)に近い動作。
- 「強化版の chroot」と考えて差し支えありません。
主な使用シナリオ
- VPS 上で隔離性を確保したいが、ネスト型仮想化が利用できない場合。
- GPU や他のハードウェアリソースを共有する必要がある場合(LLM 実行など)。
- 仮想化に伴うオーバーヘッドを避けたい場合。
- ホスト上の特定ファイルへ直接アクセスし、複雑な
な手段を使いたい場合。virtiofs - Docker の利用が不可能、または望ましくない場合。
ルートファイルシステムの作成 (chroot)
systemd-nspawn は独立したルートファイルシステム(rootfs)が必要です。一般的な慣習として、インストール先は**/var/lib/machines/[hostname]** です。
以下に代表的なディストリビューションごとの構築方法を示します。私は Debian 上でテストを行っておりますが、他でも同様に実装可能です。
Debian ファミリー向け (debootstrap
)
debootstrapDebian ベースの OS(Ubuntu や Debian そのもの)においてルートファイルシステムを作成する標準ツールです。
-
ツールインストール
sudo apt install debootstrap- 他のディストリビューションからは、ソースから直接取得することも可能です:
curl -L https://salsa.debian.org/installer-team/debootstrap/-/archive/master/debootstrap-master.tar.gz | tar xz cd debootstrap-master/ ./debootstrap
- 他のディストリビューションからは、ソースから直接取得することも可能です:
-
ルートファイルシステム作成
# --include: systemd, dbus, locales, bash-completion, curl を追加インストール sudo debootstrap --include=systemd,dbus,locales,bash-completion,curl bookworm /var/lib/machines/debian- 結果:
にベースシステムが作成されます。/var/lib/machines/debian
- 結果:
RHEL 系ディストリビューション向け (dnf
インストール)
dnfRHEL/Fedora 系環境を構築する手順です(例:Debian OS 上で動作させます)。
-
前提環境整備
sudo apt install dnf rpm sudo mkdir -p /var/lib/rpm sudo rpm --initdb -
Fedora 41 の chroot 作成
# ディレクトリ構造の準備 (etc/dnf/dnf.conf が必要) sudo mkdir -p /var/lib/machines/fedora/etc/dnf # dnf.conf の設定 (metalink, gpgkey など) sudo tee /var/lib/machines/fedora/etc/dnf/dnf.conf > /dev/null <<'EOF' [fedora] name=Fedora $releasever - $basearch metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch gpgkey=https://getfedora.org/static/fedora.gpg [updates] name=Fedora $releasever - $basearch - Updates metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$releasever&arch=$basearch gpgkey=https://getfedora.org/static/fedora.gpg EOF # インストール (Fedora 41) sudo dnf --releasever=41 --best --setopt=install_weak_deps=False \ --repo=fedora --repo=updates --installroot=/var/lib/machines/fedora \ install dnf fedora-release glibc glibc-langpack-en iproute iputils less ncurses passwd \ systemd systemd-networkd systemd-resolved util-linux vim-default-editor
Alpine Linux 向け (alpine-nspawn-install
)
alpine-nspawn-installAlpine は軽量ですが、公式の
alpine-chroot-install は危険なデフォルト設定(例:rm -rf ~ や /dev の権限破損)を含んでいるため、自作スクリプト**alpine-nspawn-install**を使用します。
# スクリプト取得 wget https://raw.githubusercontent.com/quantum5/alpine-nspawn-install/refs/heads/master/alpine-nspawn-install # インストール実行 (-d: 設定ディレクトリ指定) sudo bash alpine-nspawn-install -d /var/lib/machines/alpine
サイズ比較
| OS | サイズ | 備考 |
|---|---|---|
| Debian | 338M | 快適運用のためローカライズも含んでいるため若干大きい。 |
| Fedora | 507M | パッケージリストの影響で肥大化している。 |
| Alpine | 16M | 桁違いの軽量さを実現。推奨。 |
コンテナの初期起動と設定
単発ブートによるアクセス
まずはコンテナ内に root シェルにログインしてみましょう。
sudo systemd-nspawn -D /var/lib/machines/debian -M debian --private-users=pick --private-users-ownership=chown
: ルートファイルシステム指定 (-D
)/var/lib/machines/[name]
: マシン名(ホストネームとしても設定される)-M
: UID/GID ネームスペース有効化(セキュリティ向上)--private-users=pick
: 所有権の自動修正--private-users-ownership=chown
Debian 特有の設定ヒント
単発起動では
systemd が完全に起動していないため、以下の設定は正式な運用時に行う必要があります。
-
環境設定の簡略化 (長時間利用する場合)
cp /etc/skel/.bashrc . . ~/.bashrc -
ホストネームの修正
はデフォルトでホスト名をコピーしますが、コンテナ固有の名前に変更する必要があります。debootstraphostname > /etc/hostname -
再エントリ (再起動) シャットアウトした後、再度起動するには:
sudo systemd-nspawn -D /var/lib/machines/debian -M debian --private-users=yes
正式な運用環境への移行
長期的な運用のためには、
systemd-nspawn@[name].service ユニットを作成し、背景プロセスとして起動する必要があります。
Debian の設定例
-
SSH サーバーのインストールと設定
apt install openssh-server # SSH キーの設定 (公開鍵をコンテナ内へ転送) curl -q https://ssh.qt.ax -o ~/.ssh/authorized_keys- ※初回起動時は
が動作しない可能性があります。ユニット定義で自動起動させる必要があります。sshd
- ※初回起動時は
-
ユニットファイルの作成.nspawn
を作成します:/etc/systemd/nspawn/debian.nspawnsudo mkdir -p /etc/systemd/nspawn sudo tee /etc/systemd/nspawn/debian.nspawn > /dev/null <<'EOF' [Exec] PrivateUsers=yes # ネットワークやリソース制限などの追加設定は後述の項目で指定します。 EOF -
ユニットの有効化と起動
sudo machinectl start debian sudo machinectl login debian- エクジットするには
を 3 回押し、またはCtrl+]
で停止します。machinectl stop
- エクジットするには
Alpine Linux の補足
Alpine は systemd ベースではないため、以下の設定が必要です(
alpine-nspawn-install を使えば自動で実行されます)。
apk add openrc openssh-server rc-update add sshd rc-update add networking hostname > /etc/hostname mkdir -p ~/.ssh wget https://ssh.qt.ax -O ~/.ssh/authorized_keys
ネットワーク設定
コンテナのネットワーク接続は、
.nspawn ファイル内の [Network] セクションまたはコマンドライン引数で行います。
1. ホストネットワーク共有 (推奨しない)
ホストと完全なネットワークを共有し、隔離性を損なう方法です。デフォルト設定です。
ファイル設定:.nspawn[Network] VirtualEthernet=no
2. ブリッジ (Bridge) の活用
コンテナ専用のネットワークインタフェースを作成し、ホストの LAN に接続します。
A. ホストと同一ネットワークへ接続する(IP アドレスを保持)
自宅ルーターの背後などで動作させる場合、既存のインタフェース
eth0 をブリッジに追加します。
-
ホスト側の設定 (
)/etc/network/interfacesauto br_test iface br_test inet static bridge-ports eth0 bridge-stp off bridge-fd 0 address 192.0.2.123/24 # ホストの IP に変更 gateway 192.0.2.1 # ゲートウェイに変更 iface br_test inet6 static address 2001:db8::123/64 # ホストの IPv6 に変更 gateway 2001:db8::1 -
コンテナへの接続 (
ファイル).nspawn[Network] Bridge=br_testコンテナ内での
も同様に設定し、ブリッジ上の未使用 IP を割り当てます。/etc/network/interfaces
B. NAT 構成(VPS などで単一 IP の場合)
ブリッジを作成せず、ホストのルーターとして機能させます。
-
ホスト側の仮想インタフェース作成
auto br_test iface br_test inet static bridge-ports none bridge-stp off bridge-fd 0 address 192.0.2.1/24 # サブネットの最初のアドレス iface br_test inet6 static address 2001:db8::1/64 -
NAT ルールの追加
# 全体へ MASQUERADE(ランダム IP 割り当て) sudo iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -j MASQUERADE # 特定 IP への SNAT(高速化用、ホストが静的 IP を持つ場合) sudo iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -j SNAT --to-source 198.51.100.123 # IPv6 転送の設定 echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.conf sudo sysctl -p -
コンテナ接続
ファイルに.nspawn
を設定し、コンテナ内部で DHCP/SLAAC または静的 IP を設定します。Bridge=br_test
コンテナへの接続テスト
ネットワーク設定が完了すれば SSH でアクセス可能です。
ping 192.0.2.124 ssh root@192.0.2.124
ファイル・ディレクトリのバインドマウント
ホスト上の特定ファイルをコンテナへ書き込み可能にします。
.nspawn
ファイル内の設定例
.nspawn[Files] # ホストパス -> コンテナパス (読み書き) Bind=/srv/example # 只読アクセス BindReadOnly=/srv/example:/data # 再帰バインド禁止 Bind=/srv/example:/test:norbind
UID マッピングと ACL
コンテナ内の UID
Z とホストの UID X+Z を紐付けることで、権限管理を容易にします。
- noidmap: デフォルト。コンテナ内の
をホストのZ
にマッピング。X+Z - rootidmap: コンテナ root をバインドパスの所有者にマッピング。
- owneridmap: 所有権を保持してマッピング。
ACL を利用した柔軟なアクセス制御例:
# UID 133337 に /srv/example 下の全ファイルへ rwX 権限付与 setfacl -Rm u:133337:rwX /srv/example # 新規作成のファイルにも適用する setfacl -Rdm u:133337:rwX /srv/example
GPU の共有
KVM の VFIO と異なり、ホストと複数のゲスト間でデバイスを共有できます。
/dev/nvidia* をバインドマウントします。
Nvidia GPU 設定例
ファイル:.nspawn
[Files] Bind=/dev/nvidia0 Bind=/dev/nvidiactl Bind=/dev/nvidia-modeset Bind=/dev/nvidia-uvm Bind=/dev/nvidia-uvm-tools [Service] DeviceAllow=/dev/nvidia0 rw DeviceAllow=/dev/nvidiactl rw DeviceAllow=/dev/nvidia-modeset rw DeviceAllow=/dev/nvidia-uvm rw DeviceAllow=/dev/nvidia-uvm-tools rw
※ゲスト内のドライババージョンとホストが一致していることを確認してください。
Intel / AMD GPU
同様に
/dev/dri 系デバイスへのアクセス権限を追加します。
リソース使用量の制限
CPU コアやメモリ、I/O を制限してノイズを防ぎます。
[Exec] # CPU アフィニティ (コア 0,1,8,9 のみ利用) CPUAffinity=0-1,8-9 [Service] # CPU クォータ (2 コア分) CPUQuota=200% # メモリ制限 MemoryMax=1G MemorySwapMax=512M # I/O バンド幅制限 IOReadBandwidthMax=100M IOWriteBandwidthMax=100M
詳細は
systemd.resource-control のドキュメントを参照してください。
おわりに
本稿では、
を用いたコンテナ環境の構築から GPU 共有、リソース制限までを網羅しました。systemd-nspawn
- Docker との違い:書き込み可能な FS、VM 的な挙動。
- 利点:軽量性(特に Alpine)、ハードウェア共有、過渡的な隔離性。
- 運用方法:
ファイルを編集して柔軟にカスタマイズ可能。.nspawn
最初こそ設定が複雑ですが、一度構築すれば名前や IP アドレスの設定だけで起動できるようになります。**「完全なコントロール」と「仮想マシンと同様の機能」**を手頃なサイズで実現できるのが最大の特徴です。