先日、増田の記事を読みました。

Docker盲信してる皆様へ
dockerやめてどうしたか?

systemd-nspawn を全く知らない自分に腹が立ったので、使ってみました。

ホスト OS を Arch Linux にして試す

何も知識がないので、ググってヒットしたこちらから開始。
[Arch Linux] systemd-nspawnで軽量コンテナを建てよう! - Qiita

ホストの Arch Linux は Vagrant で用意しました。Arch Linux は初めて
使ったし、名前も知らなかったというレベルです。

$ vagrant init terrywang/archlinux

あとは記事のとおりに さまざまなディストリのコンテナを試していきました。

Arch Linux
→ 一番簡単だったが、インターネットに繋げられず

Debian
→ debootstrap が 404 でインストールできず断念

CentOS
→ dnf のインストールで挫折。

と、ひととおり試してこの記事はむしろ Arch Linux スゲー記事というこ
とに気づきました・・・!

ホスト OS を CentOS 7 にして試す

初心(?)に返って、仕事でも使っている CentOS 7 で再挑戦。

こちらの記事は簡単でした。Vagrant で出来たし、何もせずともコンテナ
からインターネットを参照できました。
Cent OS7でsystemd-nrespownで軽量コンテナを作成する

macOS の方はたぶん、この通りにやると systemd-nspawn を体験できると
思います。

$ vagrant init bento/centos-7.3
$ vagrant up
$ vagrant ssh

# コンテナを /srv/mycontainer に作成
$ sudo yum -y --releasever=7 --nogpg --installroot=/srv/mycontainer --disablerepo='*' \
--enablerepo=base install systemd passwd yum vim-minimal

# コンテナの root ユーザにパスワードを設定する。次のデーモンモードでログインするため
$ sudo systemd-nspawn -D /srv/mycontainer
-bash-4.2# passwd
(snip)
-bash-4.2# exit

# コンテナをデーモンモードで起動(CUI な Linux のログインに遷移)
$ sudo systemd-nspawn -bD /srv/mycontainer

CentOS 7 上で CentOS 7 のコンテナを起動した様子です。一瞬で起動で
きますし、ログインすればコンテナということを忘れてしまいそうです。

systemd-nspawn on CentOS 7

yum の –installroot オプションは初めて使いました。

インストールしているパッケージは systemd, passwd, yum, vim-minimal
だけ。このなかの systemd がすごい()のだと思いました。

今回は Linux kernel をインストールしないため、コンテナはホストの
Linux kernel を使うそうです。

インストール先である /srv/mycontainer の様子です。うん、見覚えがあるw

[vagrant@localhost ~]$ ls -alF /srv/mycontainer
total 24
dr-xr-xr-x. 17 root root 4096 Apr 29 05:07 ./
drwxr-xr-x.  3 root root   24 Apr 29 05:29 ../
lrwxrwxrwx.  1 root root    7 Apr 29 05:07 bin -> usr/bin/
dr-xr-xr-x.  2 root root    6 Nov  5 15:38 boot/
drwxr-xr-x.  2 root root   17 Apr 29 05:07 dev/
drwxr-xr-x. 47 root root 4096 Apr 29 05:08 etc/
drwxr-xr-x.  2 root root    6 Nov  5 15:38 home/
lrwxrwxrwx.  1 root root    7 Apr 29 05:07 lib -> usr/lib/
lrwxrwxrwx.  1 root root    9 Apr 29 05:07 lib64 -> usr/lib64/
drwxr-xr-x.  2 root root    6 Nov  5 15:38 media/
drwxr-xr-x.  2 root root    6 Nov  5 15:38 mnt/
drwxr-xr-x.  2 root root    6 Nov  5 15:38 opt/
dr-xr-xr-x.  2 root root    6 Nov  5 15:38 proc/
dr-xr-x---.  2 root root   26 Apr 29 05:08 root/
drwxr-xr-x. 11 root root 4096 Apr 29 05:07 run/
lrwxrwxrwx.  1 root root    8 Apr 29 05:07 sbin -> usr/sbin/
drwxr-xr-x.  2 root root    6 Nov  5 15:38 srv/
dr-xr-xr-x.  2 root root    6 Nov  5 15:38 sys/
drwxrwxrwt.  7 root root   88 Apr 29 05:07 tmp/
drwxr-xr-x. 13 root root 4096 Apr 29 05:07 usr/
drwxr-xr-x. 18 root root 4096 Apr 29 05:08 var/

“$ curl http://example.com ” とかで、コンテナからインターネットを参
照できることも確認できました。

コンテナを停止したい時は、コンテナログイン中に poweroff や
“shutdown -h now” コマンドを実行します。

あと、記事のとおり、コンテナをホスト側の systemd のサービスとして
起動することも出来ました。

$ sudo sh -c "printf '[Service]\nExecStart=/usr/bin/systemd-nspawn -bD /srv/mycontainer\n' > /etc/systemd/system/mycontainer.service"
$ cat /etc/systemd/system/mycontainer.service
[Service]
ExecStart=/usr/bin/systemd-nspawn -bD /srv/mycontainer

$ sudo systemctl daemon-reload

$ systemctl status mycontainer
● mycontainer.service
   Loaded: loaded (/etc/systemd/system/mycontainer.service; static; vendor preset: disabled)
   Active: inactive (dead)

$ sudo systemctl start mycontainer

$ systemctl status mycontainer
● mycontainer.service
   Loaded: loaded (/etc/systemd/system/mycontainer.service; static; vendor preset: disabled)
   Active: active (running) since Sat 2017-04-29 05:23:38 UTC; 1s ago
 Main PID: 11551 (systemd-nspawn)
   CGroup: /system.slice/mycontainer.service
           └─11551 /usr/bin/systemd-nspawn -bD /srv/mycontainer

感想

・ホストとコンテナが同一 OS なら簡単そう
・ファイルシステムはそのまんまホスト上にあるので、いろいろ気楽。
増田が Ansible でセットアップしたのも頷ける
・コンテナはホストの Linux Kernel を使うことも出来るしか出来ない~~。選択肢があるのは良い~~
・ネットワークまわりはまだ良くわからない
・Dockerfile が配布されていないケースで、社内サーバとかに使うのは良いかも
・どのように Production に載せるかは全く想像がついていない
・Production が Docker でないのであれば、開発環境を systemd-nspawn
にするのはありかもしれない。ただし、要 Linux

追記(2017-04-30):
コンテナはホストの Linux Kernel しか使えない そうです。訂正しました。