新しい IBM Developer JP サイトへようこそ!サイトのデザインが一新され、旧 developerWorks のコンテンツも統合されました。 詳細はこちら

キュー・サイズを基準にメッセージ・コンシューマーを自動スケーリングする

最近ではコンテナーのオーケストレーション・ツールがよく使われるようになってきています。IT ワークロードをパブリック・クラウドとプライベート・クラウドの両方で管理する場合、従来のモデルと比べると、コンテナー・オーケストレーション・ツールにはさまざまな利点があるからです。インテリジェントなスケジューリング、自己修復、自動負荷分散、自動スケーリングは、オーケストレーション・ツールに伴う数多くの利点の数例にすぎません。

このチュートリアルでは、Red Hat® OpenShift® バージョン 3.11 を使用します。OpenShift はフルスタックの自動オペレーションを備えたエンタープライズ対応の Kubernetes コンテナー・プラットフォームとして、ハイブリッド・クラウド・デプロイメントとマルチクラウド・デプロイメントの両方を管理できるようになっています。

OpenShift でのデフォルトの自動スケーリング機能は、メモリー使用量と CPU 使用率に基づいて行われますが、このチュートリアルでは、RabbitMQ 上のキュー・サイズに応じたアプリケーションの自動スケーリングを行います。

このチュートリアルでデプロイするのは基本的に、RabbitMQ クラスターと、RabbitMQクラスター上の特定のキューに対してメッセージを生成するプロデューサー・アプリケーション、このキューからメッセージを取り込むワーカー・アプリケーション、そして RabbitMQ オートスケーラーです。このオートスケーラーがキュー・サイズをチェックして、指定されたいくつかのパラメーターに基づいてワーカー・デプロイメントをスケーリングします。

このソリューションで使用するコンポーネントは次のとおりです。

前提条件

所要時間

このチュートリアルの所要時間は約 30 分です。

手順

ステップ 1. RabbitMQ クラスターを OpenShift にデプロイする

まず始めに、OpenShift 内でプロジェクトを作成して、作成したプロジェクトを選択します。

OpenShift でプロジェクトを作成するダイアログのスクリーンショット

次に、同じプロジェクト上で OpenShift カタログに RabbitMQ テンプレートを追加する必要があります。画面の上部にある「Add to Project (プロジェクトに追加) 」ボタンをクリックし、「Import YAML/JSON (YAML/JSON のインポート) 」を選択します。この RabbitMQ テンプレートの yaml ファイルの内容をコピーして yaml テキスト・ボックスに貼り付けます。

OpenShift の「Import YAML/JSON (YAML/JSON のインポート)」ダイアログのスクリーンショット

Create (作成) 」をクリックします。

表示されるフォーム上で「Process the Template (テンプレートの処理) 」を選択してから、「Continue (続行) 」をクリックします。

「Template Configuration (テンプレート構成)」ページで、プロジェクト名とパスワードを指定します (このチュートリアルで指定する必要があるのはこれだけです)。忘れずに、RabbitMQ ユーザー名とパスワードをメモしておいてください。

OpenShift の「Template Configuration (テンプレート構成)」ページのスクリーンショット

Create (作成) 」をクリックします。

ここではロールのバインディングとネットワーク・ポリシーを定義しているため、Red Hat OpenShift では、ここで 2 番目の確認ステップを行う必要があります。詳細については、OpenShift のドキュメントを参照してください。

数分経つと、正常に稼働しているポッドが表示されるはずです。

OpenShift 内で実行中の RabbitMQ アプリを示す画面のスクリーンショット

次は、rabbitmq-cluster-balancer サービスで使用するルートを作成しましょう。OpenShift 上のサービスにより、ポッドへの内部アクセスが可能になります。これらのサービスを外部トラフィックに公開するには、サービスで使用する「ルート」を作成する必要があります。

