dockerのコンテナの自動起動をsystemdにて行う際の注意点について

Docker公式ロゴ1b
©2023 Docker Inc. All rights reserved

 Dockerコンテナの自動起動(ホストOS起動時にDockerコンテナを自動的に起動する)を行う場合、通常はDockerコンテナに設定する再起動ポリシー(restart policy)を利用していると思います。

 再起動ポリシーは、Dockerデーモンが起動した際の各Dockerコンテナのふるまいを定義します。これを利用することでDockerコンテナを自動的に起動させることが可能です。

 しかし、お使いのLinuxがSystemdを使ってシステムを管理するディストリビューションである場合、サーバで稼働するサービスはSystemdを使って各種管理を行うことが多いと思います。

 その場合、Dockerコンテナで提供しているサービスもSystemdで起動停止したいと思われている管理者の方がいらっしゃるかもしれません。

 Docker公式サイトで調べたところ、その方法が載っていましたので早速試してみました。

 本記事では、dockerコンテナの自動起動をsystemdで行う方法についてご紹介しております。また、試してみた際にハマったポイントを注意点としてまとめました。

※本記事では、Linux(Ubuntu 18.04)とDocker ver19.03.10を使用しております。

本記事は、systemdを使用してDockerコンテナの自動起動を行う場合の注意点に関する記事です。Docker本体の自動起動に関する色々な方法に関しましては、本サイト内の別記事「Docker(Linux版)のカテゴリ別の自動起動テクニック」をご参照ください。

テスト用コンテナの作成

 私が検証時に使用しましたテスト用のDockerコンテナについて説明します。

 使用したのはApache公式イメージです。

 まず初めに、以下のコマンドでDockerコンテナを作成します。

$ docker create --name testwebserver -p 9999:80 httpd

「testwebserver」の部分はDockerコンテナ名です。Docker環境内でユニークになる名前を指定してください。

 以下のコマンドで、Dockerコンテナが作成されていることを確認します。

$ docker ps -a | grep testwebserver
 f665bc5f5304 httpd "httpd-foreground" 23 seconds ago Created testwebserver

 念のため起動確認を行います。

$ docker start testwebserver

 ブラウザにてDockerホストの9999番にアクセスして動作確認を行います。

 確認が出来ましたら、以下のコマンドで停止しておきます。

$ docker stop testwebserver

Dockerコンテナをsystemdに登録する方法

 準備が出来ましたのでDockerコンテナをsystemdに登録します。

※以下はroot権限にて作業を行う必要があります。

 Dockerコンテナを登録する定義ファイルを/etc/systemd/systemディレクトリ内に作成します。

 ファイル名は、「<サービス名>.service」としてください。<サービス名>はDockerホスト内でユニークな名前を指定してください。

 以下では<サービス名>をwebserver1として進めます。

# vi /etc/systemd/system/webserver1.service

 ファイル内に以下の内容を記述します。

[Unit]
 Description=Web container
 Requires=docker.service
 After=docker.service

[Service]
 Restart=always
 ExecStart=/usr/bin/docker start -a testwebserver
 ExecStop=/usr/bin/docker stop -t 10 testwebserver

[Install]
 WantedBy=default.target

 [Service]タグ内の「ExecStart=」部分にDockerコンテナ起動コマンドを、「ExecStop=」部分にDockerコンテナ停止コマンドを記述します。

(注意1)
「ExecStart=」の設定値は、「systemctl start」コマンドにてサービスを起動する際に実行される内容です。「docker start」コマンドには「-a」オプションを必ず指定してください。指定しない場合は、正常にコンテナが起動しない場合があります。

(注意2)
「ExecStop=」の設定値は、「systemctl start」コマンドにてサービスを停止する際に実行される内容です。「docker stop」コマンドの「-t」オプションは、停止処理が開始してから、強制停止(プロセスのkill)が掛かるまでの時間(単位は秒、デフォルトは10秒)の指定です。コンテナ内のサービスに応じて調整してください。

 ファイルを作成しましたら、以下のコマンドにて、systemdに登録します。

# systemctl daemon-reload

 これでコンテナがsystemdに登録されました。

systemdに登録したコンテナの起動/停止確認

 systemdに登録が終わりましたら、コンテナの起動確認を行います。

 以下のコマンドでコンテナを起動します。

# systemctl start webserver1

 以下のコマンドで起動確認を行います。

# systemctl status webserver1

 正常に起動されている場合は、以下のような内容が出力されます。

