序章

コンテナーは、アプリケーションを大規模に設計およびデプロイしようとしているユーザーにエレガントなソリューションを提供します。 Dockerは実際のコンテナー化テクノロジーを提供しますが、他の多くのプロジェクトは、デプロイメント環境での適切なブートストラップと通信に必要なツールの開発を支援します。

多くのDocker環境が依存しているコアテクノロジーの1つは、サービス検出です。 サービス検出により、アプリケーションまたはコンポーネントは、環境とネイバーに関する情報を検出できます。 これは通常、分散型Key-Valueストアとして実装され、構成の詳細を指示するためのより一般的な場所としても機能します。 サービス検出ツールを構成すると、ランタイム構成を実際のコンテナーから分離できるため、多くの環境で同じイメージを再利用できます。

このガイドでは、クラスター化されたDocker環境内でのサービス検出の利点について説明します。 主に一般的な概念に焦点を当てますが、必要に応じてより具体的な例を示します。

サービスディスカバリとグローバルにアクセス可能な構成ストア

サービス検出の背後にある基本的な考え方は、アプリケーションの新しいインスタンスは、現在の環境の詳細をプログラムで識別できる必要があるということです。 これは、新しいインスタンスが手動の介入なしに既存のアプリケーション環境に「プラグイン」できるようにするために必要です。 サービス検出ツールは通常、現在動作しているインスタンスまたはサービスに関する情報を格納する、グローバルにアクセス可能なレジストリとして実装されます。 ほとんどの場合、この構成のフォールトトレラントでスケーラブルにするために、レジストリはインフラストラクチャで使用可能なホスト間で分散されます。

サービス検出プラットフォームの主な目的は、接続の詳細を提供してコンポーネントをリンクすることですが、より一般的には、あらゆるタイプの構成を格納するために使用できます。 多くのデプロイメントは、構成データを検出ツールに書き込むことにより、この機能を活用します。 コンテナーがこれらの詳細を検索することを認識できるように構成されている場合、コンテナーは、検出した内容に基づいて動作を変更できます。

サービスディスカバリはどのように機能しますか?

各サービス検出ツールは、コンポーネントがデータを設定または取得するために使用できるAPIを提供します。 このため、コンポーネントごとに、サービス検出アドレスをアプリケーション/コンテナー自体にハードコーディングするか、実行時にオプションとして提供する必要があります。 通常、検出サービスは、標準のhttpメソッドを使用してアクセスできるKey-Valueストアとして実装されます。

サービス検出ポータルが機能する方法は、各サービスがオンラインになると、それ自体を検出ツールに登録することです。 提供するサービスを利用するために、関連するコンポーネントが必要とする可能性のある情報を記録します。 たとえば、MySQLデータベースは、デーモンが実行されているIPアドレスとポート、およびオプションでサインインに必要なユーザー名とクレデンシャルを登録する場合があります。

そのサービスのコンシューマーがオンラインになると、事前定義されたエンドポイントで情報をサービス検出レジストリに照会できます。 次に、見つけた情報に基づいて、必要なコンポーネントと対話できます。 この良い例の1つは、ロードバランサーです。 サービス検出ポータルにクエリを実行し、それに応じて構成を調整することで、トラフィックをフィードする必要のあるすべてのバックエンドサーバーを見つけることができます。

これにより、コンテナー自体から構成の詳細が取り出されます。 これの利点の1つは、コンポーネントコンテナーがより柔軟になり、特定の構成へのバインドが少なくなることです。 もう1つの利点は、コンポーネントを関連サービスの新しいインスタンスに簡単に反応させ、動的な再構成を可能にすることです。

構成ストレージはどのように関連していますか?

グローバルに分散されたサービス検出システムの重要な利点の1つは、コンポーネントが実行時に必要になる可能性のある他のタイプの構成データを格納できることです。 これは、コンテナからより多くの構成をより優れた実行環境に抽出できることを意味します。

通常、これを最も効果的に機能させるには、構成ストアにクエリを実行することで実行時にオーバーライドできる適切なデフォルトを使用してアプリケーションを設計する必要があります。 これにより、コマンドラインフラグを使用するのと同じように構成ストアを使用できます。 違いは、グローバルにアクセス可能なストアを利用することで、追加の作業なしでコンポーネントの各インスタンスに同じオプションを提供できることです。

構成ストレージはクラスター管理にどのように役立ちますか?