rabbitmq-cluster-balancer サービスを調べると、このサービスには 2 つのポートがあることがわかります。ポート「5672」は、アプリケーションがメッセージを生成するとき、そしてメッセージを取り込むときに使用するポートです。rabbitmq-cluster-balancer サービスの IP とポート 5672 をメモしてください。この画面に表示されるサービスのホスト名もメモしておく必要があります。最後のステップで、このホスト名を使用するためです。もう一方のポート 15672 は、RabbitMQ 管理ポータルで使用します。このポートから、RabbitMQ 管理ポータルの UI にアクセスします。

rabbitmq-cluster-balancer サービスの詳細を表示する、OpenShift 内の画面のスクリーンショット

RabbitMQ 管理ポータルに外部からアクセスできるようにすることもできます。それには、同じ画面上にある「Create route (ルートを作成) 」ボタンをクリックすればよいだけです。デフォルトでは、これによってポート 15672 のルートが作成されます。デフォルトの設定のまま、「Create (作成) 」ボタンをクリックして外部アクセス用のルートを作成できます。

OpenShift 内の「Create Route (ルートの作成)」ダイアログのスクリーンショット

上記の操作により、同じ rabbitmq-cluster-balancer サービスのページ上に「15672」ポートのホスト名が表示されるはずです。

RabbitMQ 管理ポータルにアクセスするには、このホスト名にナビゲートして、RabbitMQ クラスターを作成するときに指定した RabbitMQ ユーザー名とパスワードを使用してポータルにサインインします。

ステップ 2. プロデューサー・アプリケーションを OpenShift にデプロイする

次は、プロデューサー・アプリケーションをデプロイします。OpenShift に、私が作成したカスタム Docker イメージを含むデプロイメント yaml ファイルを渡します。この yaml ファイルにより、RabbitMQ クラスター上にキューが作成されて、そのキューを宛先とするメッセージが生成されます。

同じプロジェクト内で、再度「Add to Project (プロジェクトに追加) 」ボタンを使用して「Import YAML/JSON (YAML/JSON のインポート) 」を選択します。producer.yaml ファイルの内容をコピーして yaml テキスト・ボックスに貼り付けてから、そこに含まれる RabbitMQ 資格情報を必ず自分の資格情報に変更してください。

Create (作成) 」をクリックします。その後、プロデューサー・ポッドが正常に稼働していることを確認します。

ステップ 3. RabbitMQ に送信するメッセージを生成する

RabbitMQ に送信するメッセージを生成するには、OpenShift 内の左側のメニューから「Applications (アプリケーション) 」、「Pods (ポッド) 」の順に選択します。表示される画面に、前のステップで作成したプロデューサー・ポッドが示されているはずです。このプロデューサー・ポッドの名前をクリックすると、ポッドの詳細が表示されます。その詳細ページの「Terminal (ターミナル) 」タブをクリックして、プロデューサー・ポッドのターミナルを使えるようにします。

OpenShift 内に表示された、プロデューサー・ポッドの詳細ページにある「Terminal (ターミナル)」タブのスクリーンショット

ターミナルに「python producer.py」と入力すると、「test」という名前の RabbitMQ キュー宛てのメッセージが生成されます。このキューは、RabbitMQ 管理コンソール内でも表示できます。

RabbitMQ 管理コンソール内に表示されたキューを示す画面のスクリーンショット

ステップ 4. ワーカー・アプリケーションを OpenShift にデプロイする

ステップ 2 と同じように、yaml ファイルをデプロイしてワーカー・アプリケーションをデプロイします。この場合も「Add to Project (プロジェクトに追加) 」ボタンを使用して「Import YAML/JSON (YAML/JSON のインポート) 」を選択し、worker.yaml ファイルの内容をコピーして yaml テキスト・ボックスに貼り付けます。

忘れずに自分の RabbitMQ Cluster 資格情報を入力してから、「Create (作成) 」をクリックしてください。

ステップ 5. ワーカー・アプリケーションが RabbitMQ から正常にメッセージを取り込んでいることを確認する

