LinuxのWebサーバーには、異常終了したときに自動で再起動する機能があります。
KUSANAGIを使って運用しているんですが、異常終了して4時間も停止していた。
設定を見ると再起動しないようになっています。
ウソ~ん。Webサーバーって24時間365日フル稼働じゃないとダメじゃん。
Systemdとは何か?
Systemdはアプリケーション管理のソフトウェアで、Redhat系Linuxでは皆さんよくご存知のもの。
最近はUbuntuなどDebian系Linuxでも採用されているので増々欠かせないものになりました。
KUSANAGIでインストールされるアプリもこの管理下に置かれています。
アプリのインストール・アップデートではdnf(yum)、再起動などではsystemctlコマンドを使いますよね?
dnf(yum)はSystemdと連携しているしsystemctlはSystemdのコマンド群のひとつです。
KUSANAGIのデータベース、Webサーバーなどは、Systemd配下でインストールされています。
ここから本題ですが、そのWebサーバー、nginxとhttpd(Apache)は、異常終了したときの自動起動設定がなされていません。
/etc/systemd/system/下を見ると、nginx, httpdのサービスファイルがないので、デフォルト設定を使ってる模様。
当然ながらWebサーバーのデフォルトは自動再起動の設定はない。
Systemdの設定ファイルに自動再起動設定を追加
まずはnginxのsystemdの設定を見てみましょう。設定ファイルはsystemctlで知ることができます。
以下のコマンド入力はすべてrootユーザーで行います。
systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since 火 2022-03-22 12:11:59 JST; 6h ago
・
省略
・
次に /usr/lib/systemd/system/nginx.service ファイルを見てみます。
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStartPre=/usr/bin/mkdir -p /var/run/ngx_pagespeed_cache
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Serviceセクションに自動再起動設定のRestartがありません。
サービスファイルの編集
nginx.serviceはサービスファイルと呼ばれるもので、Systemdで管理するサービス(アプリ)固有の設定が書かれています。
通常、サービスのインストールディレクトリにあるサービスファイル(/usr/lib/systemd/system/nginx.service)は編集して変更しません。
サービスファイルの編集は/etc/systemd/system/下で行います。
今回は、サービスファイルの変更部分だけを設定する差分ファイルを使います。次のコマンドを実行します。
systemctl edit nginx.service
このコマンドは差分ファイルが作成され、そのファイルをvim(またはvi)コマンドで開きます。
/etc
└ systemd
└ system
└ nginx.service.d <--- なかったら新規作成される。
└ override.conf <--- なかったら新規作成される。
(すでに差分ファイルがあるときはそのファイルを開く。)
vim(vi)コマンドが使えない人は、とりあえず、Escを押して ":wq" を入力、 Enter でエディタが終了します。
(この操作はvimエディタの保存して終了を行う。)
そのあと、override.conf ファイルを好みのエディタで編集して上書きしてください。
次に、override.confにnginxが異常終了したときの自動起動設定を追加しましょう。
[Service]
Restart=always
正確には "always" は異常終了だけではないんですが、自動起動する条件が一番多いので、設定値の意味が分からない人はこれが無難です。
エディタを保存して終了したら設定完了です。反映されてるか確認します。
systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/nginx.service.d
└override.conf
Active: active (running) since 火 2022-03-22 12:11:59 JST; 8h ago
・
省略
・
override.confがドロップインで追加設定されました。
etc配下にコピーを作成する方法もあるが...
nginx.serviceファイルを新しく/etc/systemd/systemに用意する方法もあります。
etc配下にあるサービスファイルは、インストールディレクトリのファイルよりも優先され、ここにファイルが置いてあるだけでインストールディレクトリのファイルは一切使われません。
サービス確認コマンドでも一目瞭然。
systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: disabled)
読み込んでるファイルがetcのものに変わってます。
サービスファイルを作成するとき、vim(またはvi)コマンドで用意してもいいですが、systemctlコマンドを使ってetc下にファイルを作成しましょう。
systemctl edit --full nginx.service
--fullオプションは/usr/lib/systemd/system/nginx.serviceを/etc/systemd/system/nginx.serviceにコピーしてvimコマンドで開きます。
ただ、サービスファイルは、ちょっとした追加や変更ぐらいしかないので差分ファイルのほうがいい。
アプリのアップデートでインストール先のサービスファイルが変更されても一切使われないのもキツいし、そもそも直接インストール先で編集すると、その内容は消える。
もちろん、差分ファイルの追加設定が、変更されたインストール先ファイルの内容の上書きになる可能性はあります。
それはアップデート後に自分で確認するしかありませんが、カスタム設定の内容が消えるよりはマシでしょう。
daemon-reloadとは何か?
Systemdのサービスファイルを編集していると、systemctl status で、このような警告を目にすることがあります。
Warning: nginx.service changed on disk. Run 'systemctl daemon-reload' to reload units.
サービスファイルの内容はSystemdがメモリ上に展開して使います。
なので、内容を変更したり、etc下のサービスファイルや差分ファイルを削除して、デフォルト(インストール先のサービスファイル)を使うように変えても反映されません。
このメッセージが出たらそれに従ってデーモンリロード(メモリへの反映)を行いましょう。
systemctl edit を使って編集したときは、エディタ終了時にデーモンリロードが実行されます。
(暗に『これを使って編集しろよ』と言っている。)
サービスファイルをローカルで編集してサーバーにアップロードして上書きしたら確実に出る警告なので、サーバー上で作業できない人はこのコマンドは必ず実行してください。
systemctl daemon-reload
ちなみに、データベースはデフォルトで自動再起動設定が入ってる。
Restart=on-abort
RestartSec=5s
KUSANAGIもこの設定を使ってるので問題ない。
"systemctl status mysql" で確認できる。
httpd(Apache)も作業は同じ。
httpdの作業は割愛します。違いはサービス名とサービスファイル名がちがうだけなので。
サービス名は "httpd"、サービスファイル名は "httpd.service" になります。
また、差分ファイルの格納ディレクトリは "httpd.service.d" になります。
systemctl status httpd
systemctl edit httpd