分散からマイクロサービスまでのアーキテクチャの解読: Kubernetes マイクロサービス プラットフォームの詳細な調査

分散からマイクロサービスまでのアーキテクチャの解読: Kubernetes マイクロサービス プラットフォームの詳細な調査

Kubernetesマイクロサービスプラットフォームを詳しく見る

Kubernetesの概念と機能

アーキテクトは一般的に次のようなビジョンを持っています。システムには ServiceA、ServiceB、ServiceC という 3 つのサービスがあります。 ServiceA は 3 つのインスタンスをデプロイする必要があり、ServiceB と ServiceC はそれぞれ 5 つのインスタンスをデプロイする必要があります。彼らは、上記 13 個のインスタンスの分散展開を自動的に完了し、継続的に監視するプラットフォーム (またはツール) が存在することを期待しています。サーバーのダウンが検出されたり、サービス インスタンスに障害が発生した場合、プラットフォームは自己修復が可能であり、どの時点でも実行されているサービス インスタンスの数が予想される数を満たすことが保証されます。このように、チームはインフラストラクチャや運用保守の監視を気にすることなく、サービス開発そのものに集中することができます。

Kubernetes 以前は、上記のビジョンを実現すると公に主張するプラットフォームはありませんでした。 Kubernetes は、サービスという概念を真に最優先事項にまで高めた業界初のプラットフォームです。 Kubernetes の世界では、すべての概念とコンポーネントはサービスを中心に展開されます。この画期的な設計により、Kubernetes は長年にわたって私たちを悩ませてきた分散システムの多くの問題を真に解決できるようになり、チームはビジネス ニーズとビジネス関連のコード自体に集中する時間を増やすことができ、ソフトウェア チーム全体の作業効率と入出力比率が大幅に向上します。

Kubernetes のサービスは、実際にはマイクロサービス アーキテクチャにおけるマイクロサービスの概念であり、次のような明らかな特徴があります。

  • 各サービスには固定の仮想 IP アドレス (クラスター IP) が割り当てられます。
  • 各サービスは、TCP/UDP モードで 1 つ以上のポート (サービス ポート) でサービスを提供します。
  • クライアントがサービスにアクセスすると、リモート TCP/UDP サービスにアクセスするのと同じになります。クラスター IP との接続を確立するだけでよく、ターゲット ポートは特定のサービス ポートです。

サービスに IP アドレスが割り当てられているので、IP アドレスの変更を避けるために DNS ドメイン名を使用するのが自然です。 Kubernetes の DNS コンポーネントは、各サービスに対してドメイン名と IP のマッピング テーブルを自動的に作成します。ドメイン名はサービス名、IP は対応するクラスター IP です。また、Kubernetes の各 Pod (Docker のコンテナに類似) には Kubernetes DNS サーバーとして DNS サーバーが設定されます。このようにして、マイクロサービス アーキテクチャにおけるサービス検出の基本的な問題が巧みに解決されます。クライアントが呼び出す複雑なサービス検出 API を必要としないだけでなく、TCP/IP モードで通信するすべての分散システムを Kubernetes プラットフォームに簡単に移行することもできます。この設計だけを見ても、Kubernetes は他の製品よりもはるかに優れています。

各マイクロサービスの背後には、サービスを提供する複数のプロセス インスタンスがあることがわかっています。 Kubernetes プラットフォームでは、これらのプロセス インスタンスは Pod にカプセル化されます。ポッドは基本的に Docker コンテナと同等です。わずかな違いは、ポッドは実際には密接にバンドルされ、「一緒に存在し、一緒に死ぬ」Docker コンテナのグループであるということです。このコンテナ グループは同じネットワーク スタックとファイル システムを共有し、相互に分離はなく、プロセス間で直接通信できます。最も典型的な例は、4 つの Docker コンテナを含む Kubenetes Sky DNS Pod です。

では、Kubernetes のサービスとポッドはどのように対応するのでしょうか?どのポッドがサービスに対して特定のサービスを提供しているかをどうやって知ることができますか?次の図は答え「ラベリング」を示しています。

各ポッドには 1 つ以上の異なるラベルを付けることができ、各サービスには、どのラベルを持つどのオブジェクトを選択するかを決定する「ラベル セレクター」があります。次の YAML 形式のコンテンツは、ku8-redis-master というサービスを定義します。ラベル セレクターは「app: ku8-redis-master」であり、ラベル「app= ku8-redis-master」を持つすべての Pod がそれを提供することを示します。

  1. APIバージョン: v1
  2. 種類: サービス
  3. メタデータ:
  4. 名前: ku8-redis-masterspec:
  5. ポート:
  6. - ポート: 6379セレクター:
  7. アプリ: ku8-redis-master

以下は、ラベル属性の内容がサービスのラベルセレクタの内容と一致する Pod ku8-redis-master の定義です。

  1. apiversion: v1種類: ポッド
  2. メタデータ:
  3. 名前: ku8-redis-masterlabels:
  4. アプリ: ku8-redis-master
  5. 仕様:
  6. コンテナ:
  7. 名前: serverimage: redisports:
  8. -コンテナポート: 6379
  9. 再起動ポリシー: なし

サービスを提供するために、サービスに N 個の Pod インスタンスが常に必要であり、Pod インスタンスの 1 つに障害が発生した場合、すぐにそれを検出して新しい Pod インスタンスを自動的に生成し、空きを埋める必要がある場合は、どうすればよいでしょうか。答えは、Deployment/RC を使用することです。これは、特定のラベルを持つ Pod が Kubernetes クラスター内に複数のレプリカ インスタンスを作成する必要があることを Kubernetes に伝えます。 Deployment/RC の定義には、次の 2 つの部分が含まれます。

●対象Podのレプリカ数。

●対象のPodを作成するためのテンプレート。

