Linuxのサービス起動周りとDockerとの関連を理解する#2(社内勉強会)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。Systemd、ハンズオン、Dockerでの問題と対応SysVInit/Upstartの詳細SysVInitとUpstartは比較的近いので、まとめて説明します。/etc/inittabに記述されているランレベルに従って起動を進めるシンプルな設計です。以下は典型的なランレベルの一例ですが、LinuxのディストリビューションやOSの種類によって異なりますのでご注意ください(特にランレベル2〜5)。システムのリブート設定ファイルは以下を使います。startを実行します。実体はただのシェルスクリプトです。/etc/inittabランレベル定義ファイル/etc/init.d/サービススクリプト群がこの下に置かれる/etc/rcN.dランレベルごとに起動するスクリプト群(Nはランレベルを表す数値)上の/etc/init.d/以下のファイルに対するsymlinkになっている起動/停止は頭文字がSかどうかで判断するmorimorihoge注)主要ディストリビューションではserviceコマンドが提供されているので、通常は直接/etc/init.d以下のスクリプトを実行するのではなくserviceコマンドを利用するのが良いでしょう。デーモンの起動・終了にはserviceコマンドを利用しよう/etc/init.d/以下の様子morimorihoge注)伝統のSysVInitは当該ランレベルの/etc/rcN.d/S*を順番に起動する仕様のため、起動の優先順位があるサービスを使う場合のために、慣例的にS10hogedやS99piyodなどの数値2桁の名前が付けられてきました。SysVInitの起動スクリプトは直列に一つずつ実行されるため、例えば、mysqldが起動した後にunicornを起動して欲しい場合には、mysqldをS90mysqld、unicornをS99unicornなどとすることで、mysqlの後にunicornが起動するよう保証することも行われていました。SysVInit系の管理コマンドはSysVInit共通というものがなく、Linuxディストリビューションごとに実装が異なっています。Debian系chkconfigもupdate-rc.dも、/etc/init.d/及び/etc/rcN.d以下にあるファイル名を変更するだけのスクリプトなので、手動で変更するのと変わりません。6.10で確認しました。VirtualBoxなどで自分で動かして試してみましょう。sbin/initまずはsbin/initがどのinitかを確認してみましょう。--version/etc/inittab続いて/etc/inittabの中身です。表示してみれば1画面で収まる程度です。/etc/inittab画面の下の方にランレベルが記載されています。この場合通常のランレベルはここにある3に該当します。/etc/inittabは編集に失敗すると起動しなくなることもあるのでご注意ください。その場合は起動時にブートローダーでランレベルを直接指定するなどの方法で回避することになります。ついでですが、rootユーザーが/sbin/initに以下↓のようにランレベルを与えて実行するとその場でランレベルを変更できます。0を与えればシャットダウンと同じ動作です(実際にはまず使いませんが)。ここからわかるように、/sbin/initの動作は意外に素朴です。0/etc/init.d/続いて/etc/init.d/の下を見てみましょう。ここに置かれているのは個別のdaemonの起動や終了を制御するスクリプトで、中身は単なるシェルスクリプトです。その中からsshdのスクリプトを見てみましょう。$RETVAL~£sshスクリプトの中にはstartやstopやreloadなどがシェルスクリプトとして定義されています。実は他のスクリプトも、startやstop以外は割と自由に書かれていたりします。/etc/rc.d/次は/etc/rc.d/を見てみましょう。その中から、rc3.d/ディレクトリの下を見てみます。rc3.d/ディレクトリの下には、Kと数字で始まるスクリプトと、Sと数字で始まるスクリプトがあります。起動しないスクリプト(実際にはなくても同じだが、変更時renameだけすれば良いように配置されている)そして、スクリプトはxxの数字の順(注↓)に起動されます。非常に単純なつくりであることがわかります。この数値を変更すれば起動の順序を変えられるわけです。/etc/rcN.d/S*した順と思って良いです。そのため、もし同じ数字のスクリプトがある場合にはアルファベット順になります。chkconfigCentOSのSysVInitにはchkconfigというコマンドがあります。chkconfigだけを実行すると、rc*.d/のランレベル(ここでは1から6)ごとにサービスのオンオフ状態が表示されます。iptablesと実行するとrc*.d/の下にあるiptablesスクリプトへのsymlinkが削除されます(スクリプトそのものはこのコマンドでは削除しません)。iptablesとすればsymlinkが作成されます。morimorihoge注)chkconfigコマンドで設定及び閲覧できる情報は、あくまで起動時(ランレベル変更時)の設定です。startする必要があることに注意しましょう。以上のようにSysVInitは驚くほどシンプルなつくりです。今でも必要になることが多々ありますので、やはり知っておくのがよいでしょう。自分で何かサービス(daemon)を追加するなら、/etc/init.d/の下にある他の起動スクリプトを真似て、start/stop/restartオプションぐらいは取れるように書いておけばだいたい間に合うでしょう。SysVInit系の問題SysVInitは上から順に1つずつ直列に起動する、素朴とも言えるシンプルなつくりなので、比較的わかりやすい代わりに非効率です。具体的には、起動するスクリプト群の中に起動に時間のかかるものがあると、それに引きずられてシステム全体の起動時間が長くなってしまいます。sshdはたいてい起動順の後ろの方にあるので、Linuxシステムを再起動するとsshdが起動するまでなかなかログインできないなんてこともあります。「LANケーブルが挿さっていないとIPアドレスが取れないので起動が終わらない」などというトラブルもだいたいSysVInitです(手前のdhclient(DHCPでIPを取得する)がタイムアウトするまで次の処理に進まないあるある)Upstartはイベント実行をサポートすることでその部分が改良されていて、指定のサービスを並列起動できます。SysVInitの/etc/init.d/の下に記載するのは単なるシェルスクリプトなので、サービスごとにstartスクリプトやstopスクリプトを書くのに手間がかかります(ある程度の雛形はありますが)。依存関係を指定して起動するしくみもサポートされないので、先ほどのS*ファイルの数字を自力で変更して起動順を制御するなどしなければなりません。morimorihoge注)実際にはRedHat系のchkconfigには/etc/init.dのスクリプトに以下の形式の「コメント」を書くことで、起動順序の数字についてはそれを見てくれます。コメントである点にご注意。IT技術の処方箋:起動スクリプトの順番SysVInitやUpstartには「モニタリング機能がない」のも問題です。このため、monitやsupervisorなどを用いて別途監視体制を構築しないと、エラーで止まったdaemonは自動起動されません。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。