[Arch Linux] systemd-nspawnで軽量コンテナを建てよう！

# はじめに
Systemdには軽量コンテナ(というよりはすごいchroot)を建てる機能がなぜか備わっています。
Dockerをわざわざ入れるまでもないような場面で活躍してくれるかもしれません。
それでは早速Arch Linuxに導入してみましょう。

# Arch Linuxのコンテナを作る
Arch LinuxなのでArch Linuxのコンテナを作るのが一番手っ取り早いです。試していきましょう。

## 依存関係の解決
冒頭に示したとおり実体としてはすごいchrootなので、Linux一式をどこかに準備する必要があります。
Archはpacstrapというすてきなものがあるので、これを使えるようにしておいてください。

```bash
$ sudo pacman -S arch-install-scripts
```

## chroot環境の構築
では早速chroot環境を作っていきます。適当にコンテナ用のディレクトリを用意して、その中に入れてしまいます。
Linuxカーネルはホスト側と共有するのでインストールする必要はありません。
`linux は IgnorePkg/IgnoreGroup です。それでもインストールしますか？`と聞かれますが、`n`と入力してエンターを押してください。
この時点で何か特別にインストールしたいソフトウェアがあれば、ついでに指定してもかまいません。

```bash
$ mkdir arch_container
$ sudo pacstrap -i -c -d arch_container base --ignore linux
```

## コンテナの起動
これでコンテナは完成です。起動しましょう。デフォルトユーザーはrootです。パスワードなしでログインできます。
なお-bオプションはコンテナの起動、-Dオプションはコンテナのrootディレクトリ、-nオプションはホストとコンテナを繋ぐプライベートネットワークを設定するという意味になっています。

```bash
$ sudo systemd-nspawn -b -D arch_container -n
```

## ネットワーク接続
コンテナの中から外に向かってネットワークを繋ぐためには、systemd-networkdを利用するのが簡単です。
コンテナ内でサービスを有効にして、resolv.confのシンボリックを張ればつながるようになります。
ただし、ホスト側でもsystemd-networkdが有効になっている必要があります。注意してください。

```shell-session
# systemctl enable --now systemd-networkd systemd-resolved
# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
```

## コンテナの終了
コンテナを終了するときは、コンテナ側で`poweroff`コマンドを実行してください。

# Ubuntuのコンテナを建てる
Ubuntuも15.04以降からはsystemdが採用されているので、コンテナを建てることができます。

## 依存関係の解決
Ubuntuを入れてくれるpacstrap的な物(debootstrap)を用意する必要があります。AURにあるので、yaourtで入れましょう。

```bash
$ yaourt -S debootstrap ubuntu-keyring
```

## chroot環境の構築
Archのときと同じ要領でdebootstrapを動かして最低限の環境を作ります。とりあえず16.04で作ってみます。

```bash
$ mkdir ubuntu_container
$ sudo debootstrap xenial ubuntu_container http://ftp.jaist.ac.jp/pub/Linux/ubuntu/
```

## rootパスワードの設定
どうやら空のパスワーでは許してくれないみたいですので、事前に設定します。
普通にchrootして設定してあげてください。

```shell-session
# sudo chroot ubuntu_container
# passwd root
# exit
```

## コンテナの起動
これはArchのときと同じです。再掲します。

```bash
$ sudo systemd-nspawn -b -D ubuntu_container -n
```

# Debianのコンテナを建てる
Ubuntuとほぼ一緒です。debian用のkeyringを入れて、コードネームをいじるだけです。今回はjessie(Debian 8)で。
rootパスワードの設定もお忘れ無く。

```bash
$ yaourt -S debian-archive-keyring
$ mkdir debian_container
$ sudo debootstrap jessie debian_container http://ftp.jaist.ac.jp/pub/Linux/debian/
```

# Fedoraのコンテナを建てる
ディストリが変わると入れ方が全く変わってしまいます。順番に紹介していきます。

## 依存関係の解決
とりあえずdnf入れましょう。
依存関係がめちゃめちゃ多いので頑張ってインストールしてください。

```bash
$ yaourt -S dnf
```

## dnfの設定
Fedora用リポジトリを追加しましょう。Fedora 24のサーバー版を使います。

```bash
$ sudo mkdir -p /etc/yum/repos.d
$ sudo vim /etc/yum/repos.d/fedora.repo
```

fedora.repoは以下の通りに記述してください。

```ini
[fedora]
name=fedora
baseurl=http://ftp.jaist.ac.jp/pub/Linux/Fedora/releases/24/Server/x86_64/os/
enabled=1
```

リポジトリを認識させます。

```bash
$ sudo dnf repolist
```

## chroot環境の構築
導入したdnfを使って環境を整えます。

```bash
$ mkdir fedora_container
$ sudo dnf groupinstall core --nogpgcheck --installroot=$HOME/fedora_container
```

## コンテナの起動
Ubuntu等と同様、rootのパスワードを設定してから起動してください。

# CentOSのコンテナを建てる
Fedoraの設定を一度避けてから、ほぼ同様に進めていけばOKです。

```bash
$ sudo mv /etc/yum/repos.d/fedora.repo /etc/yum/repos.d/fedora.repo.disabled
$ sudo vim /etc/yum/repos.d/centos.repo
```

centos.repoは以下の通りに記述してください。

```ini
[centos]
name=centos
baseurl=http://ftp.jaist.ac.jp/pub/Linux/CentOS/7.2.1511/os/x86_64/
enabled=1
```

リポジトリを読み込ませてから、インストールします。dnfでCentOSを入れるっていうのも変な話ですけれども。

```bash
$ sudo dnf repolist
$ mkdir centos_container
$ sudo dnf groupinstall base --nogpgcheck --installroot=$HOME/centos_container
```

終わったらrootのパスワードを設定してから起動してください。

# おわりに
Arch Linux上のsystemd-nspawnでいろいろなディストリを起動してみる試みは、意外にもうまくいきました。
このほかにも頑張るとopenSUSEやGentooまで入れられるらしいです。

いずれにせよAURに支えられているので、Systemdが採用されていてもArch Linux以外のディストリではここまで多くのディストリを動かすことは難しいかもしれません。Arch Linuxをお使いの方は、ぜひ挑戦してみましょう！