次の例では、RC を定義します。目標は、クラスター内に常に 2 つの Pod が存在し、そのラベルが「app:ku8-redis-slave」であり、対応するコンテナー イメージが redis slave であることを確認することです。これら 2 つの Pod と ku8-redis-master は、Redis マスター スレーブ クラスター (マスター 1 つとスレーブ 2 つ) を形成します。

  1. APIバージョン:v1
  2. 種類: レプリケーションコントローラメタデータ:
  3. 名前: ku8-redis-slave仕様:
  4. レプリカ: 2テンプレート:
  5. メタデータ:
  6. ラベル:
  7. アプリ: ku8-redis-slavespec:
  8. コンテナ:
  9. 名前: サーバー
  10. イメージ: devopsbq/redis-slave
  11. 環境:
  12. 名前: マスターアドレス
  13. 値: ku8-redis-masterports:
  14. -コンテナポート: 6379

この時点で、上記の YAML ファイルは、1 つのマスターと 2 つのスレーブを持つ Redis クラスターを作成します。このクラスターでは、Redis マスターは、次の図に示すように、他のポッドまたはサービスからアクセスできるマイクロサービスとして定義されます。

上の図では、ku8-reids-slave コンテナに環境変数 MASTER_ADDR があることに注意してください。これはRedisマスターのアドレスです。ここでは、「ku8-redis-master」が入力されています。これは、Redis マスター サービスの名前です。前述のとおり、サービスの名前は DNS ドメイン名であるため、Redis スレーブ コンテナーはこの DNS を介して Redis マスター サービスと通信し、Redis マスター スレーブ同期機能を実現できます。

Kubernetes のコア概念は、サービス、ポッド、RC/デプロイメントです。これら 3 つのコア概念を中心に、Kubernetes はこれまでで最も強力なコンテナ テクノロジーに基づくマイクロサービス アーキテクチャ プラットフォームを実現しました。例えば、上記の Redis クラスターで、マスター 1 台とスレーブ 3 台でクラスターを形成したい場合、Redis スレーブを制御する ReplicationController 内のレプリカを 3 に変更するか、kubectrl scale コマンドライン関数を使用して容量を拡張するだけで済みます。コマンドは以下のとおりです。サービスの水平展開が非常に便利になったことがわかりました。

  1. kubectl スケール --replicas= 3 rc/ku8-redis-slave

さらに、Kubernetes は、水平自動拡張の高度な機能である HPA (Horizo​​ntal Pod Autoscaling) も実装しており、Pod のパフォーマンス測定パラメータ (CPU 使用率とカスタム メトリック) に基づいて、RC/Deployment によって管理される Pod を自動的にスケーリングします。たとえば、上記の Redis スレーブ クラスターに対応する Pod が外部に対してクエリ サービスも提供していると仮定すると、Pod の CPU 使用率はサービス中に変化し続けます。これらのポッドの平均 CPU 使用率が 80% を超えると、CPU 使用率が 80% を下回るか、レプリカが最大 5 個に達するまで、ポッドは自動的に拡張されます。リクエストの圧力が減少すると、Pod レプリカの数は 1 に減ります。この目標は、次の HPA コマンドを使用して達成できます。

  1. kubectl オートスケール rc ku8-redis-slave --min= 1 --max= 5 --cpu-percent= 80

Kubernetes は、マイクロサービスの水平拡張機能を簡単に実装できるだけでなく、シンプルなコマンドだけでタスクを迅速に完了できる、シンプルで強力なマイクロサービス ローリング アップデート機能も提供します。たとえば、上記の Redis Slave サービスのイメージ バージョンを devopsbq/redis-slave から leader/redis-slave にアップグレードする場合は、次のコマンドを実行するだけです。

  1. kubectl ローリングアップデート ku8-redis-slave --image=leader/redis-slave

ローリングアップグレードの原理を下図に示します。ローリング アップグレード プロセス中に、Kubernetes は新しい RC を作成します。この新しい RC は新しい Pod イメージを使用します。その後、Kubernetes は定期的に古い RC のレプリカの数を 1 つ減らし、その結果、古いバージョンの Pod コピーの数も減ります。すると、新しい RC のレプリカの数が 1 つ増えるので、新しいバージョンの Pod コピーが追加されます。アップグレード プロセス中、すべてのコピーが新しいバージョンになり、アップグレードが完了するまで、Pod コピーの数は基本的に変更されません。

Kubernetesの構成と原則

分散システムとして、Kubernetes クラスター自体も従来のマスター スレーブ アーキテクチャを採用しています。下の図に示すように、クラスターにはマスター ノードがあり、その上に API Sever、ControllerManager、Scheduler という 3 つの主要な制御プログラムがデプロイされています。 Etcd プロセスは、Kubernetes によって管理されるリソース オブジェクト (サービス、ポッド、RC/デプロイメントなど) などを永続的に保存するためにもデプロイされます。

クラスター内の他のノードはノード ノードと呼ばれ、ワーカーです。これらはすべてマスターノードによって主導され、それぞれのノードに割り当てられたポッドのコピーを管理することを主な責任としています。次の図は、Kubernetes のさまざまなプロセス間の相互作用をより明確に示しています。

上図からわかるように、中心的なプロセスは API サーバーです。他のすべてのプロセスはこれと直接対話しますが、他のプロセス間で直接対話することはありません。では、APl サーバーの役割は何でしょうか?これは実際には Kubernetes のデータ ゲートウェイであり、Kubernetes に入るすべてのデータはこのゲートウェイを介して Etcd データベースに保存され、Eted で変更されたデータは API サーバーを介して他の関連する Kubernetes プロセスにリアルタイムで送信されます。 API サーバーは、REST モードで外部インターフェースを提供します。これらのインターフェースは基本的に次の 2 つのカテゴリに分類されます。

  • すべてのリソース オブジェクトの CRUD API: リソース オブジェクトは Etcd に保存され、Pod、サービス、RC での操作などのクエリ インターフェイスを提供します。
  • リソース オブジェクトの監視 API: クライアントはこの API を使用して、サービスに関連する Pod インスタンスが正常に作成されたときや、Pod のステータスが変更されたときなど、リソースの変更に関する通知をタイムリーに取得します。 Watch API は主に Kubernetes での効率的な自動制御ロジックに使用されます。

