Unyablog.

のにれんのブログ

systemd-nspawn に関するメモ (--as-pid2 / ネットワーク関係)

--as-pid2

指定されたものを pid 2 で実行する。pid 1 には STUBINIT が入り、pid 1 に課せられた仕事を代わりにやってくれる(シグナル処理等)。何か(実質)シングルプロセスで立ち上げたい時はコレ使ってると良さそう。

root@piyo:~# systemd-nspawn --machine hoge -n --settings=no --as-pid2 bash
Spawning container hoge on /var/lib/machines/hoge.  
Press ^] three times within 1s to kill container
root@hoge:/# ps auxwwf 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  56984  3044 ?        Ss   06:41   0:00 STUBINIT
root         2  0.0  0.1  18220  3176 ?        Ss   06:41   0:00 bash
root         3  0.0  0.1  36636  2752 ?        R+   06:41   0:00  \_ ps auxwwf

https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html#-a

ネットワーク関係

--port --network-veth --network-bridge などを使う場合、親子ともに systemd-networkd が立ち上がっているべきである。

systemd 自体は ve-hoge 等のデバイスを新たに作る。この prefix がついていると、 /lib/systemd/network/80-container-***.network が反映されて諸々の設定が行われる。

コンテナ側も同様で、 host0/lib/systemd/network/80-container-host0.network で設定がなされるので systemd-networkd が立ち上がっていないと上手く動かないことがある。*1

https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html#-n

--port

--port (ポートフォワーディング)の場合、 IPMasquerade が使われているので、 systemd-networkd は必須。

このポートフォワーディングには iptables の NAT が使われており、 # iptables -L -t nat でその様子を眺めることが出来る。DebianUbuntu の場合、古い (systemd 231-5 より前) と iptables の lib がない状態でコンパイルされてて IPMasquerade は使うことが出来ない。

$ sudo machinectl start hoge

$ sudo iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 2 packets, 200 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             tcp dpt:2000 ADDRTYPE match dst-type LOCAL to:10.0.0.2:2000

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 2 packets, 126 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  any    any     anywhere            !127.0.0.0/8          tcp dpt:2000 ADDRTYPE match dst-type LOCAL to:10.0.0.2:2000

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

ちなみに !127.0.0.0/8 となっていることからも分かる通り、親コンテナからはポートフォワーディングは見えないので注意。外部 IP などから確認する必要がある。

github.com

#787480 - build with iptables support - Debian Bug report logs

*1:DHCP を使っているので networking でも初期状態でまあまあ上手くはいく。