systemdのバージョンを確認する
$ systemd --version
systemd 232
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN
セットアップ
- ホストは Debian 9.5 (stretch) on SakuraVPS
- ゲストも Debian 9.5 (stretch)
- コンテナ名として
stretch
を用いる
sudo apt-get update
# systemd-nspawnとdebootstrapをインストールする
sudo apt-get install systemd-container debootstrap
# ホストのsystemd-networkdを有効化して起動する
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
# コンテナのrootfsをつくる
# コンテナにdbusがはいってないとmachinectlコマンドが使えないので、同時にいれる
sudo debootstrap --include=dbus stretch /var/lib/machines/stretch
# コンテナを起動する
sudo systemctl start systemd-nspawn@stretch.service
# ホスト起動時にコンテナを自動起動する設定
sudo systemctl enable systemd-nspawn@stretch.service
# コンテナのネットワークの初期設定を行う
sudo machinectl shell stretch /bin/systemctl enable systemd-networkd
sudo machinectl shell stretch /bin/systemctl start systemd-networkd
# コンテナのrootシェルを開く
sudo machinectl shell stretch /bin/bash
NAT(インターネット -> コンテナ)の設定
コンテナの中で動かしているサービスを外部に公開するには、ポートのマッピングが必要。
宛先NAT(DNAT, Destination NAT)というらしい。
systemd-nspawn
コマンドでコンテナを起動する場合は--port
オプションでできるが、systemd-nspawn@.service
でコンテナを自動起動する場合は、systemd.nspawnで設定するのがよい模様。
例: ゲストのTCP:80をホストのTCP:8080で公開する
/run/systemd/nspawn/stretch.nspawn
[Network]
Port=8080:80
ハマったポイントとか
- 最初Ubuntuでやろとしていたが、パケットフィルタリングの初期設定(FORWARDチェインがデフォルトでDROP)のせいでハマった
- ネットワークが疎通しない場合は
sudo iptables -F; sudo iptables -F -t nat
でいちどルールを初期化してみるとよいかも - systemd-nspawn自体は、IPMasqueradeを自動的に設定するような設定ファイルがデフォルトではいっているので、ホストとコンテナでsystemd-networkdが起動していて、かつ余計なフィルタさえなければ、ネットワーク周りは特になにも設定しなくても外部と通信できるようになっている