上図の他の Kubernetes プロセスの主な機能は次のとおりです。

  • コントローラー マネージャー: RC/デプロイメントの自動制御、HPA の自動水平拡張の制御、定期的なディスク クリーンアップなど、すべての自動制御事項を担当します。
  • スケジューラ: Pod のスケジューリング アルゴリズムを担当します。新しいポッドが作成されると、スケジューラはアルゴリズムに基づいて最適なノードを見つけます。このプロセスは Pod バインディングとも呼ばれます。
  • Kubelet: このノード上の Pod インスタンスの作成、監視、再起動、削除、ステータス更新、パフォーマンス収集、およびマスターノードへの Pod およびローカルノードの情報の定期的なレポートを担当します。 Pod インスタンスは最終的に Docker コンテナとして反映されるため、Kubelet も Docker と対話することになります。
  • kube-proxy: サービスのロードバランサーであり、サービス クラスター IP と対応する Pod インスタンス間の NAT 転送ルールを確立する役割を担います。これは Linux iptables を通じて実現されます。

各 Kubernetes プロセスの機能を理解した後、RC の YAML 定義から複数の Pod とコンテナへの最終的なデプロイまで、舞台裏で何が起こるかを見てみましょう。この複雑なプロセスを明確に説明するために、ここでは概略図を示します。

まず、kubectrl create コマンドを使用して RC (リソース オブジェクト) を作成すると、kubectrl は Create RC REST インターフェイスを介してデータを API サーバーに送信し、API サーバーはデータを永続ストレージ用に Etcd に書き込みます。同時に、コントローラ マネージャーはすべての RC を監視します。 RC が Etcd に書き込まれると、コントローラー マネージャーに通知されます。 RC の定義を読み取り、RC で制御されている Pod のレプリカの実際の数と期待値を比較し、対応するアクションを実行します。この時点で、コントローラー マネージャーはクラスター内に対応する Pod インスタンスが存在しないことを検出し、RC 内の Pod テンプレート定義に基づいて Pod を作成し、API サーバーを介して Etcd に保存します。同様に、スケジューラ プロセスはすべての Pod を監視します。システムによって新しい Pod が生成されたことが検出されると、スケジューリング ロジックの実行が開始され、Pod の新しいホーム (ノード) が配置されます。すべてがうまくいけば、Pod はノードにスケジュールされ、つまりノードにバインドされます。次に、スケジューラ プロセスはこの情報と Pod ステータスを Etcd に更新します。最後に、ターゲット Node 上の Kubelet は、スケジュールされている新しい Pod をリッスンし、コンテナ イメージをプルして、Pod 内の定義に従って対応するコンテナを作成します。コンテナが正常に作成されると、Kubelet プロセスは Pod のステータスを実行中に更新し、API サーバーを通じて Etcd に更新します。このポッドに対応するサービスがある場合、各ノード上の Kube プロキシ プロセスは、すべてのサービスとこれらのサービスに対応するポッド インスタンスの変更を監視します。変更が見つかると、ノード上の iptables で対応する NAT 転送ルールが追加または削除され、最終的にサービスのインテリジェントな負荷分散機能が実現されます。これらはすべて、手動による介入なしに自動的に実行されます。

では、ノードがダウンするとどうなるのでしょうか?ノードが一定期間ダウンした場合、このノードにはこれらのポッドのステータスを定期的に報告する Kubelet プロセスがないため、このノード上のすべてのポッドのインスタンスは失敗したと判断されます。この時点で、コントローラー マネージャーはこれらの Pod を削除し、新しい Pod インスタンスを生成します。これらのポッドは他のノード上に作成されるようにスケジュールされ、システムは自動的に回復します。

このセクションは、次の図に示すように、Kube-proxy の進化についての説明で終わります。

Kube-proxy は元々、HAProxy に似たプロキシ サーバーであり、ソフトウェア ベースの負荷分散機能を実装し、クライアントによって開始されたリクエストをバックエンドの Pod にプロキシします。これは、Kubernetes サービスのロードバランサーとして理解できます。 Kube-proxy の元々の実装メカニズムは、iptables ルールを操作して、クラスター IP にアクセスするトラフィックを NAT 経由でローカル Kube-proxy にリダイレクトすることです。このプロセスでは、カーネル状態からユーザー状態へのネットワーク パケットの複数の複製が行われるため、効率的ではありません。 Kube-proxy の後のバージョンでは実装方法が変更されました。 iptables ルールを生成する場合、Kube-proxy を介して転送するのではなく、ターゲット Pod アドレスに NAT が直接使用されます。したがって、より効率的かつ高速になります。この方法はクライアント負荷分散方法よりも効率が若干劣りますが、プログラミングが簡単で、特定の通信プロトコルとは関係がないため、適用範囲が広くなります。この時点で、Kubernetes Service は iptables メカニズムに基づいてルーティングおよび負荷分散メカニズムを実装していると想定できます。今後、Kube-proxy は実際の「プロキシ」ではなく、ルーティング ルールを構成するためのツールのような「プロキシ」になります。

iptables に基づくルーティングおよび負荷分散メカニズムは、通常のプロキシよりもはるかに優れたパフォーマンスを発揮しますが、各サービスが一定数の iptables ルールを生成するため、固有の欠陥もあります。サービスの数が多くなると、iptables ルールの数が急増し、iptables の転送効率と Linux カーネルの安定性に一定の影響を及ぼします。そのため、多くの人が iptables の代わりに IPVS (IP 仮想サーバー) を使用しようとしています。バージョン 1.8 以降、Kubernetes は IPVS の Kube-proxy サポートを追加し、バージョン 1.11 で GA に正式に組み込まれました。 iptables とは異なり、IPVS 自体は Linux 公式標準で TCP/UDP サービスのロード バランサ ソリューションとして位置付けられているため、サービス ルーティングとロード バランシングを実装するために iptables を置き換えるのに非常に適しています。

さらに、Kube-proxy を置き換えるメカニズムもいくつかあります。たとえば、Service Mesh の SideCar は Kube-proxy の機能を完全に置き換えます。サービスが HTTP インターフェースに基づいている場合は、Ingress、Nginx など、さらに多くのオプションがあります。

