前書き
Initializationは、すべてのスクリプトとサービスの操作を制御するためのUnixベースのオペレーティングシステムの中心にある重要な手順です。 これは、起動とシャットダウンの重要なポイントで問題が発生する可能性があり、最適なパフォーマンスを確保することが優先されるサーバー環境では不可欠です。
本質的に、初期化は次の種類のプロセスに従います。
-
サーバーが起動します
-
initプロセスが実行されます(通常は
PID 1
として) -
事前定義された一連の起動タスクが順番にアクティブになります
初期化は、クラウドサーバーが正常に起動およびシャットダウンできるようにする責任があります。
Unixファウンデーションを備えた一部のディストリビューションは、初期化に標準のinitプロセスを利用します。 この記事では、Upstartについて説明します。これは、サーバーの運用を強化できる実用的で強力な代替手段です。
従来のinitの何が問題になっていますか?
従来の初期化は線形プロセスに従います。システムが起動すると、個々のタスクが事前定義された順序でロードされます。 特に急速に変化する状況では、これはあまり役に立ちません。 理由を理解するために、たとえば、ストレージデバイスを追加してサーバーの環境を変更したと想像してください。
初期化プロセスでは、環境の突然の変化を考慮することができません。つまり、追加のストレージを認識する前に、クラウドサーバーを再初期化する必要があります。 オンザフライ検出は必要なものですが、従来の初期化手順の機能ではありません。
線形シーケンスでの起動にも時間がかかります。これは、高速展開が不可欠なクラウドベースの環境では特に不利です。
また、システムがロードされた後のタスクのステータスについて心配するかもしれません。 残念ながら、initは、起動時または電源切断時のみシーケンスに関係します。
同期ブートシーケンスは望ましくありません。 厳格なシステムは昨日のシステムをサポートできますが、今日は動的です。
そこで、Upstartが登場します。これは、高度な機能によるこれらの問題の解決策です。
事前設定されたタスクのリストではなく、real-timeイベントに基づいて、この置換initデーモンがタスクの開始と停止を処理します。andは、システムの実行中にこれらのプロセスを監視します。「フルカバレッジ」が最適です。それを説明する方法。
この新しい非同期処理により、厳密なブートシーケンスが不要になります。 リアルタイム処理は概念化するのが面倒かもしれませんが、Upstartは最も複雑なシステムをサポートし、jobsの構造を使用してすべてをチェックすることができます。
Upstartの概要
Upstartイベントシステムは、最初から柔軟性を備えて設計されており、従来の初期化システムとは異なるさまざまな概念を利用しています。 ソリューションはデフォルトでRed Hat Enterprise Linux(RHEL)6、GoogleのChrome OS、Ubuntuにインストールされますが、最近の議論によりこれが継続するかどうか混乱が生じています。
Jobs
Upstartの世界では、ジョブは作業プロセスであり、タスクジョブ(目的あり)とサービスジョブ(バックグラウンドで実行可能)に分かれています。 また、抽象ジョブもあります。管理特権を持つユーザーによって停止されるまで、永久に実行されるプロセスです。
イベント
ただし、Eventsは、ジョブまたは別のイベントで特定のアクションをトリガーするために使用されるシグナルまたは「呼び出し」です。 イベントの一般的な形式は、プロセスの監視を指します:starting
、started
、stopping
、およびstopped
。
イベントの発行
イベントをブロードキャストするプロセスは「送信」と呼ばれます。これは通常、プロセスまたはジョブの状態が原因で発生しますが、管理者はinitctl emit <event>
コマンドを発行して手動でイベントを発行することもできます。 Upstartに関連する多数の操作をナビゲートするときに、init control
コマンドが非常に便利になることに気付くでしょう。
最初のジョブ設定を書く
UpstartはUbuntuでうまく機能することが知られているので、始める前にUbuntu 14.04 Dropletをスピンアップしてください。
準備ができたので、ジョブ構成ファイルが有効であるためには3つの基本原則に従う必要があることを理解することが重要です。
-
空にしないでください(コンテンツのないファイル)
-
構文エラーを含めることはできません
-
stanzaと呼ばれるコマンドブロックが少なくとも1つ含まれている必要があります
とりあえず基本のままにしましょう。 すぐに、/etc/init
ディレクトリにtestjob.conf
というファイルを作成します。 この場合、「init」は「初期化」の短縮バージョンとして使用されます。
.conf
ファイルの関連付けに注意してください–job configuration fileを書き込むことを示します。
このチュートリアルでは、コマンドラインテキストエディタnanoをお勧めします。 これらのコマンドの一部には、sudo
の管理者権限が必要な場合があるため、this articleをチェックして適切なユーザーを作成してください。
テストジョブの新しい構成ファイルを作成するには、次を実行します。
sudo nano /etc/init/testjob.conf
目的の概要を説明しましょう。 このジョブをwrite a message and the current timestamp to a log fileにします。
ジョブスクリプトの目的と作成者を定義するのに役立つ2つの基本的なスタンザがあります。description
とauthor
です。 これらをファイルの最初の行として記述します。
description "A test job file for experimenting with Upstart"
author "Your Name"
ここで、システムサービスとプロセスが既にロードされた後に(競合を防ぐために)このジョブを実行したいので、次の行に次のイベントを組み込みます。
start on runlevel [2345]
ランレベルとは何か疑問に思うかもしれません。 基本的に、現在のシステム構成を表す単一の値です。 [2345]
は、一般的なLinuxアクセスとネットワークを使用したすべての構成状態を指します。これは基本的なテスト例に最適です。
次に、実行コードを追加します。 この行はexec
で始まり、次のコマンドをBashシェルで実行する必要があることを示しています。
exec echo Test Job ran at `date` >> /var/log/testjob.log
このecho
コマンドは、バッククォートを使用してdate
をコマンドとして実行し、メッセージ全体をログファイルに書き込むことに注意してください。 バッククォートなしで単語date
を記述した場合、コマンドの出力の代わりに単語自体が出力されます。
このファイルを保存して閉じます。
ジョブを手動で開始することでこれが機能することを確認できますが、最初に構成ファイルの構文を確認しましょう。
init-checkconf /etc/init/testjob.conf
問題が検出された場合、このコマンドは特定の行番号と問題を示します。 ただし、テストジョブでは、次のような出力が表示されます。
File /etc/init/testjob.conf: syntax ok
このコマンドは、UpstartジョブおよびWebサーバーなどの他のバックグラウンドサービスの制御に使用できます。
基本的なコマンド構文は次のとおりです。
sudo service
この構文は、次の基本的なコントロールで機能します。
-
再起動:これは停止してからサービスを開始します
-
start:実行されていない場合、これはサービスを開始します
-
stop:実行中の場合、これはサービスを停止します
-
ステータス:これはサービスのステータスを表示します
テストジョブを手動で開始するため、コマンドは次のようになります。
sudo service testjob start
次に、次のコマンドを実行して、testjob.log
ファイルを確認します。
cat /var/log/testjob.log
このコマンドは、ファイルをシェルに読み取ります。次のような1行が表示されます。
Test Job ran at Fri Aug 1 08:43:05 BST 2014
これは、テストジョブがセットアップされて準備が整ったことを示しています。
ドロップレットを再起動してからログインし、ログファイルを再度読み取ります。
cat /var/log/testjob.log
後のタイムスタンプを表示するログの2行目に、Upstartジョブとして実行されたことを確認する必要があります。
Test Job ran at Fri Aug 1 08:44:23 BST 2014
これは、Upstartでできることのほんの一部に過ぎません。 詳細な例については後で説明しますが、ここでは、ジョブの状態とイベントの説明に移ります。
ジョブの状態とイベント
システムジョブは/etc/init/
ディレクトリにあり、ユーザージョブはユーザー自身のinitディレクトリ~/.init/
にあります。
ユーザージョブはユーザー自身のセッションで実行されるため、セッションジョブとも呼ばれます。 これらはシステム全体では実行されず、PID 1
の指定には含まれません。 テストジョブの目的で、/etc/init
を使用して、システムの起動時にロードできるようにしました。
タイプに関係なく、ジョブは構成ファイル(.conf)で定義されたalwaysであり、ファイル名は関連するサービスまたはタスクを表す必要があります。
これらの各ジョブには、start
またはstop
という目標があります。 これらの2つの目標の間には、目標に関するジョブの現在のアクションを定義する一連のタスク状態があります。 重要な状態は次のとおりです。
-
待機中:処理の初期状態
-
開始:ジョブが開始されるところ
-
事前開始:事前開始セクションがロードされる場所
-
生成:スクリプトセクションが実行されようとしている場所
-
開始後:開始後の操作が行われる場所
-
実行中:ジョブが完全に動作している場所
-
事前停止:事前停止操作が行われる場所
-
停止:ジョブが停止される場所
-
killed:ジョブが停止された場所
-
ポストストップ:ポストストップ操作が行われる場所-クリーンアップする
開始後状態の後、ジョブは実行中として定義されます。 事前停止がトリガーされるまで実行を継続し、ジョブを停止する準備が整うと、ジョブが強制終了され、定義されている場合は停止後のcleanupプロシージャが実行されます。
次のコマンドを使用して、Upstartシステムログ(/var/log/upstart/
ディレクトリにあります)の優先度をdebug
に設定することにより、ジョブが状態間でどのように遷移するかを確認できます。
sudo initctl log-priority debug
states are not events, and events are not statesであることを忘れないでください。 4つのイベント(開始、開始、停止、停止)はUpstartによって発行されますが、タスクの状態はジョブのライフタイムのステージ間の遷移を定義します。
これで、サービスジョブを記述して、最初の構成の要素を組み込んだより焦点の絞られた例に進む準備ができました。 これは、基本的なテスト構成の実行から本番用のスクリプトへの移行方法を示します。
詳細な例:サービスジョブ
導入部で簡単に説明したように、サービスジョブには、プロセスをバックグラウンドで実行できるようにするスクリプト構成ファイルが含まれます。 basic Node.js serverを最初から設定します。
Nodeに慣れていない場合、本質的には「サーバーサイドおよびネットワークアプリケーション向けのクロスプラットフォーム環境」(Wikipedia)です。
Node.js is a very lightweight package, although it isn’t installed by default on Ubuntu 14.04. まず、クラウドサーバーにインストールしてください。
sudo apt-get install nodejs
それでは、サービスの仕事を始めましょう。 nodetest.conf
という名前の新しいジョブ構成ファイルを/etc/init
に作成します。 目的を参照してファイルに名前を付けることが不可欠なので、このサービスジョブはNode.jsテスト用であることを認識できます。
sudo nano /etc/init/nodetest.conf
事前にUpstartの構成を理解することが重要であるため、Nodeアプリケーション自体については後の例で説明します。
まず最初に。 まず、ジョブの説明と作成者の行を入力して構成を定義します。
description "Service for a test node.js server"
author "Your Name"
このNode-poweredサーバーアプリケーションは、サーバーが稼働しているときに起動し、正常にシャットダウンしたときに停止するようにします。 このため、必ず両方の条件を指定してください。
start on filesystem or runlevel [2345]
stop on shutdown
以前のランレベル基準を覚えていますか? filesystem
イベントと組み合わせると、サーバーが正常に稼働しているときにジョブが確実に読み込まれます。
これらは基本ですが、今ではより複雑になっています。前述のstanzasを使用します。
これはサーバーアプリケーションであるため、ジョブ構成にロギング要素を組み込みます。 Nodeアプリケーションの開始時と停止時にログを記録するため、3つの異なるスタンザを使用して、サービスアクション(script
、pre-start script
、pre-stop script
)を分離します。
これらがよく知られていると思うなら、あなたは絶対に正しい。 事前開始と事前停止はジョブの状態ですが、スタンザでも機能します。 つまり、ジョブの状態に基づいてさまざまなコマンドを実行できます。
ただし、記述する最初のスタンザはジョブスクリプト自体です。 これにより、ノードバックグラウンドサーバーのプロセスIDが取得され、アプリケーションスクリプトが実行されます。 スタンザ内のコマンドのインデントに注意してください-これは構文的に正しい書式設定に不可欠です。
script
export HOME="/srv"
echo $$ > /var/run/nodetest.pid
exec /usr/bin/nodejs /srv/nodetest.js
end script
ノードではホームディレクトリ変数を設定する必要があるため、/srv
がスタンザの最初の行にエクスポートされるのはなぜですか。 次に、$$
を使用して、使用可能なプロセスIDを取得し、ジョブのPIDファイルを作成します。 それが準備できたら、Node.jsアプリケーションがロードされます。これは後で記述します。
次に、pre-start
とpre-stop
に焦点を当てます。これらは、単純なアプリケーションロギングに使用されます。 日付は、開始メッセージまたは停止メッセージとともに、ジョブのログファイルに追加されます。
pre-start script
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
事前停止スタンザには別の行が含まれていることに注意してください。サーバーをシャットダウンする手順の一部としてPIDファイルを削除します(事前停止の動作)。
pre-stop script
rm /var/run/nodetest.pid
echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script
これが、Upstartジョブの構成全体を並べ替えたものです。参照のために、ここでもすべてを説明します。
description "Test node.js server"
author "Your Name"
start on filesystem or runlevel [2345]
stop on shutdown
script
export HOME="/srv"
echo $$ > /var/run/nodetest.pid
exec /usr/bin/nodejs /srv/nodetest.js
end script
pre-start script
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
pre-stop script
rm /var/run/nodetest.pid
echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script
ファイルを保存して閉じます。
exec
行に記載されているように、Node.jsスクリプトはサーバーから実行されるため、目的の場所にnodetest.js
ファイルを作成します(この例では/srv/
を使用します)。
sudo nano /srv/nodetest.js
これはUpstartのチュートリアルであるため、Node.jsのコードのレビューにはあまり時間をかけませんが、このスクリプトが達成することの概要は次のとおりです。
-
NodeのHTTPモジュールを要求してロードする
-
HTTP Webサーバーを作成する
-
ヘッダーにステータス200(OK)応答を提供します
-
出力として「Hello World」を記述します
-
ポート8888でリッスンする
Nodeアプリケーションを実行するために必要なコードは次のとおりです。直接コピーして時間を節約できます。
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
Node.jsファイルを保存した後、最後に確認することは、Upstartジョブの構文が有効かどうかです。 いつものように、構成チェックコマンドを実行すると、出力として確認を受け取るはずです。
init-checkconf /etc/init/nodetest.conf
File nodetest.conf: syntax ok
ジョブの構成を取得し、構文を確認し、Node.jsコードを保存しました。すべての準備が整ったので、Dropletを再起動して、http://IP:8888または関連するドメインにアクセスします。
ウィンドウの左上隅に「Hello World」が表示されている場合、Upstartサービスジョブは機能しています。
状態ベースのログを確認するには、事前定義されたログファイルを読み取ると、タイムスタンプ付きのStarting
行が表示されます。 サーバーをシャットダウンするか、サービスジョブを手動で停止すると、ログにStopping
行が書き込まれます。これは、必要に応じて確認することもできます。
cat /var/log/nodetest.log
[Sun Aug 17 08:08:34 EDT 2014] Node Test Starting
[Sun Aug 17 08:13:03 EDT 2014] Node Test Stopping
標準の起動、停止、再起動などを実行できます。 次のような構文を持つ、このサービスのコマンド、およびその他の同様のUpstartジョブ。
sudo service nodetest restart
結論
このチュートリアルでは、Upstart Event Systemの表面のみをスクラッチします。 従来の初期化の背景を読み、オープンソースのUpstartソリューションがより強力な選択肢である理由を見つけ、独自のジョブを書き始めました。 基本を理解したので、可能性は無限です。
Upstart公式ウェブサイトのロゴ、著作権オリジナルデザイナー/ CanonicalLtd。