どのような動作が行われているのかを完全に理解するには、このステップが重要となります。ワーカー・アプリケーションは実行中になると同時に、RabbitMQ 上の「test」キューの listen も開始します。RabbitMQ 管理コンソールを調べると、「test」キュー上のメッセージがなくなっていることがわかります。これは、ワーカー・アプリケーションがメッセージを取り込んでいるためです。

時間のかかるワークロードを模倣するために、ワーカー・アプリケーションはキューからメッセージを取り込むたびに 10 秒待機してから、RabbitMQ に対してメッセージを処理したことを確認応答します。この確認応答により RabbitMQ は、メッセージが適切に処理されたので、そのメッセージをメモリー内に維持する必要がなくなったことを知り、ワーカー・アプリケーションによるキュー内の次のメッセージの取り込みを許可します。

OpenShift 内の左側のメニューから「Applications (アプリケーション) 」、「Pods (ポッド) 」の順に選択します。ただし今回は、ワーカー・ポッドを選択してから「Logs (ログ) 」タブを表示します。

OpenShift 内で選択された、ワーカー・ポッドの「Logs (ログ)」タブのスクリーンショット

このログから、ワーカー・ポッドがメッセージを受信できる状態になっていることがわかります。ワーカー・ポッドはプロデューサー・ポッドで生成された最初のメッセージを受信し、その 10 秒後にメッセージを処理して「[x] Done」というメッセージをログに書き込みます。

ワーカー・ポッドはメッセージを処理し終えたので、別のメッセージを取り込める状態になりました。ステップ 3 を繰り返してアプリケーションをテストし、RabbitMQ 管理コンソール内でメッセージを観察できます。

ステップ 6. RabbitMQ オートスケーラーをデプロイする

重要: RabbitMQ オートスケーラーをデプロイするには、プロジェクトを「kube-system」に切り換えて、このステップ全体を通して「kube-system」プロジェクトを使用する必要があります。

現時点では、1 つのワーカー・ポッドが各メッセージを 10 秒間で処理するようになっています。この場合、10 個のメッセージが生成されたとすると、最後のメッセージを処理するまでに 110 秒かかることになります。この最後のメッセージが処理されるまでにユーザーを待たせる時間を 30 秒以内にするにはどうすればよいでしょうか。

オートスケーラー・アプリケーションは、指定されたいくつかのパラメーターに基づいてワーカーの数をスケールアップすることができます。k8s-rabbit-pod-autoscaler の詳しい説明は、この GitHub リポジトリー内で確認できます。

「kube-system」プロジェクト内で、「Add to Project (プロジェクトに追加) 」ボタンを使用して「Import YAML/JSON (YAML/JSON のインポート) 」を選択します。clusterRole.yaml ファイルの内容をコピーして yaml テキスト・ボックスに貼り付けてから、「Create (作成) 」をクリックします。このファイルで定義している「ClusterRole」を使用すれば、クラスター内のリソースに対するアクセス権を付与できます。

serviceAccount.yaml ファイルについても上記の手順を繰り返します。これによって定義されるのは、「ServiceAccount」です。ポッド内で実行されるコンテナーは、この ServiceAccount を使用して Kubernetes クラスターの API サーバーと通信します。

さらに、clusterRoleBinding.yaml ファイルについても同じ手順を繰り返します。これによって定義されるのは「ClusterRoleBinding」です。基本的に、「ClusterRole」を「ServiceAccount」にバインドします。

次は、RabbitMQ オートスケーラーのデプロイメント yaml を定義します。以下の説明からわかるように、デプロイメント yaml 内では「ServiceAccount」を使用します。これにより、「rabbit-pod-autoscaler」ポッドが特定のコマンド (「ClusterRole」を定義する際に指定したコマンド) を特定のリソース (同じ「ClusterRole」を定義する際に指定したリソース) に対して実行できるようになります。

auto-scaler-deployment.yaml ファイルの内容をコピーして、同じ「Import YAML/JSON (YAML/JSON のインポート)」ボタンを使用して貼り付けます。ここでは「kube-system」プロジェクトを使用していることを忘れないでください。