KubernetesベースのPaaSプラットフォーム

PaaS は実際には重量級の製品ですが、多言語サポートと厳格な開発モデルによって制限されており、あまり成功していません。しかし、コンテナ技術やクラウドコンピューティングの最近の発展により、再び人々の注目を集めています。これは、コンテナ テクノロジによってアプリケーションのパッケージ化、展開、自動化の問題が完全に解決されたためです。コンテナ技術をベースに再設計・実装されたPaaSプラットフォームは、プラットフォームの技術的内容が向上しただけでなく、使いにくさ、複雑さ、自動化レベルの低さなど、従来のPaaSプラットフォームの欠点も補っています。

OpenShift は、2011 年に RedHat によってリリースされた PaaS クラウド コンピューティング プラットフォームです。Kubernetes がリリースされる前に、OpenShift は 2 つのバージョン (v1 と v2) に進化していました。しかし、Kubernetes のリリース後、OpenShift の 3 番目のバージョンである v3 では、独自のコンテナ エンジンとコンテナ オーケストレーション モジュールが廃止され、Kubernetes が完全に採用されました。

Kubernetesには以下の機能があります。

  • Pod (コンテナ) を使用すると、開発者は 1 つ以上のコンテナを「アトミック ユニット」としてデプロイできます。
  • 固定クラスター IP と組み込み DNS という独自の設計コンセプトを備えたサービス検出メカニズムにより、さまざまなサービスを簡単に相互にリンクできます。
  • RC を使用すると、懸念される Pod レプリカのインスタンス数が常に期待どおりになることを保証できます。
  • 異なるホスト上の Pod が相互に通信できるようにする非常に強力なネットワーク モデルです。
  • ステートフル サービスとステートレス サービスの両方をサポートし、永続ストレージをコンテナーにオーケストレーションしてステートフル サービスをサポートできます。
  • シンプルで使いやすいオーケストレーション モデルにより、ユーザーは複雑なアプリケーションを簡単にオーケストレーションできます。

国内外の多くの企業がPaaSプラットフォームの中核としてKubernetesを採用しており、このセクションではKubernetesをベースにした強力なPaaSプラットフォームを設計および実装する方法について説明します。

PaaS プラットフォームには、次の主要な機能が必要です。

  • マルチテナント サポート: ここでのテナントは、開発者またはアプリケーション自体になります。
  • アプリケーションの完全なライフサイクル管理: アプリケーションの定義、展開、アップグレード、廃止のサポートなど。
  • シングル サインオン サービス、ロールベースのユーザー権限サービス、アプリケーション構成サービス、ログ サービスなどの完全な基本サービス機能を備えています。同時に、PaaS プラットフォームは多くの一般的なミドルウェアを統合し、アプリケーションの呼び出しを容易にします。これらの一般的なミドルウェアには、メッセージ キュー、分散ファイル システム、キャッシュ ミドルウェアなどが含まれます。
  • 多言語サポート: 優れた PaaS プラットフォームは、Java、Node.js、PHP、Python、C++ など、複数の一般的な開発言語をサポートできます。

次に、Kubernetes をベースに設計・実装された PaaS プラットフォームが、上記の主要な機能をどのようにサポートしているかを見てみましょう。

マルチテナントを実装する方法

Kubernetes は、Namespace 機能を通じてマルチテナントをサポートします。

複数の異なる名前空間リソース オブジェクトを作成できます。各テナントには名前空間があります。異なる名前空間で作成された Pod、Service、RC などのリソース オブジェクトは別の名前空間では表示できないため、論理的なマルチテナント分離機能が形成されます。ただし、単純な名前空間の分離では、異なる名前空間でのネットワークの分離を防ぐことはできません。別の名前空間内の Pod の IP アドレスがわかっている場合でも、次の図に示すようにアクセスを開始できます。

複数テナントのネットワーク分離の問題に対処するために、Kubernetes にはネットワーク ポリシー機能が追加されました。単純にネットワーク ファイアウォールと比較します。ネットワーク ポリシー リソース オブジェクトを定義することで、名前空間 (テナント) の下の Pod にアクセスできる名前空間を制御できます。次の図に示すように、tenant2 と tenant3 という 2 つの名前空間があり、それぞれにいくつかの Pod があるとします。

次のネットワーク分離目標を達成する必要がある場合: tenant3 の role:db ラベルを持つ Pod には、tenant3 (この名前空間内) の role:frontend ラベルを持つ Pod、または tenant2 の任意の Pod のみがアクセスできます。次の図に示すように、ネットワーク ポリシー リソース オブジェクトを定義し、kubectrl ツールを使用して Kubernetes クラスターに公開して有効にすることができます。

Kubernetes ネットワーク ポリシーを有効にするには、特定の CNI ネットワーク プラグインが必要であることに注意してください。現在、次の CNI プラグインがネットワーク ポリシーをサポートしています。

  • Calico: 3 層ルーティングに基づくコンテナ ネットワーク ソリューション。
  • Weave Net: メッセージのカプセル化に基づく 2 層コンテナ ソリューション。
  • Romana: Calico に似たコンテナ ネットワーク ソリューション。

ネットワーク ポリシーはまだ初期段階にあり、サービスのアクセス ポリシーをどのように定義するかなど、研究して解決する必要がある問題がまだ多くあります。サービス アクセス ポリシーが Pod アクセス ポリシーと競合する場合、どうすれば解決できますか?さらに、外部サービスへのアクセスポリシーはどのように定義すればよいでしょうか?つまり、コンテナ分野では、コンピューティング仮想化やストレージ仮想化と比較すると、ネットワーク仮想化の多くの技術はまだ始まったばかりです。

