Linuxのサービス起動周りとDockerとの関連を理解する#1(社内勉強会)

BPS社内勉強会でのmorimorihogeさんのスライドを3回に分けてお送りします。 #1: OSとサービス、daemon、Linuxのinitソフトウェア(本記事) #2: SysVInit、ハンズオン、SysVInitの問題 #3: Systemd、ハンズオン、Dockerでの問題と対応 概要 話すこと Linuxサーバーにおけるサービス管理 サービス管理ツールとその概要 SysVInit/Upstart Systemd Monit/Supervisor Dockerに絡む話 話さないこと LinuxやDockerの操作など 最近Linuxのサービス管理が以前と変わりつつあるので、インフラ管理者はもちろん、開発者がテストサーバーを構築したりするときにも役立つ話をしてみたいと思います。 1. OSとサービス プロセスの例 Linuxシステムではさまざまなプロセスが動作しますが、「振る舞い」という観点から大きく「通常のプロセス」と「daemonプロセス」の2とおりに分けられます。 通常のプロセス 実行して仕事が終わると終了するコマンドラインから実行するプログラムやバッチがこれに該当する daemonプロセス システムに常駐して仕事を待ち受ける 仕事が終わっても終了せず、次の仕事を待ち受ける このdaemonプロセスが提供する抽象的なものが「サービス」と思っていただければよいでしょう。 morimorihoge注) イメージですが、通常の「終わると終了するプロセス」は起動時に何をどう処理するのか決まっているタスク型の処理、「daemon型のプロセス」は起動時点では決まっていない処理のためにあらかじめ待ち受けさせておくという意味でサービス型の処理を行うものだと考えると良いと思います。 「サービス」という言葉は、プロセスに比べると抽象度が高い言葉でいろいろな解釈の仕方があるかと思いますが、ここではsystemdやSysVInitで呼ばれる用語としての「サービス」として使います。 「サービス」の実体は、実際には1つのdaemonプロセスの場合もあれば、cron等で周期実行されるプログラムのconfig設定として設定されることもあります。この辺り少し紛らわしいですね。 daemonの特徴 daemon(demonではありません)の特徴は、バックグラウンドで常駐することです。daemonは、それを起動したシェルが終了しても止まらずに動き続けます(daemonプロセスは起動時にforkでシェルと別プロセスになります)。 なお通常のプログラムだと、それを起動したシェルが終了するとプロセスも終了します。 sshで時間のかかるプロセスを実行中にネットワークが切断したときにもシェルが終了するため、やはりプロセスが終了してしまいます。これを避けるには、バックグラウンド実行するとか、tmuxやbyobuなどを使うなどします。 そしてそれ以外は、daemonプロセスは通常のプロセスとまったく変わりません。daemonはroot権限で動作しているとは限りませんし、segmentation faultなどで落ちれば死ぬのも通常のプロセスと同じです。死んだプロセスはひとりでには再起動しません。 morimorihoge注) 補足すると、通常のプロセス起動(内部的にはfork())はプログラムを実行したプロセスが親プロセスとなり、親プロセスが死ぬとその子プロセスにも終了シグナルが送られて終了します。ssh作業中のプロセスが死ぬのは、SSHでクライアントがタイムアウトした際に、「起動していたシェルが終了する」->「シェルから起動していたプロセスも終了する」という連鎖が作用するためです。 それに対し、daemonプロセスはプロセスをdaemonizeする際に親プロセスが変更されます(通常はPID 1のinitプロセスの子になる)。そのため、daemon化されたプロセスは元々の親プロセスが終了しても、既に親子が切り離されているため終了シグナルが届かず、動き続けることができるわけですね。 これらの挙動は、pstreeコマンドなどを使うと見ることができますので、興味のある人は眺めてみると良いと思います。 サービスとして実行されるdaemonプロセスの多くは、特定のポートやSocketファイルなどを開き、そこに対してアクセスが発生すると何らかの動作を行います。 BSDオペレーティングシステムのマスコット「デーモン君」 なおdaemonの多くは名前の末尾がdで終わりますが、これは単なる慣習なので、nginxのようにこのとおりでないものもあります。 定番のdaemonのごく一部を以下にリストアップします。 sshd 22番ポートでsshクライアントを受け付ける apache2/httpd それぞれ80番ポートと443番ポートでブラウザからのアクセスを受け付ける mysqld 3306番ポートやsocketファイルでMySQLクライアントからのアクセスを受け付ける syslogd loggerコマンドやsocketファイル経由でログ出力のアクセスを受け付ける … Continue reading Linuxのサービス起動周りとDockerとの関連を理解する#1(社内勉強会)