皆さんいかがお過ごしでしょうか。
記録的な雨が降った地域もあるようですね。
私の地方も数年前は水害がひどく、知り合いに家が流された方とかが居たので、あまり他人ごとではありません。
今年も無事に過ごせると良いのですが・・・。
さて、昨日の記事でsystemdのinitシステム
とtimer
について書きました。
今回は予告通りsystemd-nspawn
とsystemd-networkd
について取り上げたいと思います。
コンテナ・隔離技術としてのsystemd(systemd-nspawn)
このブログで何度も取り上げたのですが、Docker
のようなコンテナ型仮想化・隔離技術と呼ばれるものです。
特定のディレクトリ配下にもう一つ別のLinuxツリーを作成し、あたかも別のマシンを触っているかのように振る舞います。
隔離はcgroups
管理の延長線上とも言えなくのないのでぶっ飛んだ話ですがsystemd
の分野とも言えるのです。
現在はまだ管理ツールに乏しいのが悩みの種ですが、
- データが標準で永続化されるのでチューニングしやすい
- 稼働中のコンテナにログインして
systemctl
でサービスを自由に立ち上げられる - 仮想ブリッジを使うも使わないも自由
- フォワーディングなしでホストのポートを使用できる(これも任意)
という点で私はこちらを使用しています。
当ブログのVPS上にも、
- phpfpm (hhvmから戻した)
- mariadb
- nginx (ホスト80番_ルーティング専用)
- nginx (www.geeks-dev.com)
- nginx (demo.geeks-dev.com)
- nginx (coqoo.net)
といったコンテナが稼働し、互いに連携しています。
最近微妙にsystemd-nspawn
の使い方が変わってしまいました。
バージョンによるものなのかどうなのかはわかりませんが従来のように、
systemctl enable systemd-nspawn@MyContainer
や
machinectl enable MyContainer
では自動起動してくれないようになりました。
もしかすると次項で紹介するsystemd-networkd
やsystemd-resolved
の影響があったのは把握しているのですが、それ以外にも以前と変わっている部分が在るようです。
もう一度きちんと、確実に動く手順をまとめたいと思います。
1. コンテナを作る
まずはコンテナにするディレクトリを作成します。
mkdir ~/MyContainer
次にディレクトリにシステムをインストールします。
ここはディストリビューションごとに異なります。
いずれもroot
で行います。
Fedora
dnf -y --releasever=21 --nogpg --installroot=~/MyContainer --disablerepo='*' --enablerepo=fedora install systemd passwd dnf fedora-release vim-minimal
Debian
debootstrap --arch=amd64 unstable ~/MyContainer/
ArchLinux
pacstrap -c -d ~/MyContainer/ base
2. コンテナ管理ディレクトリにリンクを貼る
このディレクトリの場所もいつの間にか変わっています。
/var/lib/container/
から/var/lib/machines/
になっています。
ln -s ~/MyContainer /var/lib/machines/MyContainer
3. systemd-machinedを自動起動する
従来と大きく違うのはコイツです。
多分前から居たんですけど以前まではコイツ無しで動いていました。
ちなみにこのsystemd-machined
というのは単純にsystemctl enable
を使用しても動きませんでした。
なのでこんな事します。
ln -s /usr/lib/systemd/system/machines.target /etc/systemd/system/multi-user.target.wants/machines.target
4. 作ったコンテナの自動起動を設定しようとする
systemctl enable systemd-nspawn@MyContainer
設定『しようとする』と言っているのはこのままでは自動起動しないからです。
ここで自動起動にならない原因は恐らくsystemd-resolved
です。
systemd-resolved
については次項で紹介しますが、端的にはresolv.conf
をsystemd-networkd
の設定に基づいて生成してくれます。
生成される箇所は/run/systemd/resolve/resolv.conf
ですので、/etc/resolv.conf
へシンボリックリンクを貼って使用します。
んでsystemd-nspawn
は起動時にホストの/etc/resolv.conf
をコピーしようとするのですがその時に失敗するようです。
systemd-networkd
やsystemd-resolved
を使用していないのであれば、ここまででちゃんと自動起動すると思います。
もし起動しなければ次の手順を行って下さい。
5. ユニットを書き換える
systemctl edit systemd-nspawn@MyContainer
中身は以下
[Unit]
After=network.target
[Service]
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --directory=/var/lib/machines/%I --bind-ro=/run/systemd/resolve:/run/systemd/resolve
After
パラメータはnetwork-online.target
の方が良いんですけど、とりあえず上記で問題無さそうです。
もしnetwork-online.target
にしたい方は以下の手順を行って下さい。
systemctl enable systemd-networkd-wait-online
systemctl edit systemd-nspawn@MyContainer
中身を変更
[Unit]
After=network-online.target
[Service]
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --directory=/var/lib/machines/%I --bind-ro=/run/systemd/resolve:/run/systemd/resolve
[Install]
WantedBy=network-online.target
6. 今度こそ自動起動する
ユニットを書き換えたのでdaemon-reload
しましょう。
systemctl daemon-reload
これで完了です。
マシンを再起動してみて確認して下さい。
その他の使い方については手前味噌ですが、以下の記事をご覧下さい。
ネットワーク設定ツールとしてのsystem(systemd-networkd)
systemdで出来る事を把握しない内はなんでもかんでも手を伸ばそうとしているように見えるかも知れません。
あくまでsystemdはLinuxカーネルとアプリケーション間の接着剤であろうとしています。
ですからネットワークの設定などもsystemdの分野と言えます。
一度OSS脳から離れて冷静に考えてみると、これらに複数の選択肢など存在する必要はなく、きちんと動作する物が一つあれば良いわけです。
かといってsystemdはその他のツールを排除しようとしてるわけでもありません。
使うか使わないか自由に選択できるのです。
ただ、systemdのソフトウェア一式はそれぞれのコンポーネント上で設定ファイルの書式がiniファイル形式になっているので、無用なーザーの混乱を防いでくれます。
systemd-networkd
もユニットのようにiniファイル形式で記述していけます。
systemd-networkdではデバイスにネットワーク設定を適用したり仮想ネットワークデバイスを作成する事ができます。
では使い方を見て行きましょう。
準備としては以下の2つのサービス起動が必要になります。
systemctl enable {systemd-networkd.service,systemd-resolved.service}
systemctl start {systemd-networkd.service,systemd-resolved.service}
ついで以下もやっておくと後々便利でしょう。
systemctl enable systemd-networkd-wait-online
NetworkManager等を利用している場合は切って下さい。
次にresolv.confをsystemd-resolved
が吐き出す物にリンクさせます。
mv /etc/resolv.conf /etc/resolv.conf.bak #念のため退避
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
設定ファイルは/etc/systemd/network
に設置していきます。
これも種類があるのですが、実際のネットワークに接続するだけなら.network
ファイルを使えば問題ありません。
管理しやすいようにデバイス名.network
というファイルを作っていけばいいでしょう。
enp3s0
というデバイスでDHCP接続を行いたい場合は以下のようにします。
/etc/systemd/networkd/enp3s0.network
を作成。
[Match]
Name=enp3s0
[Network]
DHCP=ipv4
固定IPを使いたい場合は以下のようになります。
[Match]
Name=enp3s0
[Network]
DNS=192.168.1.1
[Address]
Address=192.168.1.2/24
[Route]
Gateway=192.168.1.1
ここでDNSの設定が出てきましたがDNSは/etc/systemd/resolved.conf
でも設定できます。
その場合は、以下のように記述します。
[Resolve]
DNS=192.168.1.1
恐らくこちらがグローバルな設定なのかと思いますが探してみても2つの方法による違いが見当たりませんでした。
systemd-networkdで仮想ネットワークデバイスを作る
systemd-networkd
はVLANやブリッジなどの仮想ネットワークデバイスも作成できます。
私は全く使いませんがやり方次第ではDockerライクなネットワーク環境を構築することが可能です。
以下は単純なブリッジの例です。
まずホスト、コンテナの両方で以下を行っておいて下さい。
ln -sf /dev/null /etc/systemd/network/80-container-host0.network
/etc/systemd/network/br0.netdev
なんかを作成して中身を書きます。
[NetDev]
Name=br0
Kind=bridge
[Match]
Name=enp3s0
[Network]
Bridge=br0
次にブリッジのプロファイルを作ります。
/etc/systemd/network/br0.network
を作成して、中身を以下のように。
[Match]
Name=br0
[Network]
DNS=192.168.1.1
Address=192.168.1.100/24
Gateway=192.168.1.1
コンテナからブリッジに接続するには、まずsystemd-nspawn
コンテナのユニットに--network-bridge=br0
を書き加えます。
前項の例だとこうなりますね。
[Unit]
After=network.target
[Service]
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-bridge=br0 --directory=/var/lib/machines/%I --bind-ro=/run/systemd/resolve:/run/systemd/resolve
それからコンテナ内に/etc/systemd/network/host0.network
を作成して、
[Match]
Name=host0
[Network]
DNS=192.168.1.1
Address=192.168.1.101/24
Gateway=192.168.1.1
とします。
完了したらコンテナ側でも
systemctl start systemd-networkd
systemctl enable systemd-networkd
を行っておいて下さい。
まとめ
ぶっちゃけsystemd-nspawn
は使いすぎて何か面白味が無いです。
systemd-networkd
なんかは一回設定するとほとんど触る事無いし。
ユニット関連の方が何か面白い気がするのは私だけ?