Kubernetes の名前空間は、異なるテナントのプログラムを論理的に分離しますが、複数のテナントのプログラムが同じ物理マシン (ノード) にスケジュールされる可能性があります。異なるテナントのアプリケーションを異なるノードにスケジュールして物理的な分離を実現する場合は、クラスターのパーティション分割によってこれを実現できます。具体的なアプローチとしては、まず下の図に示すように、クラスター全体をテナントごとに異なるパーティションに分割し、各パーティション内のすべてのノードに同じラベルを付けます。たとえば、テナント a (tanenta) のラベルは、partition=tenant であり、テナント b (tanentb) のラベルは、partition=tenantb です。 Pod をスケジュールするときに、nodeSelector 属性を使用してターゲット ノードのラベルを指定できます。たとえば、次の記述は、Pod をテナント a のパーティション ノードにスケジュールする必要があることを示しています。

  1. ノードセレクタ:
  2. パーティション: テナント

Kubernetes のパーティションとテナントにはさまざまな設計があります。上記のような1パーティション1テナントの設計は典型的な設計です。入居者もVIP顧客と一般顧客に分けられます。各 VIP 顧客には個別のリソース パーティションがありますが、通常の顧客は N 個のグループで同じパーティションのリソースを共有できます。

PaaSプラットフォームのドメインモデル設計

マイクロサービス アーキテクチャのアプリケーションは通常、複数のマイクロサービスで構成され、Kubernetes は通常、複数の独立したアプリケーションをデプロイすることがわかっています。したがって、Kubernetes を使用してマイクロサービス アプリケーションをモデル化する場合は、PaaS プラットフォームのドメイン モデルでアプリケーション ドメイン オブジェクトを設計する必要があります。アプリケーションには複数のマイクロサービスが含まれており、次の図に示すように、リリース (デプロイ) されると最終的に対応する Pod、Deployment、および Service オブジェクトが生成されます。

以下は、より詳細なドメイン モデル図です。 Kubernetes のノードと名前空間はそれぞれ K8sNode と TanentNS としてモデル化され、パーティションは ResPartition オブジェクトとしてモデル化されます。各パーティションには、1 ~ N 個の TanentNS、つまり 1 つ以上のテナント (Tanent) を含めることができます。各テナントには、テナントのアプリケーション (アプリケーション) を定義および管理するためのいくつかのユーザー アカウント (ユーザー) が含まれています。権限を分離するために、ユーザー グループ (User Group) 方式を使用し、標準のロール ベースの権限モデルを追加できます。

上図の Service ドメイン オブジェクトは Kubernetes サービスではなく、Kubernetes サービスと関連する RC/Deployment を含む「複合構造」です。サービス ドメイン オブジェクトには必要なすべての属性のみが含まれており、アプリケーションがデプロイされると、対応する Kubernetes サービスと RC/デプロイメント インスタンスが生成されます。下図は、Service の定義インターフェース(プロトタイプ)を示しています。

インターフェース上でアプリケーションの定義を完了したら、アプリケーションを公開できます。アプリケーションを公開するときは、まずパーティションを選択し、次に Kubernetes API インターフェースを呼び出して、このアプリケーションに関連するすべての Kubernetes リソース オブジェクトを作成し、最後に Pod のステータスを照会して、リリースが成功したかどうか、および失敗の具体的な理由を判断する必要があります。以下は、定義からリリースまでのアプリケーションの主要モジュールの設計図です。

Kubernetes はコンテナ テクノロジーに基づくマイクロサービス アーキテクチャ プラットフォームであることはご存じのとおりです。各マイクロサービスのバイナリ ファイルは、標準の Docker イメージにパッケージ化されます。したがって、アプリケーションのライフサイクル管理プロセス全体における最初のステップは、ソース コードを Docker イメージにパッケージ化することです。このプロセスは簡単に自動化できます。プログラムで実装することも、成熟したサードパーティのオープンソース プロジェクトを通じて実装することもできます。ここでは Jenkins が推奨されます。次の図は、Jenkins によって実装されたイメージ パッケージ化プロセスの概略図です。 Jenkins のパワーと幅広いユーザーベースを考慮して、多くの PaaS プラットフォームは Jenkins を統合して、アプリケーションの完全なライフサイクル管理機能を実装しています。

PaaSプラットフォームの基本ミドルウェア

完全な PaaS プラットフォームでは、アプリケーション開発とホスティング操作を容易にするために、いくつかの共通ミドルウェアを統合して提供する必要があります。まず、最初の重要な基本ミドルウェアは ZooKeeper です。 ZooKeeper は Kubernetes クラスターに簡単にデプロイできます。 Kubernetes の GitHub に YAML リファレンス ファイルがあります。 ZooKeeper は、アプリケーションで使用されるだけでなく、次の図に示すように、PaaS プラットフォームがアプリケーションに提供する「集中構成サービス」の基本コンポーネントとして使用することもできます。

さらに、多くのオープンソース分散システムがクラスターの管理に ZooKeeper を使用していることを考慮すると、これらのクラスターが共有するための ZooKeeper サービスという標準を展開することもできます。

2 番目に重要なミドルウェアの種類は、前述の Redis や Memcache などのキャッシュ ミドルウェアです。また、Kubernetes クラスターに簡単にデプロイし、サードパーティ アプリケーションに基本サービスとして提供することもできます。 Kubernetes の入門ケースには、PHP ページで Redis マスター スレーブ クラスターにアクセスする方法を示す GuestBook の例があります。複雑な Codis クラスターでも、Kubernetes クラスターに正常にデプロイできます。また、RedHat の J2EE メモリ キャッシュ ミドルウェア Infinispan にも Kubernetes クラスタ導入の事例があります。

3 番目に重要なミドルウェアの種類は、メッセージ キュー ミドルウェアです。従来の ActiveMQ、RabbitMQ、または新世代の Kafka のいずれであっても、これらのメッセージ ミドルウェアは Kubernetes クラスターに簡単にデプロイしてサービスを提供できます。次の図は、Kubernetes プラットフォーム上で 3 ノードの RabbitMQ クラスターをモデル化する概略図です。 RabbitMQ クラスターを形成するために、3 つの Pod を定義しました。各 Pod は Kubernetes サービスに対応し、3 つの RabbitMQ サーバー インスタンスにマッピングされます。さらに、外部にサービスを提供して上記の 3 つの Pod に対応する ku8-rabbit-mq-server という別の Service を定義したので、各 Pod には 2 つのラベルがあります。

