Dockerエコシステム:サービス検出と分散構成ストア

前書き

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

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

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

サービス検出とグローバルにアクセス可能な構成ストア

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

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

サービスディスカバリの仕組み

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

サービスディスカバリポータルの仕組みは、各サービスがオンラインになるとディスカバリツールに登録されることです。 関連するコンポーネントが提供するサービスを利用するために必要な情報をすべて記録します。 たとえば、MySQLデータベースでは、デーモンが実行されているIPアドレスとポート、およびオプションでサインインに必要なユーザー名と資格情報を登録できます。

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

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

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

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

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

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

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

分散キー値ストアの個々のホストについて保存される情報の一部は次のとおりです。

  • ホストIPアドレス

  • ホスト自体の接続情報

  • スケジューリングの決定を対象とすることができる任意のメタデータとラベル

  • クラスター内のロール(リーダー/フォロワーモデルを使用している場合)

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

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

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

多くのサービス検出プラットフォームでは、構成可能なタイムアウトで値を設定できます。 コンポーネントは、タイムアウトを使用して値を設定し、定期的にディスカバリサービスにpingしてタイムアウトをリセットできます。 コンポーネントに障害が発生してタイムアウトに達すると、そのインスタンスの接続情報はストアから削除されます。 タイムアウトの長さは、主にアプリケーションがコンポーネントの障害にどれだけ早く応答する必要があるかによって決まります。

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

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

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

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

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

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

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

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

その質問への答えは、ストアに配置するものと、データを保護するために必要と考えるセキュリティの層の数に大きく依存します。 ほとんどすべてのサービス検出プラットフォームで、SSL / TLSを使用した接続の暗号化が可能です。 一部のサービスでは、プライバシーはそれほど重要ではない場合があり、プライベートネットワークにディスカバリサービスを配置することで満足できる場合があります。 ただし、ほとんどのアプリケーションでは、おそらく追加のセキュリティが役立ちます。

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

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

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

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

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

  • etcd:このツールは、CoreOSのメーカーによって作成され、コンテナーとホストシステム自体の両方にサービス検出とグローバルに分散された構成を提供します。 http APIを実装し、各ホストマシンでコマンドラインクライアントを使用できます。

  • consul:このサービス検出プラットフォームには、構成可能なヘルスチェック、ACL機能、HAProxy構成など、目立つようにする多くの高度な機能があります。

  • zookeeper:この例は前の2つより少し古く、いくつかの新しい機能を犠牲にして、より成熟したプラットフォームを提供します。

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

  • crypt:Cryptを使用すると、コンポーネントは公開鍵暗号化を使用して書き込む情報を保護できます。 データを読み取るためのコンポーネントには、復号化キーを与えることができます。 他のすべての関係者はデータを読み取ることができません。

  • confd:Confdは、サービス検出ポータルの変更に基づいて、任意のアプリケーションの動的な再構成を可能にすることを目的としたプロジェクトです。 システムには、関連するエンドポイントの変更を監視するツール、収集された情報に基づいて新しい構成ファイルを構築するテンプレートシステム、および影響を受けるアプリケーションをリロードする機能が含まれます。

  • vulcand:Vulcandは、コンポーネントのグループのロードバランサーとして機能します。 etcdに対応しており、ストアで検出された変更に基づいて構成を変更します。

  • marathon:marathonは主にスケジューラー(後で説明)ですが、バランスを取る必要のある利用可能なサービスに変更が加えられたときにHAProxyをリロードする基本的な機能も実装しています。

  • frontrunner:このプロジェクトはmarathonにフックして、HAProxyを更新するためのより堅牢なソリューションを提供します。

  • synapse:このプロジェクトは、トラフィックをコンポーネントにルーティングできる組み込みHAProxyインスタンスを導入します。

  • nerve:Nerveはシナプスと組み合わせて使用​​され、個々のコンポーネントインスタンスのヘルスチェックを提供します。 コンポーネントが使用できなくなった場合、神経はシナプスを更新してコンポーネントを回転させません。

結論

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

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