Create (作成) 」ボタンをクリックする前に、この yaml 内のいくつかのパラメーターを更新する必要があります。もう一度このドキュメントを確認して、これから入力するパラメーターについて理解してください。

必要なパラメーターを指定した後、「Create (作成) 」をクリックします。

例として、ここでは以下のパラメーター値を入力しました。

  • INTERVAL: 5 秒。この設定により、RabbitMQ オートスケーラーは 5 秒ごとにキューをチェックして、キュー内で待機中のメッセージの数を調べます。

  • RAABIT_HOST: rabbitmq-cluster-balancer.tutorial.svc.cluster.local。これは、クラスター内の rabbitmq-cluster-balancer サービスのホスト名です。

  • RABBIT_USER および RABBIT_PASS: RabbitMQ クラスターの作成時に指定した資格情報。

  • AUTOSCALING: “1|5|3|tutorial|worker|test”。この設定は、システムが最小 1 つのポッドにスケールダウンし、最大 5 つのポッドにスケールアップすることを意味します。キュー内で 4 件以上のメッセージが待機中になっている場合、RabbitMQ オートスケーラーが「tutorial」プロジェクトの「worker」デプロイメント内のポッドの数を 2 にスケールアップします。キュー内で 7 件以上のメッセージが待機中になっている場合は、RabbitMQ オートスケーラーがポッドの数を 3 にスケールアップするといった具体に、5 つのワーカー・ポッドになるまでスケールアップ・プロセスが続きます。リソース使用量に上限を設けるために、スケールアップ・プロセスは指定された最大ポッド数の 5 に達すると停止します。スケールダウンでも同じロジックが使用されます。つまり、稼働中のポッドが 1 つだけになるまで、システムはキュー内で待機中のメッセージの数に基づいてスケールダウンします。キュー内にメッセージがなくなったとしても、次のメッセージを処理する場合に備えて 1 つのポッドが稼働し続けます。

別の視点から見ると、この構成では、システムまたはアプリケーションのユーザーのために処理の最大許容時間を 40 秒に抑えています。

ステップ 7. RabbitMQ オートスケーラーをテストする

アプリケーションをテストするには、ブラウザー上の 1 つのタブ内でステップ 3 を好きなだけ繰り返します。このステップでターミナルに python producer.py を入力するたびに 1 つのメッセージが生成されます。前述のように、各メッセージがキューからワーカー・アプリケーションに取り込まれてから処理が終わるまでには 10 秒かかります。

OpenShift 内のプロデューサー・アプリのターミナルを示す画面のスクリーンショット

別のタブで、「kube-system」プロジェクトに含まれる rabbit-pod-autoscaler ポッドのログを開きます。

OpenShift 内のオートスケーラー・ポッドのログを示す画面のスクリーンショット

キュー上のメッセージ数に関するログと、スケーリングの更新に関するログが表示されます。

OpenShift 内のオートスケーラー・ログを示す画面のスクリーンショット

チュートリアル・プロジェクトに含まれる「worker」デプロイメントを調べて、スケーリング・プロセスを確認することもできます。

alt

この画面で、ポッドの数が変わっていることを確認できます。つまり、OpenShift がワーカー・アプリケーションのリソースを自動的に増やして入力を所定の期間で処理できるようにし、遅延を防止しているということです。

alt

まとめ

このチュートリアルでは、テンプレートを使用して迅速に RabbitMQ クラスターを OpenShift 上にデプロイする方法を説明しました。また、OpenShift 上にさまざまなアプリケーションを簡単にデプロイする方法も説明しました。最後に、RabbitMQ のキュー・サイズに基づいてアプリケーションの自動スケーリングを行う方法を説明しました。

このチュートリアルではすべての手順を行うために OpenShift 管理コンソールを使用しましたが、ターミナル・ウィンドウから OpenShift クライアント・ツール (OC ツール) を使用することもできます。

OpenShift の詳細に興味がある場合は、「Kubernetes with OpenShift 101: Exercises to get you started with Running Node-RED on OpenShift」に取り組んでください。また、OpenShift ドキュメントで詳細を確認することもできます。