Dockerデプロイメントでの分散キーバリューストアの機能の1つは、最初は明らかではないかもしれませんが、クラスターメンバーシップのストレージと管理です。 構成ストアは、管理ツールのためにホストメンバーシップを追跡するのに最適な環境です。

分散Key-Valueストアの個々のホストについて保存される可能性のある情報の一部は次のとおりです。

  • ホストIPアドレス
  • ホスト自体の接続情報
  • スケジューリングの決定の対象となる任意のメタデータとラベル
  • クラスターでの役割(リーダー/フォロワーモデルを使用している場合)

これらの詳細は、通常の状況でサービス検出プラットフォームを利用するときに考慮する必要のあるものではない可能性がありますが、管理ツールがクラスター自体に関する情報を照会または変更するための場所を提供します。

障害検出についてはどうですか?

障害検出は、さまざまな方法で実装できます。 問題は、コンポーネントに障害が発生した場合に、検出サービスが使用できなくなったことを反映するように更新されるかどうかです。 このタイプの情報は、アプリケーションまたはサービスの障害を最小限に抑えるために不可欠です。

多くのサービス検出プラットフォームでは、設定可能なタイムアウトを使用して値を設定できます。 コンポーネントはタイムアウトを使用して値を設定し、定期的に検出サービスにpingを実行してタイムアウトをリセットできます。 コンポーネントに障害が発生してタイムアウトに達すると、そのインスタンスの接続情報がストアから削除されます。 タイムアウトの長さは、主に、アプリケーションがコンポーネントの障害に応答するために必要な速度の関数です。

これは、必要最低限の「ヘルパー」コンテナを各コンポーネントに関連付けることによっても実現できます。各コンポーネントの唯一の責任は、コンポーネントの状態を定期的にチェックし、コンポーネントがダウンした場合にレジストリを更新することです。 このタイプのアーキテクチャーの懸念は、ヘルパーコンテナーがダウンし、ストア内の情報が正しくなくなる可能性があることです。 一部のシステムは、サービス検出ツールでヘルスチェックを定義できるようにすることでこれを解決します。 これにより、検出プラットフォーム自体が、登録されているコンポーネントがまだ使用可能かどうかを定期的に確認できます。

詳細が変更された場合のサービスの再構成についてはどうですか?

基本的なサービス検出モデルの重要な改善点の1つは、動的な再構成です。 通常のサービス検出では、起動時に検出情報を確認することでコンポーネントの初期構成に影響を与えることができますが、動的再構成では、構成ストア内の新しい情報に反応するようにコンポーネントを構成する必要があります。 たとえば、ロードバランサーを実装する場合、バックエンドサーバーのヘルスチェックで、プールの1つのメンバーがダウンしていることが示される場合があります。 ロードバランサーの実行中のインスタンスに通知する必要があり、これを考慮して構成を調整してリロードできる必要があります。

これは、さまざまな方法で実装できます。 負荷分散の例はこの機能の主な使用例の1つであるため、構成の変更が検出されたときにロードバランサーを再構成することに専念するプロジェクトが多数存在します。 HAProxyの構成調整は、負荷分散スペースに遍在しているため、一般的です。

特定のプロジェクトは、あらゆるタイプのソフトウェアの変更をトリガーするために使用できるという点で、より柔軟性があります。 これらのツールは定期的に検出サービスにクエリを実行し、変更が検出されたら、テンプレートシステムを使用して、検出エンドポイントで検出された値を組み込んだ構成ファイルを生成します。 新しい構成ファイルが生成された後、影響を受けるサービスが再ロードされます。

このタイプの動的再構成では、これらのメカニズムがすべてコンポーネントのコンテナー内に存在する必要があるため、ビルドプロセス中にさらに計画と構成が必要になります。 これにより、コンポーネントコンテナ自体が構成の調整を担当します。 検出サービスに書き込むために必要な値を把握し、簡単に使用できる適切なデータ構造を設計することは、このシステムに必要なもう1つの課題ですが、メリットと柔軟性はかなりのものになる可能性があります。

セキュリティはどうですか?

グローバルにアクセス可能な構成ストレージについて最初に学ぶときに多くの人が抱く懸念の1つは、当然のことながらセキュリティです。 接続情報をグローバルにアクセス可能な場所に保存しても本当に大丈夫ですか?

