Macとsystemd-nspawnで普通の開発環境を作るまで(2)～起動設定～

# 概要

[前回の記事](https://qiita.com/yaasita/items/4e274a6b5ccdaa000970)の続きです
長いオプションの付いたsystemd-nspawnコマンドを毎回打たなくても、起動設定を行えば簡潔なmachinectlコマンドでコンテナを起動できます
今回はmachinectlの使えるようにする設定と使い方を書きます

# 起動設定

machinectlコマンドは内部でsystemctlコマンドを呼んでsystemd-nspawnを実行しますので、Unitファイルを作ります
マシン名を受け取るtemplateユニットとして設定しておきます

```bash
curl -L https://goo.gl/NZbdo8 > /etc/systemd/system/systemd-nspawn@.service
```

また内部でdbusが走っていないと, `machinectl login`, `machinectl shell` コマンドが使えないので予めインストールしておきます

```bash
cd /var/lib/machines
systemd-nspawn -b -D ./ubuntu --network-bridge=br0
# ここからコンテナ側での操作
# rootでログインする
apt install dbus
halt
# コンテナ側操作はここまで
```

これで準備が整いました

# machinectlコマンド

少しmachinectlコマンドを使ってみます
例として、コンテナスタート→コンテナにログイン→自動起動の設定までやってみます

```bash
# 起動
machinectl start ubuntu
# 起動確認
machinectl
# コンテナに入りシェルを実行
machinectl shell ubuntu /bin/bash
# コンテナ内でnginxが動いていることを確認
ps -ef
# コンテナ内のシェルから抜ける
exit
# ubuntuコンテナの自動起動設定
machinectl enable ubuntu
# ホスト再起動
shutdown -r now
```

再起動後に
http://192.168.56.3/
にアクセスするとNginxのデフォルトページが表示されるかと思います

これは以下のようにホストのsystemdがubuntuコンテナを起動し、ubuntuコンテナ内のsystemdがNginxを起動しています

![bootflow.png](https://qiita-image-store.s3.amazonaws.com/0/106549/462a041a-8197-eb21-55e6-fa786d7da986.png)

ちなみにubuntuコンテナの自動起動を止めたい場合は`machinectl disable ubuntu`というコマンドで可能です


# Dockerとの比較

Dockerとの比較表を作ってみました
Dockerと機能も概念も違うため完全に同一ではありません。大まかなイメージとして捉えてくれればと思います。

| machinectl   | docker       | 説明                                                                  |
|--------------|--------------|-----------------------------------------------------------------------|
| bind         | -vオプション | docker run の-vオプションのように異なるファイルパスをつなげる機能です |
| copy-from    | cp           | コンテナ側からホスト側へコピーします                                  |
| copy-to      | cp           | ホスト側からコンテナ側へコピーします                                  |
| disable      |              | 自動起動を解除します                                                  |
| enable       |              | コンテナがホスト起動時に自動で立ち上がるようにします                  |
| export-tar   | export       | 対象のコンテナをtarに固めます。止まっている状態でもOKです             |
| image-status | inspect      | イメージの情報を表示します                                            |
| import-tar   | import       | tarからコンテナをインポートします                                     |
| kill         | stop         | デフォルトで全コンテナプロセスにSIGTERMを送信します[^1]               |
| list         | ps           | 動いているコンテナをリストします                                      |
| list-images  | images       | コンテナイメージのリストを表示します                                  |
| login        |              | ログインコンソールを表示します                                        |
| poweroff     | stop         | 綺麗にシャットダウンします(systemd互換のinitのみ動作します)           |
| pull-tar     | pull         | コンテナが置かれてるURLからダウンロードしてインポートします           |
| reboot       | restart      | コンテナを再起動させます。(initにSIGINTを送信)[^2]                    |
| remove       | rmi          | イメージを削除します                                                  |
| rename       | tag          | イメージの名前を変えます[^3]                                          |
| shell        | exec         | コンテナ内でシェルを実行します。[^4]                                  |
| show         | inspect      | 稼働中のコンテナの情報を表示します                                    |
| show-image   | inspect      | image-statusより詳細にイメージの情報を出力します                      |
| start        | run          | コンテナを起動させます                                                |
| status       | top          | 稼働中のコンテナのプロセス、ログ情報を表示します                      |
| terminate    | kill         | コンテナ内の全プロセスを強制終了します                                |


[^1]: DockerのstopはメインプロセスにSIGTERMを送信後、一定時間後にSIGKILLを送信します
[^2]: Dockerのrestartはstopしてからstartするだけです
[^3]: 実際は /var/lib/machines/ 以下にあるディレクトリをmvしているだけです
[^4]: docker exec -it コンテナ名 /bin/sh のような挙動です。コンテナ内でdbusが動いている必要があります

参考
https://www.variantweb.net/blog/systemd-machinectl-vs-docker/

---
次回: [Macとsystemd-nspawnで普通の開発環境を作るまで(3)～ファイル共有設定～](https://qiita.com/yaasita/items/5c8894af70b1fba9c0b8)