クラッシュまたは再起動後に自動的に開始するようにLinuxサービスを構成する方法–パート1:実際の例
序章
この2部構成のチュートリアルでは、再起動またはクラッシュ後に自動的に再起動するようにLinuxサービスを構成する方法を学習します。 systemd
.
パート1では、次のような一般的なLinuxサービス管理の概念について説明します。 init
デーモンとランレベル。 最後に、サービス管理のデモンストレーションを行います。 systemd
. ここで調べます targets
, wants
, requires
、 と unit
ファイル。
パート2は、実用的で一般的なものを完了するためのステップバイステップのチュートリアルを提供します systemd
仕事。 具体的には、クラッシュまたは再起動後に自動的に起動するようにMySQLデータベースサーバーを構成します。
注:systemctlを使用してsystemdサービスとユニットを制御するための非常に人気のあるチュートリアルを読むことも検討してください。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- CentOS 8を実行しているサーバーで、sudo権限を持つroot以外のユーザーが含まれます。 ファイアウォールを含め、これらすべてを設定するには、CentOS 8 を実行するDigitalOceanDropletを作成してから、初期サーバーセットアップガイドに従います。
サービス管理デーモンの紹介
Linuxサービスは、サービス管理デーモン(別名、サービス管理デーモン)による処理方法を変更することで、主に自己回復させることができます。 init
デーモン。
init
は、マシンが起動してカーネルがメモリにロードされた後、Linuxシステムで開始される最初のプロセスです。 特に、ユーザープロセスまたはシステムサービスをロードする方法、順序、および自動的に開始するかどうかを決定します。
Linuxが進化するにつれて、 init
デーモン。 もともと、LinuxはSystemVから始まりました init
、Unixで使用されたものと同じです。 それ以来、LinuxはUpstartを実装しています init
デーモン(Ubuntuによって作成された)、そして今はsystemd init
デーモン(Fedoraによって最初に実装されました)。
最近のほとんどのLinuxディストリビューションは、System Vから徐々に移行し、現在systemdを使用しています。 古いスタイル init
(使用する場合)下位互換性のためにのみ保持されます。 UNIXの変種であるFreeBSDは、BSDと呼ばれる別のSystemV実装を使用します。 init
.
systemdは、今日のLinuxディストリビューションで使用されている最新の一般的なサービスマネージャーであるため、この記事で取り上げます。 ただし、必要に応じてSystem VとUpstartについても説明し、そこからsystemdがどのように進化したかを確認します。 あなたにアイデアを与えるために:
- SystemVが最も古い
init
システム、で使用される - Debian6以前
- Ubuntu9.04以前
- CentOS5以前
- UpstartはSystemVの後に登場し、
- Ubuntu14.04を含むUbuntu9.10からUbuntu14.10
- CentOS 6
- systemd は、で使用されている最新のLinuxサービスマネージャーです。
- Debian7以降
- Ubuntu15.04以降
- CentOS7以降
を理解するには init
デーモン、runlevelと呼ばれるものから始めましょう。
ランレベル
ランレベルは、Linuxシステムの現在の状態を表します。 たとえば、ランレベルは、Linuxサーバーのシャットダウン状態、シングルユーザーモード、再起動モードなどです。 各モードは、その状態で実行できるサービスを決定します。
一部のサービスは1つ以上のランレベルで実行できますが、他のサービスでは実行できません。 ランレベルは、0〜6の値で示されます。 次のリストは、これらの各レベルの意味を示しています。
- ランレベル0:システムのシャットダウン
- ランレベル1:シングルユーザー、レスキューモード
- ランレベル2、3、4 :マルチユーザー、ネットワーキングが有効なテキストモード
- ランレベル5:マルチユーザー、ネットワーク対応、グラフィカルモード
- ランレベル6:システムの再起動
ランレベル2、3、および4は、ディストリビューションによって異なります。 たとえば、一部のLinuxディストリビューションはランレベル4を実装していませんが、他のディストリビューションは実装しています。 一部のディストリビューションでは、これら3つのレベルが明確に区別されています。 一般に、ランレベル2、3、または4は、Linuxがマルチユーザーのネットワーク対応のテキストモードで起動した状態を意味します。
サービスの自動開始を有効にすると、Linuxは実際にそのサービスをランレベルに追加します。 たとえば、System Vでは、OSは特定のランレベルで起動します。 そして、起動すると、そのランレベルに関連付けられているすべてのサービスを起動しようとします。 systemdでは、ランレベルがターゲットになり、サービスが自動開始されると、ターゲットに追加されます。 ターゲットについては、この記事の後半で説明します。
SystemVの紹介 init
デーモン
SystemVは inittab
後でファイル init
メソッドは下位互換性を維持しています。 SystemVの起動シーケンスを実行してみましょう。
- The
init
デーモンはバイナリファイル/sbin/initから作成されます - 最初のファイル
init
デーモンの読み取りは/etc/inittabです - このファイルのエントリの1つは、マシンが起動するランレベルを決定します。 たとえば、ランレベルの値が3と指定されている場合、Linuxはネットワークが有効になっているマルチユーザーのテキストモードで起動します。 (このランレベルはデフォルトのランレベルと呼ばれます)
- 次に、
init
デーモンは/etc/ inittabファイルをさらに調べて、何を読み取りますかinit
そのランレベルで実行する必要のあるスクリプト
だから、 init
デーモンは何を見つけます init
特定のランレベルで実行する必要のあるスクリプト。実際には、起動する必要のあるサービスを見つけています。 これらは init
スクリプトは、個々のサービスの起動動作を構成できる場所です。
アン init
スクリプトは、SystemVの特定のサービスを制御するものです。 init
サービスのスクリプトは、アプリケーションのベンダーによって提供されたか、Linuxディストリビューション(ネイティブサービス用)に付属しています。 独自に作成することもできます init
カスタム作成されたサービスのスクリプト。
MySQLサーバーなどのプロセスまたはサービスがSystemVで起動する場合、そのバイナリプログラムファイルをメモリにロードする必要があります。 サービスの構成方法によっては、このプログラムはバックグラウンドを継続的に実行する(そしてクライアント接続を受け入れる)場合があります。 このバイナリアプリケーションの開始、停止、または再読み込みのジョブは、サービスの init
脚本。 それはと呼ばれています init
これは、サービスを初期化するためのスクリプトです。
System Vでは、 init
スクリプトはシェルスクリプトです。 彼らはまた呼ばれます rc
(コマンドを実行)スクリプト。 スクリプトは、 /etc/init.d
ディレクトリ。 これらのスクリプトは、 /etc/rc
ディレクトリ。 以内 /etc
ディレクトリ、いくつかあります rc
ディレクトリ。それぞれの名前に番号が含まれています。 数字はさまざまなランレベルを表しています。 だから私たちは /etc/rc0.d
, /etc/rc1.d
, /etc/rc2.d
等々。
クラッシュまたは再起動後にサービスを再起動するには、通常、次のような行をに追加できます。 init
脚本:
- ms:2345:respawn:/bin/sh /usr/bin/service_name
System Vサービスをシステムの起動時に開始できるようにするには、次のコマンドを実行します。
- sudo chkconfig service_name on
無効にするには、次のコマンドを実行します。
- sudo chkconfig service_name off
ステータス(実行中または停止中)を確認するには、このコマンドを実行します
- sudo service service_name status
Upstartデーモンの紹介
ジョブとサービスをロードするシリアル化された方法がSystemVでより時間がかかり、複雑になるにつれて init
、Upstartデーモンは、OSのより高速なロード、クラッシュしたサービスの適切なクリーンアップ、およびシステムサービス間の予測可能な依存関係のために導入されました。
アップスタート init
SystemVよりも優れていた init
いくつかの方法で:
- サービスをロードおよび管理するための難解なシェルスクリプトは処理しませんでした。 代わりに、理解と変更が容易な単純な構成ファイルを使用します
- System Vのようにサービスがシリアルにロードされなかったため、システムの起動時間が短縮されました
- 柔軟なイベントシステムを使用して、さまざまな状態でのサービスの処理方法をカスタマイズしました
- Upstartには、クラッシュしたサービスがどのようにリスポーンするかを処理するためのより良い方法がありました。
- すべて同じスクリプトを指す、冗長なシンボリックリンクを多数保持する必要はありませんでした。
物事を単純にするために、UpstartはSystemVと下位互換性があります。 The /etc/init.d/rc
スクリプトは引き続き実行され、ネイティブのSystemVサービスを管理します。 その主な違いは、複数のイベントをサービスに関連付ける方法です。 このイベントベースのアーキテクチャにより、Upstartは柔軟なサービスマネージャーになることができました。 Upstartを使用すると、各イベントは、そのイベントを処理するシェルスクリプトを起動できます。 これらのイベントには次のものが含まれます。
- 起動
- 開始
- 停止
- 停止
これらのイベントの合間に、サービスは、待機、事前開始、開始、実行、事前停止、停止など、さまざまな状態になる可能性があります。 Upstartは、これらの各状態に対してもアクションを実行し、非常に柔軟なアーキテクチャを作成できます。
起動時に、Upstartは任意のSystemVを実行します init
通常のスクリプト。 その後、下を見ていきます /etc/init
ディレクトリを作成し、各サービス構成ファイルでシェルコマンドを実行します。 特に、これらのファイルはサービスの起動動作を制御していました。
ファイルの命名スタイルは service_name.conf
、およびスタンザと呼ばれるさまざまなセクションを持つプレーンテキストコンテンツがあります。 各スタンザは、サービスのさまざまな側面とその動作方法を説明します。 クラッシュまたは再起動後にサービスを自動的に開始するには、 respawn
cronサービスについて以下に示すように、サービス構成ファイルのコマンド。
...
description "regular background program processing daemon"
start on runlevel [2345]
stop on runlevel [!2345]
expect fork
**respawn**
exec cron
の紹介 systemd
デーモン
Linuxの最新版 init
デーモンはsystemdです。 実際、それは単なる init
デーモン:systemdは、最新のLinuxシステムの多くのコンポーネントを網羅するフレームワークです。
その機能の1つは、Linuxのシステムおよびサービスマネージャーとして機能することです。 この容量では、systemdは、サービスがクラッシュしたり、マシンが再起動したりした場合のサービスの動作を制御します。 ここでsystemdのsystemctlについて読むことができます。
systemdは、SystemVコマンドおよび初期化スクリプトと下位互換性があります。 つまり、SystemVサービスもsystemdで実行されます。 これが可能なのは、ほとんどのUpstartおよびSystemV管理コマンドがsystemdで機能するように変更されているためです。
systemd構成ファイル:ユニットファイル
systemdの中心にはユニットファイルがあります。 各ユニットファイルは、特定のシステムリソースを表します。 リソースに関する情報は、ユニットファイルで追跡されます。 サービスユニットファイルは、宣言型構文の単純なテキストファイル(Upstart .confファイルなど)です。 これにより、ファイルの理解と変更が容易になります。
systemdと他の2つの主な違い init
メソッドは、systemdがサービスデーモンと、デバイスのオペレーティングシステムパス、マウントポイント、ソケットなどの他のタイプのリソースの初期化を担当することです。 ユニットファイルの命名スタイルは次のとおりです。 service_name.unit_type
. したがって、次のようなファイルが表示されます dbus.service
, sshd.socket
、 また home.mount
.
ディレクトリ構造
CentOSのようなRedHatベースのシステムでは、ユニットファイルは2つの場所にあります。 主な場所は /lib/systemd/system/
. カスタム作成されたユニットファイルまたはシステム管理者によって変更された既存のユニットファイルは、 /etc/systemd/system
.
同じ名前のユニットファイルが両方の場所に存在する場合、systemdは以下のものを使用します /etc
. サービスが起動時またはその他のターゲット/ランレベルで開始できるようになっているとします。 その場合、そのサービスユニットファイルのシンボリックリンクが、の適切なディレクトリの下に作成されます。 /etc/systemd/system
. 下のユニットファイル /etc/systemd/system
実際には、同じ名前のファイルへのシンボリックリンクです。 /lib/systemd/system
.
systemd init
シーケンス:ターゲットユニット
特殊なタイプのユニットファイルは、ターゲットユニットです。
ターゲットユニットのファイル名には、.targetという接尾辞が付いています。 ターゲットユニットは、特定のリソースを表していないため、他のユニットファイルとは異なります。 むしろ、それらはいつでもシステムの状態を表します。 ターゲットユニットは、その状態の一部である必要がある複数のユニットファイルをグループ化して起動することによってこれを行います。 したがって、systemdターゲットは、同じではありませんが、SystemVランレベルと大まかに比較できます。
各ターゲットには、番号ではなく名前があります。 たとえば、 multi-user.target
それ以外の runlevel 3
また reboot.target
それ以外の runlevel 6
. Linuxサーバーが次のように起動すると、 multi-user.target
、それは本質的にサーバーを runlevel 2, 3, or 4
、ネットワークが有効になっているマルチユーザーテキストモードです。
サーバーをその段階に引き上げる方法が違いです。 System Vとは異なり、systemdはサービスを順番に起動しません。 途中で、他のサービスやリソースの存在を確認し、それらのロードの順序を決定できます。 これにより、サービスを並行してロードできるようになります。
ターゲットユニットとランレベルのもう1つの違いは、System Vでは、Linuxシステムは1つのランレベルにしか存在できないことです。 ランレベルを変更することはできますが、システムはその新しいランレベルにのみ存在します。 systemdを使用すると、ターゲットユニットを包括的にすることができます。つまり、ターゲットユニットがアクティブになると、他のターゲットユニットがその一部としてロードされるようになります。
たとえば、グラフィカルユーザーインターフェイスで起動するLinuxシステムでは、graphical.targetがアクティブ化されます。これにより、multi-user.targetも自動的にロードされ、アクティブ化されます。 System Vの用語では、ランレベル3と5を同時にアクティブ化するようなものです。
次の表は、ランレベルとターゲットを比較しています。
ランレベル(System V init) | ターゲットユニット(Systemd) |
---|---|
ランレベル0 | poweroff.target |
ランレベル1 | resuce.target |
ランレベル2、3、4 | multi-user.target |
ランレベル5 | graphics.target |
ランレベル6 | restart.target |
systemd default.target
systemd default.target
SystemVのデフォルトのランレベルと同等です。
System Vには、inittabというファイルで定義されたデフォルトのランレベルがありました。 systemdでは、そのファイルはdefault.targetに置き換えられます。 デフォルトのターゲットユニットファイルは、/ etc / systemd/systemディレクトリにあります。 これは、/ lib / systemd/systemの下にあるターゲットユニットファイルの1つへのシンボリックリンクです。
デフォルトのターゲットを変更すると、基本的にそのシンボリックリンクが再作成され、システムのランレベルが変更されます。
System Vのinittabファイルは、Linuxが実行するディレクトリも指定しました。 init
からのスクリプト:それはrcn.dディレクトリのいずれかである可能性があります。 systemdでは、デフォルトのターゲットユニットによって、起動時にロードされるリソースユニットが決まります。
ユニットがアクティブ化されると、それらはすべて並行して、またはすべて順番にアクティブ化されます。 リソースユニットのロード方法は、必要または必要な他のリソースユニットによって異なる場合があります。
systemdの依存関係:必要なものと必要なもの
systemd wantsおよびrequiresは、systemdがサービスデーモン間の依存関係に対処する方法を制御します。
前述のように、Upstartは、構成ファイルを使用してサービスの並列ロードを保証します。 System Vでは、サービスは特定のランレベルで開始できますが、別のサービスまたはリソースが使用可能になるまで待機させることもできます。 同様の方法で、systemdサービスを1つ以上のターゲットにロードするか、別のサービスまたはリソースがアクティブになるまで待機することができます。
systemdでは、別のユニットを必要とするユニットは、必要なユニットがロードされてアクティブ化されるまで起動しません。 最初のユニットがアクティブなときに必要なユニットが何らかの理由で故障した場合、最初のユニットも停止します。
これにより、システムの安定性が確保されます。 したがって、特定のディレクトリが存在する必要があるサービスは、そのディレクトリへのマウントポイントがアクティブになるまで待機させることができます。 一方、別のユニットが必要なユニットは、そのような制限を課しません。 発信者がアクティブなときに目的のユニットが停止しても停止しません。 この例としては、グラフィカルターゲットモードで表示される必須ではないサービスがあります。
実用例:systemdの起動シーケンスを理解する
systemdでのサービスの起動動作を理解するために、CentOS8.3ドロップレットを使用しています。 可能な限り.targetrabbit-trailをたどります。 systemdの起動シーケンスは、依存関係の長いチェーンに従います。
まず、次のコマンドを実行して、デフォルトのターゲットユニットファイルを一覧表示します。
- sudo ls -l /etc/systemd/system/default.target
これは、次のような出力を示しています。
Outputlrwxrwxrwx. 1 root root 37 Dec 4 17:42 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target
ご覧のとおり、デフォルトのターゲットは、実際には/ lib / systemd /system/の下にあるマルチユーザーターゲットファイルへのシンボリックリンクです。 したがって、システムはmulti-user.targetで起動することになっています。これは、SystemVinitのランレベル3に似ています。
multi-user.target.wants
次に、次のコマンドを実行して、multi-user.targetファイルが必要とするすべてのサービスを確認します。
- sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service
これにより、/ usr / lib / systemd /system/の下にある実際のユニットファイルを指すシンボリックリンクファイルのリストが表示されます。
Outputlrwxrwxrwx. 1 root root 38 Dec 4 17:38 /etc/systemd/system/multi-user.target.wants/auditd.service -> /usr/lib/systemd/system/auditd.service
lrwxrwxrwx. 1 root root 39 Dec 4 17:39 /etc/systemd/system/multi-user.target.wants/chronyd.service -> /usr/lib/systemd/system/chronyd.service
lrwxrwxrwx. 1 root root 37 Dec 4 17:38 /etc/systemd/system/multi-user.target.wants/crond.service -> /usr/lib/systemd/system/crond.service
lrwxrwxrwx. 1 root root 42 Dec 4 17:39 /etc/systemd/system/multi-user.target.wants/irqbalance.service -> /usr/lib/systemd/system/irqbalance.service
lrwxrwxrwx. 1 root root 37 Dec 4 17:41 /etc/systemd/system/multi-user.target.wants/kdump.service -> /usr/lib/systemd/system/kdump.service
...
以外 multi-user.target
、次のようなさまざまなタイプのターゲットがあります system-update.target
また basic.target
. マルチユーザーターゲットが依存しているターゲットを確認するには、次のコマンドを実行します。
- sudo systemctl show --property "Requires" multi-user.target | fmt -10
出力は次のとおりです。
OutputRequires=basic.target
basic.target
次のコマンドを実行して、basic.targetに必要なユニットがあるかどうかを確認できます。
- sudo systemctl show --property "Requires" basic.target | fmt -10
結局のところ、basic.targetにはsysinit.targetが必要です。
OutputRequires=sysinit.target
-.mount
また、いくつかのターゲットも必要です。
- sudo systemctl show --property "Wants" basic.target | fmt -10
このコマンドは次を返します。
OutputWants=slices.target
paths.target
timers.target
microcode.service
sockets.target
sysinit.target
再帰的に実行すると、sysinit.targetで他のターゲットも実行する必要があるかどうかを確認できます。
- sudo systemctl show --property "Requires" sysinit.target | fmt -10
ありません。 ただし、sysinit.targetが必要とする他のターゲットがあります。
- systemctl show --property "Wants" sysinit.target | fmt -10
次のような出力が表示されます。
OutputWants=systemd-random-seed.service
dev-mqueue.mount
rngd.service
systemd-modules-load.service
proc-sys-fs-binfmt_misc.automount
local-fs.target
sys-fs-fuse-connections.mount
systemd-sysusers.service
systemd-update-done.service
systemd-update-utmp.service
systemd-journal-flush.service
dev-hugepages.mount
dracut-shutdown.service
swap.target
systemd-udevd.service
import-state.service
sys-kernel-debug.mount
nis-domainname.service
systemd-journald.service
selinux-autorelabel-mark.service
kmod-static-nodes.service
loadmodules.service
ldconfig.service
cryptsetup.target
systemd-sysctl.service
systemd-ask-password-console.path
systemd-journal-catalog-update.service
systemd-udev-trigger.service
systemd-tmpfiles-setup.service
systemd-hwdb-update.service
sys-kernel-config.mount
systemd-binfmt.service
systemd-tmpfiles-setup-dev.service
systemd-machine-id-commit.service
systemd-firstboot.service
調べて systemd
ユニットファイル
さらに一歩進んで、sshd用のサービスユニットファイルの内部を見てみましょう。
- sudo vi /etc/systemd/system/multi-user.target.wants/sshd.service
次のようになります。
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
サービスユニットファイルがクリーンでわかりやすいことがわかります。
最初の重要な部分は、 [Unit]
セクション。 これは、network.targetとsshd-keygen.targetがロードされた後にsshdサービスをロードする必要があることを示しています。
The [Install]
セクションは、サービスがmulti-user.targetによって必要とされていることを示しています。 これは、multi-user.targetがsshdデーモンをロードすることを意味しますが、ロード中にsshdが失敗しても、シャットダウンまたはクラッシュすることはありません。
以来 multi-user.target
はデフォルトのターゲットであり、sshdデーモンは起動時に起動することになっています。 の中に [Service]
セクション、 Restart
パラメータの値は on-failure
. この設定により、sshdデーモンがクラッシュしたり、終了がクリーンでない場合に再起動できます。
結論
この記事では、System V、Upstart、およびsystemdサービス管理デーモンについて学習しました。 スタートアップスクリプトと構成ファイル、重要なパラメーター、スタートアップシーケンス、およびサービスのスタートアップ動作を制御するコマンドについて説明しました。
この記事のパート2では、これらのスキルを実際の例に適用し、systemdを使用してMySQLを構成します。 完了すると、MySQLインスタンスは再起動またはクラッシュ後に自動的に再起動します。 また、サンプルアプリケーションとしてMySQLを使用しますが、NginxやApacheWebサーバーなどの任意の数のサービスを置き換えることができます。