● webserver1.service - Web container
   Loaded: loaded (/etc/systemd/system/webserver1.service; disabled; vendor pres
   Active: active (running) since Wed 2020-09-23 16:10:25 JST; 6s ago
 Main PID: 18849 (docker)
    Tasks: 10 (limit: 4915)
   CGroup: /system.slice/webserver1.service
           mq18849 /usr/bin/docker start -a testwebserver
 (以下略)

 上から3行目くらいのところの「active (running)」を確認します。

 何度か起動確認を行い、コンテナが再起動を繰り返していないかなど、正常に動作していることを確認してください。

 念のため、「docker ps」コマンドでも確認を行って下さい

# docker ps

 次に、以下のコマンドにてコンテナの停止を行います。

# systemctl stop webserver1

 以下のコマンドで停止確認を行います。

# systemctl status webserver1

正常に停止すると、以下のような内容が出力されます。

● webserver1.service - Web container
 Loaded: loaded (/etc/systemd/system/webserver1.service; disabled; vendor preset: disabled)
 Active: inactive (dead)
(以下略)

systemdによるコンテナの自動起動設定

 systemdによるコンテナの起動停止が確認できましたので、いよいよ自動起動の設定です。

 以下のコマンドで自動起動の設定を行います。

# systemctl enable webserver1

正常に設定されると、以下のような内容が出力されます。

Created symlink from /etc/systemd/system/default.target.wants/webserver1.service → /etc/systemd/system/webserver1.service.

 以下のコマンドで自動起動の設定になっているか確認します。

# systemctl status webserver1

 以下のような現状のサービスのステータスが表示されます。

● webserver1.service - Web container
 Loaded: loaded (/etc/systemd/system/webserver1.service; enabled; vendor preset: disabled)
 Active: inactive (dead)

 2行目の「Loaded: loaded (/etc/systemd/system/webserver1.service;」の次が「enabled;」になっていることを確認します。

 では、Dockerホストを再起動して、コンテナが自動起動されているか確認しましょう。

 Dockerホストが立ち上がりましたら、以下のコマンドでコンテナのステータスを確認しましょう。

#&nbsp;systemctl status webserver1
# docker ps

 もし、どちらか1つでも異常な状態でしたら、本記事の最初から見直してください。特にコンテナ起動時のオプションとsystemdの定義ファイルの内容は、重点的にお願いします。

 自動起動をやめる場合は、以下のコマンドを実行します。

# systemctl disable webserver1

 以下のコマンドで自動起動の設定が解除されているか確認します。

# systemctl status webserver1

 以下のような現状のサービスのステータスが表示されます。

● webserver1.service - Web container
 Loaded: loaded (/etc/systemd/system/webserver1.service; disabled; vendor preset: disabled)
 Active: inactive (dead)

 2行目の「Loaded: loaded (/etc/systemd/system/webserver1.service;」の次が「disabled;」になっていることを確認します。

systemdで自動起動設定を行った場合の注意点

 systemdで自動起動を行う場合の注意点を列挙します。

systemd登録ファイルのコンテナ起動コマンド「docker start」に「-a」を付ける

 systemdでコンテナの起動停止を行うためには、対象コンテナをsystemd管理下に置く必要があります。「-a」を付けることによって、systemdによって起動されたコンテナは、systemdによって制御が可能となります。

Dockerコンテナの起動/停止はsystemctlコマンドを使用する

 systemd管理下のコンテナの起動停止は、systemctlコマンドで行う必要があります。

 systemd管理下のコンテナをdockerコマンドにて起動停止してしまった場合は、不整合が発生し、想定外の動作をする可能性があります。

 例えば、systemdの「Restart=always」指定がある場合は、dockerコマンドでコンテナを停止しても、直ぐに起動されます。

「Restart」設定はsystemdの機能にて行う

 systemd管理下のDockerコンテナにDockerの再起動ポリシーを設定している場合、systemd管理外でコンテナの起動停止が行われる可能性があります。

 もし起動停止が行われた場合は、不整合が発生し、想定外の動作をする可能性があります。

おわりに

 最初は、軽いノリで試していたのですが、考えが甘すぎました。

 中でも、「docker start」時の「-a」オプションはハマリポイントでした。

※「-a」オプションにつきましては、本サイト内の別記事「docker startコマンドの使い方(実例付)」で紹介してます。そちらもご利用ください。

 最初は「-a」を付けずに試していまして、サクっと起動したので、お手軽だあ、と思っていたのですが、実際にマシンを再起動したり、わざとdockerコマンドで停止させたり起動させたりしている内に、どうやってもコンテナが起動できなくなってしまいました。

 「-a」を付けてからは、問題は出なくなりました。

 サーバ内のサービスをSystemdで一括管理されてる管理者の方にとっては試してみる価値があるかもしれません。システム監視ツールとの相性問題などが発生する可能性がありますので、検証は十分に行うことをオススメします。

 最後までお読みいただきありがとうございました。

コメント