さやノート

Kaggler grandmasterを目指して

Systemdについてちゃんとまとめてみる

はじめに

いつも仕事でCentOSのサーバ立ち上げて、データベースとかアプライアンスとか入れて動かしたいとき、 たとえばそれがPostgreSQLだったら

systemctl enable postgresql
systemctl start postgresql

ってするし、Dockerデーモンなら

systemctl enable docker
systemctl start docker

ってする。 この「systemctl」ってコマンド、何も考えずにこれまで使ってきたが、 ちゃんと調べる機会が出てきたので、ここでちゃんとまとめておくことにする。

本題

デーモンとサービス

OSで走るプロセスには、大きくわけて

  • 自分で何らかのコマンドを打つことで起動するプロセスと、

  • OSが立ち上がっている間ずっと起動しているプロセス

がある。 前者は、たとえば、

python hello.py
./start.sh
make install

が該当する。ユーザーが起動するので、ユーザープロセスとか言われる。 psコマンドを実行すると、実行されているプロセスが確認できる。

後者は、OS起動時にシステムによって立ち上げられ、バックグランドで動くプロセスで、これをデーモンと呼ぶ。 よく知られているものだとpostgresqlmysqlなどのデータベース、httpdやnginxなどのリバースプロキシ、その他jenkinsやgithubとかのアプライアンスなどが該当する。

systemd

systemdは、OSが起動されたときに、これらデーモンたちを立ち上げ、プロセス管理をするプロセスである。 systemctlというコマンドは、このsystemdにアクセスして、デーモンの起動・停止、監視などを行っている。

systemctl enable postgresql.service # PostgreSQLサーバを有効化
systemctl restart docker # Dockerデーモンを再起動
systemctl stop nginx # Nginxを停止
systemctl status sshd # SSHデーモンの状態確認

ユニットファイル

 では、Systemdは、デーモンプロセスの立ち上げを要求されたとき、実際はどんなことをしているのだろう。 それは、/etc/systemd/system/以下にある「ユニットファイル」というファイルに記載されている。

たとえば、Postgresのユニットファイルの中身はこうだ。

引用元: https://www.postgresql.jp/document/11/html/server-start.html

[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)

[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0

(後略)

ユニットファイルの中身はWindows Configファイル(.ini)ライクな書き方で、 実際に実行されるコマンドというのは[Service]セクションの中のExecStartの部分だ。

ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data

つまり、SystemdはOS起動時に/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/dataというコマンドを実行していることになる。 ちなみに、その上にUser=postgresとある通り、このコマンドはpostgresユーザとして実行されている。

他にも、このユニットの前に起動されている必要のあるデーモンを指定するAfterや、デーモン専用の環境変数を指定するEnvironmentなどがある。 このあたりの話は、下記に詳しい。

access.redhat.com

また、systemctl list-unit-filesで、ユニットファイルの一覧を表示できる。

まとめ

今回は、systemdというLinuxにおいて実は重要な役割を果たしていたものについてまとめてみた。 今となってはサービスを公開するにはDockerやKubernetesを使って、コンテナやPodの単位でスケールしたり監視するのが主流となっているが、購入したアプライアンスなどをインストールするとき、物によってはこうしたsystemdの使用を強制されることがある。 そこで何かトラブルがあった際に対応できないと困るので、ちゃんと調べておくのは大事だ。