4 番目の重要なミドルウェアの種類は、分散ストレージ ミドルウェアです。現在、Kubernetes クラスター上では、Ceph クラスターが提供するブロック ストレージ サービスと、GlusterFS が提供する分散ファイル ストレージ サービスが利用できます。その中で、GlusterFS は、RedHat の OpenShift プラットフォームによってファイル ストレージの標準ストレージ システムとして推奨されています。以下はこのソリューションの概略図です。

RedHat のソリューションでは、GlusterFS クラスターは独立したサーバー クラスターに展開され、クラスター サイズが大きく、パフォーマンスとストレージ要件が高いシナリオに適しています。マシンが限られている場合は、Kubernetes クラスター内の各ノードを GlusterFS ストレージ ノードとして扱い、DaemonSet スケジューリング メソッドを使用して GlusterFS を Kubernetes クラスターにデプロイすることもできます。具体的なデプロイメント方法については、Kubernetes GitHub Web サイトで詳しく説明されています。 GlusterFS クラスターを Pod モードでデプロイすると、GlusterFS のデプロイと操作も非常に簡単になります。

全文検索機能を提供する ElasticSearch クラスターも Kubernetes に簡単にデプロイできます。前述の集中ログ収集とクエリ分析のための 3 ピースの ELK セットは、現在基本的にすべて Pod の形式でデプロイされており、Kubernetes クラスター ログとユーザー アプリケーション ログの統合収集、クエリ、分析を実現しています。

現在注目されているビッグデータ分野では、Hadoop、HBase、Spark、Storm などの重量級クラスターなど、多くのシステムをコンテナ化された方法で Kubernetes クラスターにデプロイすることもできます。次のセクションでは、Storm On Kubernetes のモデリング ソリューションを示し、それを Kubernetes クラスターにデプロイします。最後に、第 6 章で WordCountTopology ジョブを送信し、実行結果を確認します。

Kubernetes 上の Storm の動作

第 6 章の学習を通じて、Storm クラスターは ZooKeeper、Nimbus (マスター)、およびいくつかの Supervisor (スレーブ) ノードで構成されていることがわかりました。クラスター構成ファイルは、デフォルトで conf/storm.yaml に保存されます。最も重要な構成パラメータは次のとおりです。

  • storm.zookeeper.servers: ZooKeeper クラスター内のノードの IP アドレスのリスト。
  • nimbus.seeds: Nimbus の IP アドレス。
  • supervisor.slots.ports:Supervisor 内のワーカーのリスニング ポートのリスト。

上記の主要な構成情報と Storm クラスターの動作原理に基づいて、まず、Nimbus と Supervisor がアクセスできるように固定ドメイン名アドレスを提供するために、ZooKeeper を Kubernetes サービスとしてモデル化する必要があります。以下は ZooKeeper のモデリング プロセスです (簡単にするために、1 つの ZooKeeper ノードのみをモデル化します)。

まず、ZooKeeper に対応するサービスを定義します。サービス名は ku8-zookeeper で、関連付けられているラベルは app=ku8-zookeeper Pod です。

  1. apiバージョン: v1種類: サービスメタデータ:
  2. 名前: ku8-zookeeper仕様:
  3. ポート:
  4. 名前: クライアントポート: 2181セレクタ:
  5. アプリ: ku8-zookeeper

次に、ZooKeeper に対応する RC を定義します。

  1. APIバージョン: v1
  2. 種類: レプリケーションコントローラメタデータ:
  3. 名前: ku8-zookeeper-lspec:
  4. レプリカ: 1テンプレート:
  5. メタデータ:
  6. ラベル:
  7. アプリ: ku8-zookeeper仕様:
  8. コンテナ:
  9. 名前: サーバー
  10. 画像: jplock/zookeeper
  11. imagePu1lPolicy: IfNotPresentポート:
  12. -コンテナポート: 2181

次に、Storm クライアントはトポロジ タスクを送信するために Nimbus サービスに直接アクセスする必要があるため、Nimbus を Kubernetes サービスとしてモデル化する必要があります。そのため、conf/storm.yaml に nimbus.sceds パラメーターがあります。 Nimbusはポート6627でThriftベースのRPCサービスを提供するため、Nimbusサービスの定義は次のとおりです。

  1. Apiversion:V1Kind:ServiceMetadata:
  2. 名前:nimbusspec:
  3. セレクタ:
  4. アプリ:Storm-Nimbusports:
  5. -NAME:nimbus-rpc
  6. ポート: 6627
  7. ターゲットポート: 6627

storm.yaml構成ファイルに多くのパラメーターがあることを考慮して、任意のパラメーターの構成可能性を達成するために、Kubernetesの構成マップリソースオブジェクトを使用してStorm.yamlを保存し、Nimbus(および監督者)ノードに対応するPODインスタンスにマッピングできます。以下は、この場合に使用されているstorm.yamlファイル(storm-conf.yaml)の内容です。

  1. storm.zookeeper.servers:[ku8-zookeeper]
  2. nimbus.seeds:[nimbus] storm.log.dir: "log"
  3. 嵐。 local.dir: "Storm-Data" supervisor.slots.ports:
  4. -6700
  5. 670167026703

上記の構成ファイルを対応するConfigMap(Storm-Config)として作成するには、次のコマンドを実行できます。

  1. Kubelet Create ConfigMap Storm-Config - From-File = Storm-Conf.yaml

次に、Storm-Configは、コンテナ内の指定されたパスへのボリュームとして、任意のポッドで取り付けることができます。次に、Nimbusサービスに対応するPODのモデリングを続けることができます。 Docker Hubで関連するストーム画像を検索して分析した後、Dockerが正式に提供する画像ストーム:1.0を選択しました。他の嵐の画像と比較して、この公式に維持されている画像には次の利点があります。

  • ストームの新しいバージョン。
  • Stormには全体の画像が1つしかなく、コンテナのコマンドパラメーターは、Nimbus Masterノード、Nimbus-UIマネージャー、またはスーパーバイザースレーブノードなど、どのタイプのノードを起動するかを決定します。
  • ストームプロセスを開始する標準化された方法では、コンテナの外側のconf/storm.yaml構成ファイルをマッピングできるため、Kubernetesの構成機能を使用できます。

