仮想マシン再起動時にsystemdで以ってiptablesのルールを保存・適用

OS: Ubuntu Server 18.04.1 LTS
VMware Workstation Pro 14.1.1 build-7528167

以前はifupdownでiptablesのルールを保存・適用していたけれどもnetplanの台頭によって近頃は流儀が異なるようである。netplanは2018年10月2日現在でif-up.dやif-down.dのような仕組みを持ち合わせていないからnetworkd-dispatcherで代替する手がある模様である。

ネットワークインターフェースが無効になった際に動き出すのは /usr/lib/networkd-dispatcher/off.d/ 配下に設置したスクリプトで、有効となった場合は /usr/lib/networkd-dispatcher/routable.d/ 配下のスクリプトであるという。

Netplan frequently asked questionsによる

ところがVMware上のUbuntu仮想マシンではoff.d配下のスクリプトが全然起動しなかった。スクリプトの所有権をrootにし、パーミッションも700にセットして必要条件を満たしてもどうしてもダメである。手動でネットワークインターフェースを無効にした場合は確かに実行されるけれどもどうもシャットダウンや再起動時には仮想マシンのネットワークが何故か無効にならない様子である。まるで原因がわからないからもうsystemdで以って対応した。

$ sudo vi /etc/systemd/system/iptables.service
[Unit]
Description=Save and restore iptables rules.
After=network.target
Before=shutdown.target reboot.target
Requires=network.target

[Service]
Type=simple
ExecStart=/bin/sh -c '/sbin/iptables-restore -c < /etc/iptables.conf'
ExecStop=/bin/sh -c '/sbin/iptables-save -c > /etc/iptables.conf'
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

ExecStartやExecStopの項目ではリダイレクト記号を生で記述すると特別なものとして解釈されてしまうのか実行時にはリダイレクトが無いものとして振る舞っていた。これに気が付けずずいぶん悩んだものである。あとはユニットを有効にして終いである。

$ sudo /bin/sh -c '/sbin/iptables-save -c > /etc/iptables.conf'
$ sudo systemctl enable iptables.service
$ systemctl status iptables.service
● ipt-save.service - Save and restore iptables rules.
   Loaded: loaded (/etc/systemd/system/ipt-save.service; enabled; vendor preset: enabled)
   Active: active (exited) since Tue 2018-10-02 21:51:22 JST; 29min ago
(snip)

networkd-dispatcherは思い通りにならないしsystemdはなんだかとっつき難いし偉いものに首を突っ込んでしまったという心持ちである。

参考:
Use pre-up, post-up, etc. hook scripts
clayton craft / networkd-dispatcher・GitLab
Ubuntu Manpage: networkd-dispatcher – Dispatcher service for systemd-networkd connection status changes

systemdを用いてマシン起動時にMySQLを起動するよう設定

OS: Ubuntu Server 16.04
MySQL 5.7.21

大変な権勢を誇っているsystemdで以ってMySQLの起動や停止を管理しようと息巻いてオンラインの文献を二、三斜め読みしたところでこれはえらいものに手を出してしまったぞと気付いた。マニュアルが多数あり分量も膨大でどこから手を付けていいか途方に暮れた。も少し軽薄に臨む心づもりでいたからこれには参った。とまれMySQLのドキュメントを見ているとcmakeのオプションでsystemd用のファイルをインストールするものがあるようである。

-DWITH_SYSTEMD=bool

Whether to enable installation of systemd support files. By default, this option is disabled. When enabled, systemd support files are installed, and scripts such as mysqld_safe and the System V initialization script are not installed. On platforms where systemd is not available, enabling WITH_SYSTEMD results in an error from CMake.

-DWITH_SYSTEMD=1を加えてMySQLをビルド、インストールしてみるとなるほどmysqld.serviceというファイルがインストールディレクトリに放り込まれて居る。どのような取り扱いが定石であるか判然としないけれども、手探りで設定したところなんだか希望どおりには動いている模様である。まずはMySQLの起動オプションを書き付けた。

$ sudo vi /etc/default/mysql
MYSQLD_OPTS="--basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=mysql.err --pid-file=/usr/local/mysql/data/mysql.pid"

次にユニットファイル(mysqld.service)を/etc/systemd/system/へコピーし、みずからの環境に合致するようオプションを編集した。

$ cd /usr/local/mysql
$ sudo cp mysqld.service /etc/systemd/system/
$ sudo vi /etc/systemd/system/mysqld.service
#PIDFile=/var/run/mysqld/mysqld.pid
PIDFile=/usr/local/mysql/data/mysql.pid

#ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS
ExecStart=/usr/local/mysql/bin/mysqld --daemonize $MYSQLD_OPTS

#EnvironmentFile=-/etc/sysconfig/mysql
EnvironmentFile=-/etc/default/mysql

そうしたらシステムの起動時にMySQLが起動するようsystemctl enableコマンドで執り成してやる。マシンを再起動してみるとたしかにMySQLが自動で立ち上がっているので概ね成功と言ってよかろうとおもう。

$ sudo systemctl enable mysqld.service
Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service to /etc/systemd/system/mysqld.service.

$ systemctl list-unit-files mysqld.service
UNIT FILE      STATE
mysqld.service enabled

なお手動でMySQLを起動するならこういう具合である。ステータスを確認することもできるようである。

$ sudo systemctl start mysqld
$ sudo systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/etc/systemd/system/mysqld.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-03-22 20:42:22 JST; 15s ago
(snip)
Mar 22 20:42:22 mysql-systemd-test systemd[1]: Started MySQL Server.

ユニットファイルの全貌はこういう塩梅である。

$ cat /etc/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/usr/local/mysql/data/mysql.pid
TimeoutSec=0
PermissionsStartOnly=true
ExecStartPre=/usr/local/mysql/bin/mysqld_pre_systemd
ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/usr/local/mysql/data/mysql.pid $MYSQLD_OPTS
EnvironmentFile=-/etc/default/mysql
LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false

参考:
systemd.exec
systemd – ArchWiki
systemd – Wikipedia
2.5.10 Managing MySQL Server with systemd
What is $OPTIONS in a systemd service file?