その質問に対する答えは、ストアに何を配置するか、およびデータを保護するために必要と思われるセキュリティの層の数によって大きく異なります。 ほとんどすべてのサービス検出プラットフォームでは、SSL/TLSを使用した接続の暗号化が可能です。 一部のサービスでは、プライバシーはそれほど重要ではない場合があり、検出サービスをプライベートネットワークに配置することで十分であることが証明される場合があります。 ただし、ほとんどのアプリケーションは、おそらく追加のセキュリティの恩恵を受けるでしょう。

この問題に対処するにはさまざまな方法があり、さまざまなプロジェクトが独自のソリューションを提供します。 プロジェクトの解決策の1つは、検出プラットフォーム自体へのオープンアクセスを引き続き許可することですが、そこに書き込まれるデータを暗号化することです。 アプリケーションコンシューマーは、ストアで見つけたデータを復号化するための関連付けられたキーを持っている必要があります。 他の当事者は、暗号化されていないデータにアクセスできなくなります。

別のアプローチとして、一部のサービス検出ツールは、キースペースを個別のゾーンに分割するためにアクセス制御リストを実装します。 次に、特定のキースペースで定義されたアクセス要件に基づいて、所有権またはエリアへのアクセスを指定できます。 これにより、特定の関係者に情報を提供すると同時に、他の関係者から情報を非公開にする簡単な方法が確立されます。 各コンポーネントは、明示的に必要な情報にのみアクセスできるように構成できます。

一般的なサービス検出ツールとは何ですか?

サービス検出ツールとグローバルに分散されたKey-Valueストアの一般的な機能のいくつかについて説明したので、これらの概念に関連するプロジェクトのいくつかに言及できます。

最も一般的なサービス検出ツールのいくつかは次のとおりです。

  • etcd :このツールは、CoreOSのメーカーによって作成され、コンテナーとホストシステム自体の両方にサービス検出とグローバルに分散された構成を提供します。 http APIを実装し、各ホストマシンで使用可能なコマンドラインクライアントを備えています。
  • consul :このサービス検出プラットフォームには、構成可能なヘルスチェック、ACL機能、HAProxy構成など、目立つようにする多くの高度な機能があります。
  • zookeeper :この例は、前の2つよりも少し古く、いくつかの新しい機能を犠牲にして、より成熟したプラットフォームを提供します。

基本的なサービス検出を拡張するその他のプロジェクトは次のとおりです。

  • crypt :Cryptを使用すると、コンポーネントは公開鍵暗号化を使用して書き込んだ情報を保護できます。 データを読み取るためのコンポーネントには、復号化キーを与えることができます。 他のすべての関係者はデータを読み取ることができなくなります。
  • confd :Confdは、サービス検出ポータルの変更に基づいて、任意のアプリケーションの動的な再構成を可能にすることを目的としたプロジェクトです。 このシステムには、関連するエンドポイントの変更を監視するツール、収集された情報に基づいて新しい構成ファイルを作成するテンプレートシステム、および影響を受けるアプリケーションをリロードする機能が含まれます。
  • vulcand :Vulcandは、コンポーネントのグループのロードバランサーとして機能します。 etcdを認識し、ストアで検出された変更に基づいて構成を変更します。
  • marathon :marathonは主にスケジューラー(後で説明)ですが、バランスを取る必要のある利用可能なサービスに変更が加えられたときにHAProxyをリロードする基本機能も実装しています。
  • frontrunner :このプロジェクトはマラソンに参加して、HAProxyを更新するためのより堅牢なソリューションを提供します。
  • synapse :このプロジェクトでは、トラフィックをコンポーネントにルーティングできる組み込みのHAProxyインスタンスを導入しています。
  • nerve :Nerveはシナプスと組み合わせて使用され、個々のコンポーネントインスタンスのヘルスチェックを提供します。 コンポーネントが使用できなくなった場合、神経はシナプスを更新してコンポーネントを回転から外します。

結論

サービス検出とグローバル構成ストアにより、Dockerコンテナーは現在の環境に適応し、既存のコンポーネントにプラグインできます。 これは、コンポーネントが環境内の変更を追跡して応答できるようにすることで、シンプルでハンズフリーのスケーラビリティと展開を提供するための必須の前提条件です。

次のガイドでは、Dockerコンテナーとホストがカスタマイズされたネットワーク構成と通信する方法について説明します。