‫Docker Health Checkコマンド｡ 1.で追加された新機能です｡ DockerでSwarm KitとSwarm Modeが利用できるようになったのと同じ2016年半ばに登場した「12」｡
‫ツールキットの一部として追加されたものですが､
‫DockerfileやComposeファイル､ Docker Runコマンド､ Stackファイル､ Service UpdateやService Createコマンドなど､
‫さまざまなファイルで使用することができます｡
‫どこにでもあるんです｡
‫本番では､ このヘルスチェックコマンドのテストオプションに取り組むことを強くお勧めします｡
‫エクゼクティブですぐに使えそうです｡
‫まるで自分のexecコマンドを実行するように､ コンテナ内でそのコマンドを実行するのです｡
‫つまり､ ポートを公開していないシンプルなワーカーでも､
‫簡単なコマンドを実行することで良いデータを返しているかどうかを検証することができるのです｡
‫単純にコマンドを実行するだけなので､ 単純なリターンが得られるということです｡ 0 または 1 を期待する｡
‫LinuxやWindowsでは､ コマンドの終了コードがあって､ 0がいいんですね｡
‫すべて順調だったということです｡
‫0以外の値は､ ほとんどのアプリケーションでエラーになります｡
‫しかし､ Dockerでは､ そのアプリケーションが具体的に1を終了する必要があるのです｡ その方法をすぐにお見せします｡
‫Dockerのヘルスチェックには､ 3つの状態しかありません｡ スタートするところから始まります｡ スタートは､ デフォルトで､ まだヘルスチェック・コマンドを実行していない最初の30秒間です｡
‫それなら1本で済みますね｡
‫それが0を返した場合は､ 健康な状態からスタートします｡ ヘルシーなオプションに変更されます｡
‫このコマンドを実行すると､ またデフォルトで30秒ごとに実行されます｡ もし､ exit 1のような不健康な返事を受け取ることがあれば､
‫それを不健康なコンテナとしてマークするのです｡
‫リトライを含むすべての制御を行うオプションがあります｡
‫それはすぐにわかります｡
‫今までのDockerは､ アプリケーションがまだ動いていることを確認するだけでしたから､ これは今までよりもずっと良い選択肢です｡
‫そのアプリケーションがやるべきことをやっているかどうか､ 洞察することができなかったのです｡
‫これで､ Dockerコンテナ自体の中で､ それができるようになりました｡
‫しかし､ これはサードパーティの監視ソリューションの代替にはなりません｡
‫これは､ 監視ソリューションに期待されるようなグラフや時間経過によるステータス､ サードパーティツールのようなものを提供するものではありません｡
‫これは､ コンテナ自体が基本的に健全なレベルかどうかをDockerが理解することです｡
‫つまり､ Nginxの場合､ rootのインデックスファイルのlocalhostを返すかもしれません｡ 200や300のリターンは問題なく､ 終了コード0を与え､
‫健全と判断する｡
‫これは､ 超高度な......あの､ モニタリングツールではないんです｡
‫しかし､ もし404や500のエラーを返した場合は､ その時点で不健全と判断し､ それに対して何らかの対処をすることができます｡
‫このDocker healthcheckは､ GUIのどこに表示されるのでしょうか？
‫最初の場所は､ コンテナlsの中です｡
‫この新しいオプションとして認識されるだけです｡
‫真ん中にあるんです｡ ヘルスチェックが実行されている場合､
‫3つの状態のうちの1つが表示されます｡
‫少なくとも､ それが一番簡単な方法だと思います｡ そのコンテナのインスペクトに､ ヘルスチェックの履歴（過去5回分）が表示されるのがわかります｡
‫そして､ そこには基本的な経年変化が見られます｡
‫しかし､ docker runコマンドは､ 不健全なコンテナにはアクションを起こしません｡
‫healthcheck がコンテナを不健康と判断すると､ docker run は ls コマンドと inspect でそのことを示すだけで､
‫アクションを起こすわけではありません｡
‫そこで､ Swarmサービスに期待しているのです｡
‫そのため､ スタックやサービスは､ スケジューラによって､ コンテナを新しいタスクに置き換えたり､ 新しいホストで実行したりします｡
‫update コマンドでも､ healthcheck
‫を使用することで､ ちょっとしたボーナスがあります｡
‫コンテナが出てきても､ ヘルスチェックに合格しなければ､ サービスの更新は次のコンテナには行きません｡
‫あるいは､ 与えた変化をもとにアクションを起こします｡
‫コマンドラインに行く前に､ いくつかの例を見てみましょう｡
‫これは､ docker runで使っているものです｡
‫これによって､ ヘルスチェックが入っていない既存の画像を使うことができ､ 実行時にヘルスチェックを入れているのです｡
‫今回は､ Elasticsearchのイメージを使用します｡ コマンドはcURL localhost 9200で､ これは公開ポートではなく､
‫コンテナ内部でElasticsearchが動作しているポートであることがわかると思います｡
‫Elasticsearchの場合､
‫実際のヘルスURLはあります｡
‫だから､ ここでそれを利用することができる｡
‫そのコマンドの最後にfalseのついた2本のパイプがあることにお気づきでしょうか｡
‫cURLのような､ 1以外のエラーコードを送信するツールを使用している場合､
‫これはかなり一般的なことです｡
‫さっきの話､ 覚えてる？ 問題があれば1で終了させる必要があります｡ なぜなら､ Dockerが何とかしてくれるエラーコードはこれだけだからです｡
‫この場合､ シェルがそのコマンドから0以外のものが出てきたら､ 必ず偽の1終了コードを返すようにする必要があるのです｡
‫その問題を回避するためのいい方法だと思います｡
‫たまたまcURLを使うと､ cURLが他の潜在的なエラーコードを出してしまうので､ そうならないようにするためです｡
‫実際のDockerファイルでも､ 同じようにコマンドを追加すればよい｡ フォーマットが少し違うんです｡ でも､ ここにはこんなオプションがあるんですよ｡
‫間隔､ タイムアウト､ 開始期間（これは新しい）､ リトライがあります｡
‫と思うような間隔です｡ デフォルトでは､ 30秒ごとです｡
‫このヘルスチェックを実行する頻度｡ タイムアウトは､ アプリが遅い場合にエラーになり､
‫不正なコードが返されるまでの時間です｡ スタートピリオドは､ 17年の今だからこそできる新機能です｡
‫09 以降､ 継続時間の最初の 30 秒より長い待ち時間を与えるようにした｡ 以前は､
‫いつも長い時間待つだけでしたが...｡ ヘルスチェックを開始するまでのインターバル時間を指定します｡
‫でも､ Javaアプリやデータベースなど､ 起動に時間がかかるものがあるかもしれません｡
‫もしかしたら､ 5分で終わるかもしれません｡
‫そこにそのスタートピリオドを加えてもいいのでは｡ 健康診断もできますよ｡ しかし､ その時間が経過するまでは､
‫不健全なチェックでアラームが鳴ることはありません｡
‫そこで2分と設定すると､ 30秒ごとにヘルスチェックをしていても､ その2分を超えた時点で初めて不健康と判断されます｡
‫最後のretriesは､
‫このヘルスチェックを不健全と判断するまでにx回試行することを意味します｡
‫そうすることで､ もしかしたら不安定になりそうなアプリが､ これを本当に不健全なコンテナと考える前に､ 健全な状態で戻って来て､
‫自ら回復する機会を与えることができるかもしれません｡
‫Dockerfileで使う基本的なhealthcheckコマンドはHEALTHCHECKといい､
‫そこはすべて大文字です｡ PHPアプリなどのためにローカルホストの単純なcURLを実行する場合でも､
‫同じ形式が存在します｡ それができるのは､ 私たちです｡
‫このように､ Dockerfileにこれらのオプションを追加していくのですが､ コマンド自体の前にタイムアウト間隔と再試行を追加しているのがわかると思います｡
‫最初のものは基本的なコマンドで､ 実行するコマンドを指定するだけなら､ CMDを入れる必要はないことに注意してください｡
‫しかし､
‫オプションを表示したい場合､ タイムアウトなどのカスタムオプションを最初から与えたい場合は､ どれがコマンドなのかを指定する必要があるんだ｡
‫今､ これは2つの異なるラインではありません｡
‫最初の行の末尾にあるバックスラッシュに注目してください｡
‫だから､ そこを勘違いしないように｡
‫ここでは､ Nginx サーバの内部で静的なアプリケーションを動作させた場合の簡単な例を紹介します｡
‫Dockerfileから間隔とタイムアウトを設定すれば､ あとは単純にローカルホストのcURLコマンドを実行させるだけですね｡
‫200や300が返ってくれば､ それでいいと考える｡ もし､ 4や5などを返したら､ それはエラーと見なします｡
‫ここで､ 出口が1であることに気づきますが､ これはfalseと同じ意味です｡
‫ネット上の特定の例には偽りがあることを示すためにそうしたのです｡ 特定の例では､ 出口1があります｡
‫どちらも同じことをするんです｡
‫ここでは､ もう少し進んだ例をご紹介します｡
‫今回は､ Nginxと組み合わせたPHPアプリを使用しています｡
‫リソースの中に､ このPHPのサンプルへのリンクがあります｡ NginxとPHP-FPMのステータスURLを使用するNginxのカスタム設定ファイルに追加しています｡
‫これらのアプリケーションは､ それぞれ独自のステータスページとヘルスチェックのping URLのようなものを備えています｡
‫PHPやNginxを使用している場合､ それらをアプリで使用することができます｡ URLは2種類ありますが､ 同じヘルスチェックの中で両方使うことができます｡
‫この場合､ そのうちのひとつだけを使用し､ localhost/pingを投入します｡ これは実際にはPHP-FPMのステータスコマンドですが､
‫PHP-FPMの内部でこれを有効にする必要があります｡ 繰り返しになりますが､ この講義のリソースの中に､ PHP Docker
‫Good Defaultsへのリンクがあります｡
‫この例をもう少し詳しく紹介したGitHubで確認してみてください｡
‫次はPostgresの例なので､ Dockerfileでは別のURLを使うことができます｡
‫ここでは､ Postgresアプリケーションのhealthcheckコマンドで､ pg isreadyというコマンドを使用しています｡
‫さて､ アプリが違えば､ ツールも違います｡ Postgresでは､ Postgresサーバーへの接続を非常に簡単にテストするツールが内蔵されています｡
‫良いデータがあるかどうか､ データベースが正しくマウントされているかどうかは検証しません｡ 単純に､ 「このデータベースサーバーは接続を許可しているか？
‫イエスかノーか？ '
‫箱から出してできるオモシロさですね｡
‫composer/stackファイルでは以下のようになります｡
‫非常によく似ています｡
‫下のスタートピリオドが違うバージョンを要求しているのがわかると思います｡
‫1でhealthcheckコマンドが出たので｡ 12､ 実は2でも対応していた｡ このComposeファイルの1｡
‫しかし､ スタートピリオドを使うということは､ Composeファイルをバージョン3に更新する必要があるということです｡
‫4 をサポートするためです｡ なぜなら､
‫healthcheckコマンドの実行後､ 1年以上経ってから開始時期が出たからです｡
‫まずは､ 簡単な実行コマンドから始めてみましょう｡
‫ここでは､ Postgresデータベースサーバを起動する際に､ デフォルトではヘルスチェックを行わないようにします｡
‫次に､ コマンドラインで追加する手動ヘルスチェック・コマンドで再度実行し､
‫その違いを確認します｡
‫ここでは､ 最初の1枚をp1と呼ぶことにします｡ Postgresの公式イメージからデタッチして実行することにします｡
‫docker container lsを実行すると､ ここにはヘルスチェックを示すものは何もないことがわかります｡
‫もう一度同じコマンドを実行し､ 今度はp2と呼ぶと､ healthコマンドが追加されます｡
‫今回は､ 先ほどお話したpg isreadyを使って､ このPostgresサーバーで接続が可能かどうかをテストしてみます｡
‫必要なユーザはpostgresユーザであることを伝えることにします｡
‫実際にはパスワードを与える必要はないのです｡ ログインしようとはしない｡
‫検証しようとするだけです｡ Postgresのイメージを使用することにします｡
‫ここでDockerコンテナのlsを実行し､ 少しズームアウトすると､ 「Up 4 seconds health is starting」と表示されるのがわかります｡
‫'
‫これで､ lsコマンドのステータスにこの追加機能が表示されるようになりました｡ 初めてhealthcheckコマンドを実行するまで､
‫デフォルトの30秒間は起動状態を維持します｡
‫30秒以上待ったので､ ステータスがhealthyに変わっているのがわかると思います｡
‫この p2 を docker コンテナで検査すると､ その一番上に新しい健康状態オプションがあることがわかります｡
‫今回は､ まだ2回しか実行できていないのですが｡
‫接続を受け入れていることが出力されているのがわかると思います｡
‫わかりました｡ 同じデータベースに対して､ 同じテストのヘルスチェックで､ いくつかのサービス作成コマンドを実行してみましょう｡
‫このように､ サービスの起動時には3つの異なる状態があることがわかります｡
‫準備中ということは､ 通常､ 画像をダウンロードしていることになります｡ 起動しているということは､ コンテナを実行し､ 立ち上げているということです｡
‫それから､ 走っている｡
‫healthcheckコマンドを使用しない場合､ 起動と実行は非常に短時間で済みます｡ ほとんど瞬殺です｡
‫ここでは､ docker service create name p1 postgresで見てみます｡
‫イメージをダウンロードして準備が完了すると､ ヘルスチェックがないため､ すぐに起動から実行に移ることがわかります｡
‫コンテナを起動して「うん」と言う以外にすることがないのです｡
‫バイナリが動作しています｡ しかし､ 同じコマンド､
‫docker service createを実行し､ 前と同じようにp2と名付け､ 同じhealthコマンドを与えてみます｡
‫healthcheckコマンドを組み込んで､ このサービスを開始します｡
‫準備から起動に移行し､ 最初のヘルスチェックが実行されるまでの30秒間は､
‫デフォルトの起動状態で待機します｡
‫これは､ Dockerサービスがこのサービスを完全に実行中とみなす前に､ 健全な状態を期待するようになったものです｡
‫30秒が過ぎると､ 走行状態に移行します｡ そして､
‫最後の小さな検証を行い､ 安定していると判断されたら終了です｡
‫サービス､ そしてサービスのアップデートで､ 可能な限りこれらのコマンドを使用すれば､
‫健康概念というおまけがつくことは､ すでにおわかりでしょう｡