ストームを使用してニンバスポッドを定義するYAMLファイル:1.0画像は次のとおりです。

  1. Apiversion:V1Kind:Pod
  2. メタデータ:
  3. 名前:nimbuslabels:
  4. アプリ:Storm-Nimbusspec:
  5. ボリューム:
  6. 名前:config-volumeconfigmap:
  7. 名前:Storm-Configitems:
  8. 1つの鍵:Storm-conf.yaml
  9. パス:storm.yaml
  10. コンテナ:
  11. - 名前:ニンバス
  12. 画像:ストーム: 1.0
  13. ImagePullpolicy:ifnotpresentports:
  14. -containerport: 6627
  15. コマンド:[ "Storm""nimbus" ] volumemounts:
  16. - 名前:config-volumemountpath: /conf
  17. 再起動ポリシー: 常に

ここでは、2つの詳細に注意する必要があります。最初の詳細は、configMapの使用です。まず、以前に定義されたconfigmap -storm -configをポッドのボリュームにマップし、このボリュームをコンテナ内の特定のパスに取り付ける必要があります。 2番目の詳細は、コンテナのコマンドパラメーターです。上記のコマンド:["Storm"、 "Nimbus"]は、この容器がNimusプロセスを開始することを示します。

同様に、グラフィカルなストーム管理機能を提供するWeb管理プログラムであるStorm-UIサービスを定義します。 Kubernetesクラスターの外でアクセスする必要があるため、NodePortを介してホストのポート8080をポート30010にマッピングします。 Storm-UIサービスのYAML定義ファイルは次のとおりです。

  1. Apiversion:V1Kind:ServiceMetadata:
  2. 名前:Storm-Uispec:
  3. タイプ:nodeportselector:
  4. アプリ:Storm-Uiports:
  5. -Name:web
  6. ポート: 8080
  7. ターゲットポート:8080NodePort: 30010

最後に、監督者をモデル化するようになります。監督者は積極的に呼び出されないため、監督者をサービスとしてモデル化する必要はないようですが、実際には監督者ノードは互いにコミュニケーションを開始します。したがって、Zookeeperのスーパーバイザーノードによって登録されたアドレスは、互いにアクセスできる必要があります。 Kubernetesプラットフォームでこの問題を解決するには、2つの方法があります。

最初の方法では、スーパーバイザーノードがZookeeperに登録されている場合、ホスト名(ポッド名)は使用されませんが、PODのPアドレスが使用されます。

2番目の方法では、ヘッドレスサービスモードを使用します。各スーパーバイザーノードはヘッドレスサービスとしてモデル化されており、スーパーバイザーノードのコンテナ名(ホスト名)がヘッドレスサービスの名前と同じであることが保証されます。この時点で、Zookeeperに登録されているスーパーバイザーノードのアドレスはヘッドレスサービス名と同じであり、スーパーバイザーノードは互いのヘッドレスサービスドメイン名を使用して通信できます。

その中で、最初の方法では、スーパーバイザーの起動スクリプトと対応するパラメーターを変更する必要があります。これは、実装がより面倒です。 2番目の方法は、画像を変更せずに実装できるため、最初の方法を採用しました。さまざまな方法でモデリング。以下は、スーパーバイザーノードのサービス定義です。 Clusteripの特別な表記に注意してください:なし:

  1. Apiversion:V1
  2. 種類:ServiceMetadata:
  3. 名前:Storm-Supervisorspec:
  4. Clusterip:NoneSelector:
  5. アプリ:Storm-Supervisorports:
  6. - ポート: 8000

Storm-Supervisorノードのポッド定義は次のとおりです。ポッド名はStorm-Supervisorであり、コマンド値は["Storm"、 "Supervisor"]であることに注意してください。

  1. Apiversion:V1Kind:Pod
  2. メタデータ:
  3. 名前:Storm-Supervisorlabels:
  4. アプリ:Storm-Supervisorspec:
  5. ボリューム:
  6. 名前:config-volumeconfigmap:
  7. 名前:Storm-Configitems:
  8. 1つの鍵:Storm-conf.yaml
  9. パス:storm.yaml
  10. コンテナ:
  11. 名前:Storm-Supervisorimage:Storm: 1.0
  12. イメージプルポリシー: IfNotPresent
  13. コマンド:[ "Storm""Supervisor" ] volumemounts:
  14. -Name:config-volumemountpath: /conf
  15. RestArtPolicy:常に

複数のスーパーバイザーノードを定義できます。たとえば、この場合、2つのスーパーバイザーノードが定義されています。 Kubernetesクラスターに正常に展開した後、Storm UIのポート30010を介してStorm Managementインターフェイスを入力し、次のインターフェイスを確認します。

次のスクリーンショットでは、2つのスーパーバイザーノードもクラスターに正常に登録できることを確認します。各ノードには4つのスロットがあることがわかります。これは、Storm.yamlでの構成に沿っています。

この時点で、Kubernetes上のストームクラスターのモデリングと展開が正常に完了しました。次に、ストームクラスターで以前に学んだWordCountopologyの仕事を提出する方法を見て、それがどのように実行されるかを観察しましょう。

まず、https://ljar-download.com/にアクセスして、コンパイルされたWordCountTopology Job JARファイルをダウンロードできます
Storm-Starter-Topologies-1.0.3.jar、その後、ストームクライアントツールを介してトポロジージョブをストームクラスターに提出します。ジョブを送信するコマンドは次のとおりです。

  1. Storm Jar/userlib/Storm-Starter-Topology -1.03.jar org.apache.storm.starter.ordcounttopologyトポロジー

