「Systemd-nspawn」の版間の差分
Kusakata.bot2 (トーク | 投稿記録) (Pkg/AUR テンプレートの更新) |
|||
(2人の利用者による、間の24版が非表示) | |||
1行目: | 1行目: | ||
{{Lowercase title}} |
{{Lowercase title}} |
||
[[Category:仮想化]] |
[[Category:仮想化]] |
||
+ | [[Category:サンドボックス]] |
||
[[en:Systemd-nspawn]] |
[[en:Systemd-nspawn]] |
||
+ | [[es:Systemd-nspawn]] |
||
+ | [[ru:Systemd-nspawn]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
− | {{ |
+ | {{Related|systemd}} |
{{Related|Linux Containers}} |
{{Related|Linux Containers}} |
||
− | {{ |
+ | {{Related|systemd-networkd}} |
− | {{ |
+ | {{Related|Docker}} |
{{Related|Lxc-systemd}} |
{{Related|Lxc-systemd}} |
||
+ | {{Related|Getty#Nspawn コンソール}} |
||
+ | {{Related|mkosi}} |
||
{{Related articles end}} |
{{Related articles end}} |
||
− | ''systemd-nspawn'' は [[ |
+ | ''systemd-nspawn'' は [[chroot]] コマンドに似ていますが、''chroot を強化したもの''です。 |
− | ''systemd-nspawn'' を使えば軽量な名前空間コンテナでコマンドや OS を実行することができます。ファイルシステム構造だけでなく、プロセスツリーや様々な IPC サブシステム、ホスト・ドメイン名も完全に仮想化するため [[ |
+ | ''systemd-nspawn'' を使えば軽量な名前空間コンテナでコマンドや OS を実行することができます。ファイルシステム構造だけでなく、プロセスツリーや様々な IPC サブシステム、ホスト・ドメイン名も完全に仮想化するため [[chroot]] よりも強力です。 |
''systemd-nspawn'' は {{ic|/sys}}, {{ic|/proc/sys}}, {{ic|/sys/fs/selinux}} などのコンテナの様々なカーネルインターフェイスへのアクセスを読み取り専用に制限します。コンテナの中からネットワークインターフェイスやシステムクロックを変更することは出来ません。デバイスノードを作成することも不可能です。コンテナの中からホスト環境を再起動することはできず、カーネルモジュールをロードすることも制限されます。 |
''systemd-nspawn'' は {{ic|/sys}}, {{ic|/proc/sys}}, {{ic|/sys/fs/selinux}} などのコンテナの様々なカーネルインターフェイスへのアクセスを読み取り専用に制限します。コンテナの中からネットワークインターフェイスやシステムクロックを変更することは出来ません。デバイスノードを作成することも不可能です。コンテナの中からホスト環境を再起動することはできず、カーネルモジュールをロードすることも制限されます。 |
||
− | 仕組みとしては [[Lxc-systemd]] や [[ |
+ | 仕組みとしては [[Lxc-systemd]] や [[Libvirt]]-lxc と異なり、とてもシンプルなツールで設定を行います。 |
== インストール == |
== インストール == |
||
26行目: | 31行目: | ||
=== コンテナに最小限の Arch Linux ディストリビューションを作成して起動 === |
=== コンテナに最小限の Arch Linux ディストリビューションを作成して起動 === |
||
− | まず |
+ | まず {{Pkg|arch-install-scripts}} パッケージを[[pacman|インストール]]してください。 |
そして、お好きな場所にディレクトリを作成してください。例えば: {{ic|$ mkdir ~/''MyContainer''}}。 |
そして、お好きな場所にディレクトリを作成してください。例えば: {{ic|$ mkdir ~/''MyContainer''}}。 |
||
− | pacstrap を使って最小限の arch システムをコンテナにインストールします。最低限でも {{ |
+ | pacstrap を使って最小限の arch システムをコンテナにインストールします。最低限でも {{Pkg|base}} グループはインストールする必要があります。 |
− | # pacstrap -i -c |
+ | # pacstrap -i -c ~/MyContainer base [additional pkgs/groups] |
− | {{Tip| |
+ | {{Tip|{{ic|-i}} オプションはパッケージ選択の自動確認を無効にします。コンテナ上に Linux カーネルをインストールする必要はないため、パッケージリストの選択から[[Pacman#使い方|削除]]することができます。}} |
+ | {{Note|{{Pkg|base}} グループに含まれている {{Pkg|linux}} は {{Pkg|linux-firmware}} パッケージを必要としていますがコンテナを実行するのに必要というわけではなく、{{ic|systemd-nspawn}} で起動を行うときに {{ic|systemd-tmpfiles-setup.service}} に問題を発生させることがあります。コンテナを作成するとき {{Pkg|base}} グループをインストールすることは可能ですが、その場合 {{ic|# pacstrap -i -c ~/MyContainer base --ignore linux [additional pkgs/groups]}} として {{Pkg|linux}} パッケージやその依存パッケージは除外してください。{{ic|--ignore}} フラグは {{Pkg|pacman}} に渡されます。詳しくは {{Bug|46591}} を参照。}} |
||
− | インストールが完了したら、コンテナを起動してください: |
||
+ | |||
− | # systemd-nspawn -bD ~/MyContainer |
||
+ | インストールが完了したら、コンテナを起動してください ({{ic|-b}} はシェルを実行する代わりにコンテナを起動します (つまり PID=1 として {{ic|systemd}} を実行)。{{ic|-D}} にはコンテナのルートディレクトリにするディレクトリを指定します): |
||
+ | # systemd-nspawn -b -D ~/MyContainer |
||
これで終わりです。空のパスワードを使って "root" でログインしてください。 |
これで終わりです。空のパスワードを使って "root" でログインしてください。 |
||
+ | コンテナの電源を切りたいときはコンテナの中から {{ic|poweroff}} を実行することで出来ます。ホストからは、[[#machinectl|machinectl]] ツールでコンテナを制御できます。 |
||
− | セッションを終了するには {{ic|Ctrl}} を押しながら {{ic|]}} を3回押してください。コンテナは実行し続けますが、セッションは終了します。 |
||
+ | |||
+ | {{Note|コンテナの中からセッションを終了するには {{ic|Ctrl}} を押しながら {{ic|]}} を素早く3回押してください。US キーボード以外の場合は {{ic|]}} の代わりに {{ic|%}} を使用します。}} |
||
+ | |||
+ | ==== x86_64 環境で Arch Linux i686 をブートストラップ ==== |
||
+ | |||
+ | サブディレクトリの中に i686 の最小限の Arch Linux をインストールして [[chroot]] や[[:カテゴリ:仮想化|仮想化]]するかわりに systemd-nspawn コンテナとして使うことができます。i686 環境で {{ic|PKGBUILD}} のコンパイルをテストしたい場合などに有用です。{{ic|pacman.conf}} で {{ic|multilib}} リポジトリが有効になっていないことを確認してください。 |
||
+ | |||
+ | # pacman_conf=/tmp/pacman.conf # this is pacman.conf without multilib |
||
+ | # mkdir /mnt/i686-archlinux |
||
+ | # linux32 pacstrap -C "$pacman_conf" -i /mnt/i686-archlinux base base-devel |
||
+ | |||
+ | {{ic|base}} グループの {{ic|linux}} の選択は解除してかまいません。作成されるブートストラップディレクトリは実機や仮想マシン上で実行するわけではないためです。 |
||
+ | |||
+ | 作成された i686 の Arch Linux の systemd-nspawn インスタンスを起動するには、以下のコマンドを実行: |
||
+ | |||
+ | # linux32 systemd-nspawn -D /mnt/i686-archlinux |
||
+ | |||
+ | === Debian や Ubuntu 環境の作成 === |
||
+ | |||
+ | {{Pkg|debootstrap}} と {{Pkg|debian-archive-keyring}} か {{Pkg|ubuntu-keyring}} のどちらか (インストールしたい方のディストリのキーリング) をインストールしてください。 |
||
+ | |||
+ | {{Note|systemd-nspawn を使用するにはコンテナ内の OS で systemd が PID 1 として動作している必要があります。Ubuntu 15.04 以前は、そのままでは動作せず、upstart から systemd への移行が必須です。また、コンテナ環境に {{ic|systemd-container}} パッケージをインストールしてください。}} |
||
+ | |||
+ | 後は簡単に Debian や Ubuntu 環境をセットアップできます: |
||
+ | |||
+ | # cd /var/lib/machines |
||
+ | # debootstrap <codename> myContainer <repository-url> |
||
+ | |||
+ | Debian の場合、コードネームとして指定するのは "stable" や "testing" などのローリングの名前か "stretch" や "sid" などのリリース名になります。Ubuntu の場合、"xenial" や "zesty" などのコードネームを使ってください。コードネームの完全なリストは {{ic|/usr/share/debootstrap/scripts}} にあります。Debian イメージの場合は "repository-url" には {{ic|<nowiki>http://deb.debian.org/debian/</nowiki>}} などを指定します。Ubuntu のイメージの場合は "repository-url" は {{ic|<nowiki>http://archive.ubuntu.com/ubuntu/</nowiki>}} などとなります。 |
||
+ | |||
+ | Arch と違って、Debian や Ubuntu は最初のログイン時にパスワードが要ることになっています。root のパスワードを設定するために、'-b' オプションを付けずにログインしてからパスワードを設定してください: |
||
+ | |||
+ | # systemd-nspawn -D myContainer |
||
+ | # passwd |
||
+ | # logout |
||
+ | |||
+ | 上記のコマンドで上手く行かない場合、コンテナを起動してから以下のコマンドを使ってみてください: |
||
+ | |||
+ | # systemd-nspawn -b -D myContainer #Starts the container |
||
+ | # machinectl shell root@myContainer /bin/bash #Get a root bash shell |
||
+ | # passwd |
||
+ | # logout |
||
+ | |||
+ | === プライベートユーザーの作成 (非特権コンテナ) === |
||
+ | |||
+ | ''systemd-nspawn'' は非特権コンテナをサポートしていますが、コンテナは root で起動する必要があります。 |
||
+ | |||
+ | {{Note|非特権コンテナは {{man|7|user_namespaces}} を必要とします。詳しくは [[Linux Containers#非特権コンテナのサポートを有効化 (任意)]] を参照してください。}} |
||
+ | |||
+ | 非特権コンテナを使うときは ''systemd-nspawn'' に全てを決めさせるのが一番簡単です: |
||
+ | |||
+ | # systemd-nspawn -UD myContainer |
||
+ | # passwd |
||
+ | # logout |
||
+ | # systemd-nspawn -bUD myContainer |
||
+ | |||
+ | 上記のコマンドで ''systemd-nspawn'' はディレクトリの所有者が使われているかどうか確認して、使われていない場合は所有者をベースとしてそれを上回る 65536 の ID が使われます。一方で UID/GID が使用中の場合はランダムに 524288 - 1878982656 の範囲から 65536 の ID を選択します。 |
||
+ | |||
+ | {{Note| |
||
+ | * ランダムに選ばれるベース ID は必ず 65536 の倍数です。 |
||
+ | * カーネルがユーザー名前空間をサポートしている場合、{{ic|-U}} と {{ic|1=--private-users=pick}} は同じです。{{ic|1=--private-users=pick}} には {{ic|1=--private-users-chown}} が暗黙的に含まれます。詳しくは {{man|1|systemd-nspawn}} を参照してください。 |
||
+ | }} |
||
+ | |||
+ | コンテナの UID/GID を手動で指定することも可能です: |
||
+ | |||
+ | # systemd-nspawn -D myContainer --private-users=1354956800:65536 --private-users-chown |
||
+ | # passwd |
||
+ | # logout |
||
+ | # systemd-nspawn -bUD myContainer |
||
+ | |||
+ | コンテナの起動時に {{ic|1=--private-users=1354956800:65536}} と {{ic|--private-users-chown}} を使うこともできますが、無駄に複雑なので、ID を割り当てた後に {{ic|-U}} を使うようにしてください。 |
||
=== マシンのブート時にコンテナを起動する === |
=== マシンのブート時にコンテナを起動する === |
||
− | コンテナを頻繁に使用 |
+ | コンテナを頻繁に使用する場合、ブート時に systemd でコンテナを起動できます。まず {{ic|systemd}} ターゲットの {{ic|machines.target}} を有効化してください: |
+ | |||
+ | # systemctl enable machines.target |
||
+ | |||
+ | それから以下を実行してください: |
||
− | # mv ~/MyContainer /var/lib/ |
+ | # mv ~/MyContainer /var/lib/machines/MyContainer |
# systemctl enable systemd-nspawn@MyContainer.service |
# systemctl enable systemd-nspawn@MyContainer.service |
||
# systemctl start systemd-nspawn@MyContainer.service |
# systemctl start systemd-nspawn@MyContainer.service |
||
− | {{Note| |
+ | {{Note|{{ic|systemd-nspawn@.service}} は nspawn コンテナが {{ic|/var/lib/machines}} にあることを想定したテンプレートユニットです。}} |
{{Tip| |
{{Tip| |
||
− | * |
+ | * {{Pkg|systemd}} v229 現在 {{ic|/var/lib/machines}} にコンテナのシンボリックリンクを作成しても動作しません。[https://github.com/systemd/systemd/issues/2001] を参照。 |
+ | * コンテナの起動をカスタマイズする場合、{{ic|/etc/systemd/nspawn/''myContainer''.nspawn}} ユニットを[[systemd#ユニットファイルの編集|編集]]してください。利用可能なオプションは {{man|5|systemd.nspawn}} を参照。 |
||
− | * ''systemd-nspawn'' サービスは次のコマンドを実行します: {{ic|<nowiki>/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=guest --directory=/var/lib/container/%i </nowiki>}}。ディスクイメージファイルを使用したりコンテナに [[SELinux|SELinux]] セキュリティを設定するために、コンテナのディレクトリから {{ic|/var/lib/container/MyCoantainer}} にシンボリックリンクが貼られていない場合、このファイルを修正してオプションを追加する必要があります。コンテナのネットワーク設定を分離させたい場合、[[systemd-networkd|systemd-networkd]] を参照してください。さらに詳しいブートオプションの情報は {{ic|systemd-nspawn(1)}} に載っています。 |
||
− | * {{ic|systemd-nspawn@.service}} を無効にすると、{{ic|# systemd-nspawn -bD /path/to/container}} を実行して手動でコンテナを起動することができます。コンテナにログインした後は、{{ic|# systemctl poweroff}} を実行すればシャットダウンします。 |
||
}} |
}} |
||
62行目: | 143行目: | ||
== 管理 == |
== 管理 == |
||
+ | |||
+ | 使用例は[[他のディストリビューションのパッケージの作成]]を参照。 |
||
=== machinectl === |
=== machinectl === |
||
+ | |||
+ | {{Note|''machinectl'' ツールを使うには [[systemd]] と {{Pkg|dbus}} がコンテナにインストールされている必要があります。詳しくは [https://github.com/systemd/systemd/issues/685] を参照。}} |
||
コンテナの管理は原則 {{ic|$ machinectl}} コマンドで行います。このサービスを使って仮想マシンやコンテナの状態を確認したり操作します。オプションの詳細なリストは {{ic|machinectl(1)}} を参照してください。 |
コンテナの管理は原則 {{ic|$ machinectl}} コマンドで行います。このサービスを使って仮想マシンやコンテナの状態を確認したり操作します。オプションの詳細なリストは {{ic|machinectl(1)}} を参照してください。 |
||
69行目: | 154行目: | ||
例: |
例: |
||
− | * 実行中のコンテナに新しいシェルを起動: {{bc|machinectl login MyContainer}} |
+ | * 実行中のコンテナに新しいシェルを起動: {{bc|$ machinectl login MyContainer}} |
− | * コンテナの詳細情報を表示: {{bc| machinectl status MyContainer}} |
+ | * コンテナの詳細情報を表示: {{bc|$ machinectl status MyContainer}} |
− | * コンテナを再起動: {{bc| machinectl reboot MyContainer}} |
+ | * コンテナを再起動: {{bc|$ machinectl reboot MyContainer}} |
− | * コンテナを電源オフ: {{bc| |
+ | * コンテナを電源オフ: {{bc|$ machinectl poweroff MyContainer}} |
+ | :{{Tip|電源オフや再起動は ''systemctl'' の {{ic|reboot}} や {{ic|poweroff}} コマンドをコンテナのセッションの中から実行することでも可能です。}} |
||
− | |||
+ | * イメージをダウンロード: {{bc|# machinectl pull-tar ''URL'' ''name''}} |
||
− | {{Tip|シャットダウンや再起動は systemd の {{ic|reboot}} や {{ic|shutdown}} コマンドをコンテナのセッションの中から実行することでも可能です。}} |
||
=== systemd ツールチェイン === |
=== systemd ツールチェイン === |
||
82行目: | 167行目: | ||
例: |
例: |
||
− | * 特定のマシンの journal ログを表示: {{bc| |
+ | * 特定のマシンの journal ログを表示: {{bc|$ journalctl -M MyContainer}} |
* control group の中身を表示: {{bc|$ systemd-cgls -M MyContainer}} |
* control group の中身を表示: {{bc|$ systemd-cgls -M MyContainer}} |
||
* コンテナの起動時間を表示: {{bc|$ systemd-analyze -M MyContainer}} |
* コンテナの起動時間を表示: {{bc|$ systemd-analyze -M MyContainer}} |
||
+ | * リソース利用状況を表示: {{bc|$ systemd-cgtop}} |
||
+ | == ヒントとテクニック == |
||
− | == Tips == |
||
=== X 環境 === |
=== X 環境 === |
||
93行目: | 179行目: | ||
外部の X サーバーにコンテナのセッションを接続するには {{ic|DISPLAY}} 環境変数を設定する必要があります。 |
外部の X サーバーにコンテナのセッションを接続するには {{ic|DISPLAY}} 環境変数を設定する必要があります。 |
||
+ | |||
+ | X は必要なファイルを {{ic|/tmp}} ディレクトリに保存します。コンテナから全てを表示させるには、{{ic|/tmp}} ディレクトリのファイルにアクセスできるようにしなくてはなりません。コンテナを起動するときに {{ic|--bind<nowiki>=</nowiki>/tmp/.X11-unix:/tmp/.X11-unix}} オプションを追加してください。 |
||
+ | |||
+ | {{Note|systemd バージョン 235 には [https://github.com/systemd/systemd/issues/7093 バグ] が存在し、{{ic|/tmp/.X11-unix}} がファイルシステムから消失することがあります。問題を回避するには {{ic|/tmp/.X11-unix}} を読み取り専用でバインドしてください: {{ic|--bind-ro<nowiki>=</nowiki>/tmp/.X11-unix/X0}}。{{ic|/run/user/1000}} もバインドしている場合は明示的に {{ic|/run/user/1000/bus}} を読み取り専用でバインドすることで dbus ソケットが削除されないように保護することができます。}} |
||
+ | |||
+ | === nspawn コンテナの中で Firefox を実行 === |
||
+ | |||
+ | [[Firefox 設定#nspawn コンテナの中で Firefox を実行]]を見て下さい。 |
||
+ | |||
+ | === ホストのファイルシステムにアクセス === |
||
+ | |||
+ | 例えばホストとコンテナの両方が Arch Linux で、pacman のキャッシュを共有するには: |
||
+ | |||
+ | # systemd-nspawn --bind=/var/cache/pacman/pkg |
||
+ | |||
+ | 詳しくは {{man|1|systemd-nspawn}} の {{ic|--bind}} と {{ic|--bind-ro}} を参照してください。 |
||
+ | |||
+ | ファイルを使ってコンテナごとにバインドを設定することもできます: |
||
+ | |||
+ | {{hc|/etc/systemd/nspawn/''my-container''.nspawn|<nowiki> |
||
+ | [Files] |
||
+ | Bind=/var/cache/pacman/pkg |
||
+ | </nowiki>}} |
||
+ | |||
+ | [[#コンテナごとに設定を指定する]]を参照。 |
||
=== ネットワーク === |
=== ネットワーク === |
||
+ | ネットワーク管理に [[systemd-networkd]] を使用して DNS に {{ic|systemd-resolved}} を使用する、インターネットに接続できる最も簡単な設定: |
||
− | 上で説明しているインストールでは、何も設定しなくてもネットワークが動作するコンテナが作られるので、追加の設定は必要ありません。もっと複雑なネットワークを設定してホストのネットワークからコンテナのネットワークを分離させたいときは、[[systemd-networkd]] を見て下さい。 |
||
+ | |||
+ | # systemctl enable --now systemd-networkd systemd-resolved |
||
+ | # ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf # let systemd-resolved manage /etc/resolv.conf |
||
+ | |||
+ | 上記の設定を使うには {{ic|-n}} スイッチを使って {{ic|systemd-nspawn}} を実行して、ホストに仮想イーサネットリンクを作成する必要があります。 |
||
+ | |||
+ | {{ic|systemd-resolved}} を使わないでコンテナの {{ic|/etc/resolv.conf}} を手動で編集して DNS サーバーの IP アドレスを追加することも可能です。 |
||
+ | |||
+ | 基本的な [[systemd-networkd]] のホストとコンテナの {{ic|.network}} ファイルは https://github.com/systemd/systemd/tree/master/network にあります。 |
||
+ | |||
+ | もっと複雑なネットワークを設定する方法は、[[systemd-networkd#コンテナでの使用方法]]を見て下さい。 |
||
+ | |||
+ | ==== nsswitch.conf ==== |
||
+ | |||
+ | ホストからコンテナへの接続を楽にするために、コンテナの名前のローカル DNS 解決を有効にすることができます。{{ic|/etc/nsswitch.conf}} の {{ic|hosts:}} セクションに {{ic|mymachines}} を追加してください: |
||
+ | |||
+ | hosts: files mymachines dns myhostname |
||
+ | |||
+ | こうすると、ホスト上でホストネーム {{ic|foo}} の DNS ルックアップで {{ic|/etc/hosts}} が参照され、それからローカルコンテナの名前、上流の DNS などが参照されます。 |
||
+ | |||
+ | ==== ホストのネットワークを使用 ==== |
||
+ | |||
+ | {{ic|machinectl start MyContainer}} で起動したコンテナによって使用されるプライベートネットワークを無効化するには {{ic|systemctl edit systemd-nspawn@.service}} を実行して {{ic|systemd-nspawn@.service}} サービスファイルの設定を編集してください。{{ic|--network-veth}} パラメータを削除するように {{ic|1=ExecStart=}} オプションを設定します: |
||
+ | |||
+ | {{hc|/etc/systemd/system/systemd-nspawn@.service.d/override.conf|<nowiki> |
||
+ | [Service] |
||
+ | ExecStart= |
||
+ | ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --machine=%I |
||
+ | </nowiki>}} |
||
+ | |||
+ | 次に起動したコンテナはホストのネットワークを使用するようになります。 |
||
+ | |||
+ | ==== 仮想イーサネットインターフェイス ==== |
||
+ | |||
+ | コンテナを {{ic|systemd-nspawn ... -n}} で起動した場合、systemd は自動的にホストとコンテナに仮想イーサネットインターフェイスを作成して、仮想イーサネットケーブルで接続します。 |
||
+ | |||
+ | コンテナの名前が {{ic|foo}} ならば、仮想イーサネットインターフェイスのホストにおける名前は {{ic|ve-foo}} になり、コンテナではどんな場合でも名前は {{ic|host0}} です。 |
||
+ | |||
+ | {{ic|ip link}} でインターフェイスを確認すると、インターフェイスの名前には {{ic|ve-foo@if2}} や {{ic|host0@if9}} のように接尾辞が付きます。{{ic|@ifN}} は実際はインターフェイスの名前には含まれていません。仮想イーサネットケーブルが他の端末に接続されていることを示すために {{ic|ip link}} によって情報が加えられています。 |
||
+ | |||
+ | 例えば、ホストの仮想イーサネットインターフェイス {{ic|ve-foo@if2}} がコンテナ {{ic|foo}} に接続、コンテナの中の2番目のネットワークインターフェイスに接続する場合、コンテナの中から {{ic|ip link}} を実行するとインデックス 2 が付きます。同じように、コンテナの {{ic|host0@if9}} という名前のインターフェイスはホストの9番目のインターフェイスに接続します。 |
||
+ | |||
+ | ==== ネットワークブリッジを使用 ==== |
||
+ | |||
+ | ローカルネットワークの物理マシンのようにコンテナに IP アドレスを割り当てるためにホスト環境にネットワークブリッジを設定している場合 (詳しくは [[systemd-networkd#2つの別々な IP で DHCP を使う]]や [[systemd-networkd#固定 IP ネットワーク]]を参照)、{{ic|1=--network-bridge=''br0''}} オプションを使って systemd-nspawn から利用することができます。 |
||
+ | |||
+ | === systemd を使っていない環境で動作させる === |
||
+ | |||
+ | [[Init#systemd-nspawn]] を見て下さい。 |
||
+ | |||
+ | === コンテナごとに設定を指定する === |
||
+ | |||
+ | 全体設定を上書きすることなく各コンテナの設定を指定したい場合 (例: どれかひとつのコンテナにディレクトリをバインドする場合)、{{ic|.nspawn}} ファイルを使うことで設定できます [https://github.com/systemd/systemd/issues/3442#issuecomment-223837408]。{{man|5|systemd.nspawn}} を見てください [https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html]。 |
||
+ | |||
+ | === Btrfs のサブボリュームをコンテナのルートとして使う === |
||
+ | |||
+ | [[Btrfs#サブボリューム|Btrfs サブボリューム]]をコンテナのルートのテンプレートとして使うには、{{ic|--template}} フラグを使用します。サブボリュームのスナップショットを使ってコンテナのルートディレクトリが生成されます。 |
||
+ | |||
+ | {{Note|指定されたテンプレートのパスがサブボリュームのルートでなかった場合、ツリー全体がコピーされます。その場合、非常に時間がかかります。}} |
||
+ | |||
+ | 例えば、{{ic|/.snapshots/403/snapshot}} に存在するスナップショットを使うには: |
||
+ | |||
+ | # systemd-nspawn --template=/.snapshots/403/snapshots -b -D ''my-container'' |
||
+ | |||
+ | {{ic|''my-container''}} は作成するコンテナのディレクトリの名前に置き換えてください。電源を切っても、新しく作成されたサブボリュームは消えません。 |
||
+ | |||
+ | === コンテナの一時的な Btrfs スナップショットを使う === |
||
+ | |||
+ | {{ic|--ephemeral}} や {{ic|-x}} フラグを使ってコンテナの一時的な btrfs スナップショットを作成してコンテナのルートとして利用できます。コンテナの実行中に変更が加えられても保存されません。例: |
||
+ | |||
+ | # systemd-nspawn -D ''my-container'' -xb |
||
+ | |||
+ | ''my-container'' はシステムに存在する既存のコンテナのディレクトリに置き換えてください。例えば {{ic|/}} が btrfs のサブボリュームだった場合、以下のコマンドで実行中のホスト環境の一時的なコンテナを作成することができます: |
||
+ | |||
+ | # systemd-nspawn -D / -xb |
||
+ | |||
+ | コンテナの電源を切ると、作成された btrfs サブボリュームはすぐに削除されます。 |
||
== トラブルシューティング == |
== トラブルシューティング == |
||
=== root ログインが失敗する === |
=== root ログインが失敗する === |
||
− | ログインしようとしたときに以下が表示される場合: |
+ | ({{ic|machinectl login <name>}} を使用して) ログインしようとしたときに以下のエラーが表示される場合: |
arch-nspawn login: root |
arch-nspawn login: root |
||
Login incorrect |
Login incorrect |
||
− | そして |
+ | そして {{ic|journalctl}} が以下のように表示する場合: |
pam_securetty(login:auth): access denied: tty 'pts/0' is not secure ! |
pam_securetty(login:auth): access denied: tty 'pts/0' is not secure ! |
||
− | コンテナのファイルシステム |
+ | コンテナのファイルシステム上にある {{ic|/etc/securetty}} のターミナル名のリストに {{ic|pts/0}} を追加してください。詳しくは [https://unix.stackexchange.com/questions/41840/effect-of-entries-in-etc-securetty/41939#41939] を参照。また、コンテナの {{ic|/etc/securetty}} を削除して root で全ての tty にログインできるようにするという方法もあります。[https://github.com/systemd/systemd/issues/852] を見てください。 |
+ | |||
+ | === コンテナのパッケージをアップグレードできない === |
||
+ | |||
+ | ときどきコンテナの特定のパッケージがアップグレードできなくなることがあります。{{Pkg|filesystem}} などが特にそうです。原因は {{ic|/sys}} が読み取り専用でマウントされていることにあります。{{ic|mount -o remount,rw -t sysfs sysfs /sys}} を実行してディレクトリを読み書き可能で再マウントしてから、アップグレードを行なって、コンテナを再起動してください。 |
||
== 参照 == |
== 参照 == |
||
− | * [ |
+ | * [https://www.freedesktop.org/software/systemd/man/machinectl.html machinectl man ページ] |
− | * [ |
+ | * [https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html systemd-nspawn man ページ] |
− | * [ |
+ | * [https://lwn.net/Articles/572957/ Creating containers with systemd-nspawn] |
* [https://www.youtube.com/results?search_query=systemd-nspawn&aq=f Lennart Pottering による systemd-nspawn のプレゼンテーション] |
* [https://www.youtube.com/results?search_query=systemd-nspawn&aq=f Lennart Pottering による systemd-nspawn のプレゼンテーション] |
||
+ | * [http://dabase.com/e/12009/ Running Firefox in a systemd-nspawn container] |
2019年11月21日 (木) 18:49時点における版
systemd-nspawn は chroot コマンドに似ていますが、chroot を強化したものです。
systemd-nspawn を使えば軽量な名前空間コンテナでコマンドや OS を実行することができます。ファイルシステム構造だけでなく、プロセスツリーや様々な IPC サブシステム、ホスト・ドメイン名も完全に仮想化するため chroot よりも強力です。
systemd-nspawn は /sys
, /proc/sys
, /sys/fs/selinux
などのコンテナの様々なカーネルインターフェイスへのアクセスを読み取り専用に制限します。コンテナの中からネットワークインターフェイスやシステムクロックを変更することは出来ません。デバイスノードを作成することも不可能です。コンテナの中からホスト環境を再起動することはできず、カーネルモジュールをロードすることも制限されます。
仕組みとしては Lxc-systemd や Libvirt-lxc と異なり、とてもシンプルなツールで設定を行います。
インストール
systemd-nspawn は systemd に含まれています。
サンプル
コンテナに最小限の Arch Linux ディストリビューションを作成して起動
まず arch-install-scripts パッケージをインストールしてください。
そして、お好きな場所にディレクトリを作成してください。例えば: $ mkdir ~/MyContainer
。
pacstrap を使って最小限の arch システムをコンテナにインストールします。最低限でも base グループはインストールする必要があります。
# pacstrap -i -c ~/MyContainer base [additional pkgs/groups]
インストールが完了したら、コンテナを起動してください (-b
はシェルを実行する代わりにコンテナを起動します (つまり PID=1 として systemd
を実行)。-D
にはコンテナのルートディレクトリにするディレクトリを指定します):
# systemd-nspawn -b -D ~/MyContainer
これで終わりです。空のパスワードを使って "root" でログインしてください。
コンテナの電源を切りたいときはコンテナの中から poweroff
を実行することで出来ます。ホストからは、machinectl ツールでコンテナを制御できます。
x86_64 環境で Arch Linux i686 をブートストラップ
サブディレクトリの中に i686 の最小限の Arch Linux をインストールして chroot や仮想化するかわりに systemd-nspawn コンテナとして使うことができます。i686 環境で PKGBUILD
のコンパイルをテストしたい場合などに有用です。pacman.conf
で multilib
リポジトリが有効になっていないことを確認してください。
# pacman_conf=/tmp/pacman.conf # this is pacman.conf without multilib # mkdir /mnt/i686-archlinux # linux32 pacstrap -C "$pacman_conf" -i /mnt/i686-archlinux base base-devel
base
グループの linux
の選択は解除してかまいません。作成されるブートストラップディレクトリは実機や仮想マシン上で実行するわけではないためです。
作成された i686 の Arch Linux の systemd-nspawn インスタンスを起動するには、以下のコマンドを実行:
# linux32 systemd-nspawn -D /mnt/i686-archlinux
Debian や Ubuntu 環境の作成
debootstrap と debian-archive-keyring か ubuntu-keyring のどちらか (インストールしたい方のディストリのキーリング) をインストールしてください。
後は簡単に Debian や Ubuntu 環境をセットアップできます:
# cd /var/lib/machines # debootstrap <codename> myContainer <repository-url>
Debian の場合、コードネームとして指定するのは "stable" や "testing" などのローリングの名前か "stretch" や "sid" などのリリース名になります。Ubuntu の場合、"xenial" や "zesty" などのコードネームを使ってください。コードネームの完全なリストは /usr/share/debootstrap/scripts
にあります。Debian イメージの場合は "repository-url" には http://deb.debian.org/debian/
などを指定します。Ubuntu のイメージの場合は "repository-url" は http://archive.ubuntu.com/ubuntu/
などとなります。
Arch と違って、Debian や Ubuntu は最初のログイン時にパスワードが要ることになっています。root のパスワードを設定するために、'-b' オプションを付けずにログインしてからパスワードを設定してください:
# systemd-nspawn -D myContainer # passwd # logout
上記のコマンドで上手く行かない場合、コンテナを起動してから以下のコマンドを使ってみてください:
# systemd-nspawn -b -D myContainer #Starts the container # machinectl shell root@myContainer /bin/bash #Get a root bash shell # passwd # logout
プライベートユーザーの作成 (非特権コンテナ)
systemd-nspawn は非特権コンテナをサポートしていますが、コンテナは root で起動する必要があります。
非特権コンテナを使うときは systemd-nspawn に全てを決めさせるのが一番簡単です:
# systemd-nspawn -UD myContainer # passwd # logout # systemd-nspawn -bUD myContainer
上記のコマンドで systemd-nspawn はディレクトリの所有者が使われているかどうか確認して、使われていない場合は所有者をベースとしてそれを上回る 65536 の ID が使われます。一方で UID/GID が使用中の場合はランダムに 524288 - 1878982656 の範囲から 65536 の ID を選択します。
コンテナの UID/GID を手動で指定することも可能です:
# systemd-nspawn -D myContainer --private-users=1354956800:65536 --private-users-chown # passwd # logout # systemd-nspawn -bUD myContainer
コンテナの起動時に --private-users=1354956800:65536
と --private-users-chown
を使うこともできますが、無駄に複雑なので、ID を割り当てた後に -U
を使うようにしてください。
マシンのブート時にコンテナを起動する
コンテナを頻繁に使用する場合、ブート時に systemd でコンテナを起動できます。まず systemd
ターゲットの machines.target
を有効化してください:
# systemctl enable machines.target
それから以下を実行してください:
# mv ~/MyContainer /var/lib/machines/MyContainer # systemctl enable systemd-nspawn@MyContainer.service # systemctl start systemd-nspawn@MyContainer.service
control group の中身を表示したい場合は、$ systemd-cgls
を実行してください。
管理
使用例は他のディストリビューションのパッケージの作成を参照。
machinectl
コンテナの管理は原則 $ machinectl
コマンドで行います。このサービスを使って仮想マシンやコンテナの状態を確認したり操作します。オプションの詳細なリストは machinectl(1)
を参照してください。
例:
- 実行中のコンテナに新しいシェルを起動:
$ machinectl login MyContainer
- コンテナの詳細情報を表示:
$ machinectl status MyContainer
- コンテナを再起動:
$ machinectl reboot MyContainer
- コンテナを電源オフ:
$ machinectl poweroff MyContainer
- イメージをダウンロード:
# machinectl pull-tar URL name
systemd ツールチェイン
systemd のコアツールチェインは多くがコンテナでも使えるようにアップデートされています。コンテナの名前を引数とする -M, --machine=
オプションをツールに付けるだけです。
例:
- 特定のマシンの journal ログを表示:
$ journalctl -M MyContainer
- control group の中身を表示:
$ systemd-cgls -M MyContainer
- コンテナの起動時間を表示:
$ systemd-analyze -M MyContainer
- リソース利用状況を表示:
$ systemd-cgtop
ヒントとテクニック
X 環境
新しいコンテナで X アプリケーションを動かす必要がある場合は Xhost を見て下さい。
外部の X サーバーにコンテナのセッションを接続するには DISPLAY
環境変数を設定する必要があります。
X は必要なファイルを /tmp
ディレクトリに保存します。コンテナから全てを表示させるには、/tmp
ディレクトリのファイルにアクセスできるようにしなくてはなりません。コンテナを起動するときに --bind=/tmp/.X11-unix:/tmp/.X11-unix
オプションを追加してください。
nspawn コンテナの中で Firefox を実行
Firefox 設定#nspawn コンテナの中で Firefox を実行を見て下さい。
ホストのファイルシステムにアクセス
例えばホストとコンテナの両方が Arch Linux で、pacman のキャッシュを共有するには:
# systemd-nspawn --bind=/var/cache/pacman/pkg
詳しくは systemd-nspawn(1) の --bind
と --bind-ro
を参照してください。
ファイルを使ってコンテナごとにバインドを設定することもできます:
/etc/systemd/nspawn/my-container.nspawn
[Files] Bind=/var/cache/pacman/pkg
#コンテナごとに設定を指定するを参照。
ネットワーク
ネットワーク管理に systemd-networkd を使用して DNS に systemd-resolved
を使用する、インターネットに接続できる最も簡単な設定:
# systemctl enable --now systemd-networkd systemd-resolved # ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf # let systemd-resolved manage /etc/resolv.conf
上記の設定を使うには -n
スイッチを使って systemd-nspawn
を実行して、ホストに仮想イーサネットリンクを作成する必要があります。
systemd-resolved
を使わないでコンテナの /etc/resolv.conf
を手動で編集して DNS サーバーの IP アドレスを追加することも可能です。
基本的な systemd-networkd のホストとコンテナの .network
ファイルは https://github.com/systemd/systemd/tree/master/network にあります。
もっと複雑なネットワークを設定する方法は、systemd-networkd#コンテナでの使用方法を見て下さい。
nsswitch.conf
ホストからコンテナへの接続を楽にするために、コンテナの名前のローカル DNS 解決を有効にすることができます。/etc/nsswitch.conf
の hosts:
セクションに mymachines
を追加してください:
hosts: files mymachines dns myhostname
こうすると、ホスト上でホストネーム foo
の DNS ルックアップで /etc/hosts
が参照され、それからローカルコンテナの名前、上流の DNS などが参照されます。
ホストのネットワークを使用
machinectl start MyContainer
で起動したコンテナによって使用されるプライベートネットワークを無効化するには systemctl edit systemd-nspawn@.service
を実行して systemd-nspawn@.service
サービスファイルの設定を編集してください。--network-veth
パラメータを削除するように ExecStart=
オプションを設定します:
/etc/systemd/system/systemd-nspawn@.service.d/override.conf
[Service] ExecStart= ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --machine=%I
次に起動したコンテナはホストのネットワークを使用するようになります。
仮想イーサネットインターフェイス
コンテナを systemd-nspawn ... -n
で起動した場合、systemd は自動的にホストとコンテナに仮想イーサネットインターフェイスを作成して、仮想イーサネットケーブルで接続します。
コンテナの名前が foo
ならば、仮想イーサネットインターフェイスのホストにおける名前は ve-foo
になり、コンテナではどんな場合でも名前は host0
です。
ip link
でインターフェイスを確認すると、インターフェイスの名前には ve-foo@if2
や host0@if9
のように接尾辞が付きます。@ifN
は実際はインターフェイスの名前には含まれていません。仮想イーサネットケーブルが他の端末に接続されていることを示すために ip link
によって情報が加えられています。
例えば、ホストの仮想イーサネットインターフェイス ve-foo@if2
がコンテナ foo
に接続、コンテナの中の2番目のネットワークインターフェイスに接続する場合、コンテナの中から ip link
を実行するとインデックス 2 が付きます。同じように、コンテナの host0@if9
という名前のインターフェイスはホストの9番目のインターフェイスに接続します。
ネットワークブリッジを使用
ローカルネットワークの物理マシンのようにコンテナに IP アドレスを割り当てるためにホスト環境にネットワークブリッジを設定している場合 (詳しくは systemd-networkd#2つの別々な IP で DHCP を使うや systemd-networkd#固定 IP ネットワークを参照)、--network-bridge=br0
オプションを使って systemd-nspawn から利用することができます。
systemd を使っていない環境で動作させる
Init#systemd-nspawn を見て下さい。
コンテナごとに設定を指定する
全体設定を上書きすることなく各コンテナの設定を指定したい場合 (例: どれかひとつのコンテナにディレクトリをバインドする場合)、.nspawn
ファイルを使うことで設定できます [3]。systemd.nspawn(5) を見てください [4]。
Btrfs のサブボリュームをコンテナのルートとして使う
Btrfs サブボリュームをコンテナのルートのテンプレートとして使うには、--template
フラグを使用します。サブボリュームのスナップショットを使ってコンテナのルートディレクトリが生成されます。
例えば、/.snapshots/403/snapshot
に存在するスナップショットを使うには:
# systemd-nspawn --template=/.snapshots/403/snapshots -b -D my-container
my-container
は作成するコンテナのディレクトリの名前に置き換えてください。電源を切っても、新しく作成されたサブボリュームは消えません。
コンテナの一時的な Btrfs スナップショットを使う
--ephemeral
や -x
フラグを使ってコンテナの一時的な btrfs スナップショットを作成してコンテナのルートとして利用できます。コンテナの実行中に変更が加えられても保存されません。例:
# systemd-nspawn -D my-container -xb
my-container はシステムに存在する既存のコンテナのディレクトリに置き換えてください。例えば /
が btrfs のサブボリュームだった場合、以下のコマンドで実行中のホスト環境の一時的なコンテナを作成することができます:
# systemd-nspawn -D / -xb
コンテナの電源を切ると、作成された btrfs サブボリュームはすぐに削除されます。
トラブルシューティング
root ログインが失敗する
(machinectl login <name>
を使用して) ログインしようとしたときに以下のエラーが表示される場合:
arch-nspawn login: root Login incorrect
そして journalctl
が以下のように表示する場合:
pam_securetty(login:auth): access denied: tty 'pts/0' is not secure !
コンテナのファイルシステム上にある /etc/securetty
のターミナル名のリストに pts/0
を追加してください。詳しくは [5] を参照。また、コンテナの /etc/securetty
を削除して root で全ての tty にログインできるようにするという方法もあります。[6] を見てください。
コンテナのパッケージをアップグレードできない
ときどきコンテナの特定のパッケージがアップグレードできなくなることがあります。filesystem などが特にそうです。原因は /sys
が読み取り専用でマウントされていることにあります。mount -o remount,rw -t sysfs sysfs /sys
を実行してディレクトリを読み書き可能で再マウントしてから、アップグレードを行なって、コンテナを再起動してください。