ストームクライアントツールはすでにストームに含まれているため、1.0イメージがあるため、最も簡単な方法はポッドを定義してからダウンロードすることです。
Storm-Starter-Topologies-1.0.3.Jarは、ポッドの / userlib /ディレクトリのボリュームとしてマッピングされています。コンテナの開始コマンドを上記のコマンドに設定して、ジョブを送信します。以下は、このポッドのYAML定義です。

  1. Apiversion:V1
  2. 種類:Podmetadata:
  3. 名前:Storm-Topo-Examplespec:
  4. ボリューム:
  5. 名前:user-libhostpath:
  6. パス: /root /stormName:config-volumeconfigmap:
  7. 名前:Storm-Configitems:
  8. - キー:Storm-conf.yaml
  9. パス:嵐。ヤム
  10. コンテナ:
  11. 名前:Storm-Topo-ExampleImage:Storm: 1.0
  12. イメージプルポリシー: IfNotPresent
  13. コマンド:[ "Storm""Jar" ​​、 "/userlib/storm-starter-topologies-1.0.3.jar"
  14. 「org.apache.storm.starter.wordcounttopology」「トポロジー」 ]]
  15. ボリュームマウント:
  16. - 名前:config-volumemountpath: /conf
  17. 名前:user-lib
  18. MountPath: /userlib
  19. 再起動ポリシー: なし

上記の定義には、次の重要なポイントがあります。

  • ホストの /ルート /ストームディレクトリにStorm-Starter-Topologies-1.0.3.Jarを配置します。
  • コンテナの開始コマンドはストームクライアントであり、トポロジジョブが提出されます。
  • トポロジジョブは必要なため、POD再起動戦略は決してありません。

上記のポッドを作成した後、ポッドのログを確認します。次の出力を見ると、WordCounttopologyのトポロジージョブがストームクラスターに正常に提出されたことを意味します。

次に、嵐UIに行き、仕事の実行を確認します。次の図は、WordCountTopologyの要約情報です。アクティブなステータスを持っています。 8分間実行され、3つのワーカープロセスを占有し、合計28のタスクが実行されます。

ストームクラスターに正常に送信した後、スーパーバイザーノード(POD)を入力して、トポロジジョブのログ出力を表示できます。ジョブのログ出力は、ディレクトリ /ログ /ワーカーアーティファクトにあります。各トポロジジョブには、ログを保存するための個別のフォルダーがあります。 WordCountTopologyの最後のボルト - Tupleが送信したログの統計を検索します。次の結果、つまり各単語(単語)が統計的に出力されることがわかります。

次のインターフェイスは、WordCountopologyに関する詳細な情報を提供します。これは、生成されたいくつかのタスク、合計で送信されたタプルの数、失敗したタプルの数、すべてのボルトに関する関連情報、処理、処理の処理、処理の遅延、その他の統計情報など、すべてのボルトに関する関連情報など、トポロジのすべてのスパウトに関する関連情報を表示します。

上記のリスト情報に加えて、Storm UIは、ストリームの動作を示すトポロジカル図も提供します。下の図に示すように、データフローがスパウトノードから送信されていることがわかります。スプリットノードで処理されるには3.13msかかり、カウントノードに到着します。カウントノードの処理時間は0.06msです。

Stormのトポロジジョブは実行されると停止しません。そのため、WordCountopologyのスパウトノードが常にタプルを生成しているため、次のインターフェースのタプルの統計が増加していることがわかります。

<<:  2021 年にビジネス回復を促進する 3 つのテクノロジーとクラウド コンピューティングのトレンド

>>:  2021 年のテクノロジー予測: クラウドからエッジ コンピューティングまで

推薦する

2020 年のクラウド コンピューティング技術のトレンドの展望

年末が近づくにつれ、業界の調査組織は来年の技術動向を予測し、過去数年間の開発動向に関する予測と洞察を...

王通氏:タオバオSEO市場には大きな成長の余地がある

2002 年、私は SEO を始めたばかりでした。ある日、有名な IT コミュニティに、SEO は急...

Weibo を分析すると、ウェブサイトへのバックリンクを獲得できますか?

多くの人がこう尋ねます: Weibo は外部リンクを導入できますか?今日は、孟澤玉さんがこの質問に答...

3分レビュー! 2021 年 5 月のクラウド コンピューティング分野の重要な動向を簡単に紹介します

このような熱い発展の流れは、2021年も続くでしょう。過去 1 か月間、クラウド コンピューティング...

この記事はJVMについて深く理解するのに役立ちます

[[278753]] 1. JVMとは何かJVM は Java Virtual Machine の略...

100% 米国住宅用 IP VPS および専用サーバー、米国ストリーミングとゲームを網羅、月額 25 ドルから、Windows/Linux

soladrive は、米国住宅 IP、米国住宅 VPS、米国住宅独立サーバーを提供しており、デフォ...

デバイス・エッジ・クラウドの連携: クラウドからエッジへ

SDX は Software Defined X の略で、ソフトウェア定義パラダイムを意味し、ソフト...

情報フロー広告は効果がないのでしょうか?適切なプロモーション チャネルを選択しなかった可能性があります。

これまで、教育機関のプロモーション方法は、校門でのチラシ配布、専門家や教授による講演、電話による販売...

クラウド コンピューティング サービスの利点、欠点、種類

クラウド コンピューティングは、現代のビジネスに柔軟性、効率性、拡張性、セキュリティ、コラボレーショ...

検索エンジンは決して変わらない:ユーザーエクスペリエンスは決して変わらない

ウェブマスターは、検索エンジンのアルゴリズムの変更について再び不満を言っています。実際、検索エンジン...

ZStack をベースにしたディープラーニング クラウド プラットフォームの構築

序文ディープラーニングは機械学習と人工知能研究の人気の分野であり、今日最も人気のある科学研究トレンド...

おすすめ: Ramnode - 永久60%割引コード/有効期限なし

HostCatは、国内のネットユーザー向けに、長期的かつタイムリーに更新されるホスト情報ウェブサイト...

私のように新しいウェブサイトを構築しようとしている新しいウェブサイト所有者向けに書かれています

私のデビュー記事が A5 ウェブマスター プラットフォームに掲載されたときはうれしかったです。今日は...

2019年 小紅書コミュニティトレンドレポート

小紅書は「上向きの生活 -小紅書コミュニティトレンドレポート2019」を発表しました。レポートは、全...