3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dapr を使った React / Express / Flask のマイクロサービスアプリケーションを Azure Container Apps にデプロイする

Posted at

はじめに

本記事は、Microsoft Azure TechQiita アドベントカレンダー の記事です。昔から存在は知っていたけどなんとなく難しそうなイメージがあり、なかなか手を出せていなかった dapr ですが、今回はアドベントカレンダーということでしたので、思い切って勉強と開発をしてみました。dapr ということでマイクロサービスごとは疎結合で連携されているため、PythonJavaScript という技術スタックが異なるコンテナーが動くマイクロサービスを構築してみました。構築後は、Azure Container Apps にデプロイするところまでを記事にまとめています。本記事では、まず初めに daprAzure Container Apps などの説明をした後、構築したマイクロサービスのデモと説明をします。そして最後に、マイクロサービスのデプロイ手順について紹介します。

マイクロサービスアーキテクチャとは

マイクロサービスアーキテクチャとは、大規模なアプリケーションを小さな独立したサービスに分割した構成のことです。マイクロサービスアーキテクチャを使用することで、システム全体の機能のコア領域を個別に開発、アップグレード、バージョン管理、スケーリングできるようになります。これにより、迅速な開発と保守が可能で、異なる技術スタックを利用できるため、効率的で柔軟性の高いアプリケーション開発が実現されます。

image.png

上の図は、モノリシックなアプリケーションとマイクロサービスアプリケーションの違いを概念図として比較したものになります。モノリシックなアプリケーションは、Web 3 層構造などの、Web、ビジネス、データなどの、機能層で分割された構造となっています。クラウドの導入が進み、従来のこうしたモノリシックなアプリケーションは、マイクロサービスアプリケーションアーキテクチャに向かう傾向にあります。マイクロサービスアプリケーションは、個々が小規模な個別サービスなので、あらゆる言語、あらゆるフレームワーク、バージョン、デプロイ、拡張、が可能で自由度が高いですが、複雑性が増すという課題もあります。次の見出しで紹介する dapr はこうした分散システムの複雑性を軽減することが可能です。

dapr とは

daprDistributed Application Runtime)は、分散システムの開発を容易にするためのオープンソースのランタイムフレームワークです。異なるサービスのコミュニケーション、状態管理、エベント処理などの共通機能を抽象化し、開発者がアプリケーションを構築する際の複雑さを軽減します。様々なプログラミング言語やクラウドプラットフォームで利用可能であり、柔軟で拡張可能な分散システムの構築が可能です。dapr では、マイクロサービスアプリケーションを構成要素と呼ばれる独立した API に構築するための仕組みが体系化されています。dapr の機能について、以下で簡単にまとめます。

image.png

  • Service-to-service Invocation
    • サービスの呼び出しのためのエンドポイントが作成され、他のサービスとの連携を容易に実現
  • State Management
    • テートフルなサービスをに対応し、状態データを保存可能
  • Publish and Subscribe
    • サービス同士の Publish-Subscribe メッセージングを実現可能
  • Input/Output Bindings
    • 外部のイベントによるアプリのトリガーと、入出力インターフェイスが利用可能
  • Actors
    • Actor パターンにより、サービス同士の連携が可能
  • Secrets
    • 機密データを格納したストレージに接続してアクセス可能
  • Configuration
    • アプリケーションに関する設定情報が登録可能
  • Distributed Lock
    • ロックをしてリソースへの排他的なアクセスが可能
  • Workflows
    • ビジネスロジックと統合を簡単に記述し、マイクロサービスの調整が可能
  • Cryptography
    • 暗号化キーをアプリケーションに公開することなく、暗号化操作を実行可能

Azure Container Apps とは

Azure Container Apps は、コンテナー化されたアプリケーションを実行するためのサーバーレスプラットフォームです。Azure Container Apps を利用することで、保守するインフラストラクチャが少なくなるため、運用コストを削減できます。Azure Container Apps は 1 つ以上のコンテナーで作られたコンテナーアプリで構成されるため、個々がマイクロサービスとしての役割を果たします。

Azure Container Apps の一般的な用途には以下になります。

  • API エンドポイントのデプロイ
  • バックグラウンド処理ジョブのホスティング
  • イベント駆動型処理の処理
  • マイクロサービスの実行

image.png

Azure Container Apps は、Container Apps Environment と呼ばれるセキュリティ境界内にデプロイされます。また、Azure Container Apps は、スケーリング、バージョン管理、アップグレード、サービス検出、ネイティブの dapr 統合、といったマイクロサービスをデプロイする基盤を提供しています。

image.png

サンプルアプリの紹介・デモ

サンプルアプリのデモ動画を Twitter に載せました。このサンプルアプリは、りんご・ばななの在庫個数をリアルタイムで表示する Web アプリになっています。サンプルアプリの仕様として、りんご・ばななの在庫はそれぞれ 1000 個ずつあり、りんごは 1 秒ごとに 1 個 から 10 個の間の乱数、ばななは 2 秒ごとに 1 個 から 20 個の間の乱数の注文が入るようにするため、りんご・ばななの注文サービスは定期的に dapr に向けて POST 通信をするようにしています。このアプリの全体像を伝えるために、ブラウザで動く Web アプリだけを録画するよりも、他のマイクロサービスで出力されるログを同時に確認できたほうが、サービス全体の動きを理解しやすいと思うので、Visual Studio Code の画面でブラウザと複数のコンソール画面をまとめて 1 画面に録画しました。左上が React による在庫個数を表示したフロント画面であり、中央上が Worker1 によるりんごの注文ログ、右上が Worker2 によるばななの注文ログを表示しており、下が Service によるりんごとばななの受注ログ・在庫個数ログになります。

サンプルアプリのソースコードは以下の GitHub リポジトリに公開しています。

サンプルアプリは以下のソースコードを参考にして開発しました。

アーキテクチャ

構築したマイクロサービスアプリケーションのアーキテクチャ図は以下になります。Azure Container Apps Environments 内に 5 つのマイクロサービスをデプロイし、それぞれに対して Azure Container Apps でホスティングしています。マイクロサービスはそれぞれ Docker でコンテナ化されており、その横にサイドカーとして動く dapr が配置されています。dapr 間は gRPC で通信しており、dapr とサーバー間は HTTP もしくは gRPC で通信をしています。それぞれのサービスで公開しているポート番号や通信経路は以下の図にまとめています。一方で今回はサンプルなので、Vnet による閉域化などの細かい設計はしていません。また、イングレスについても図にのせていませんが、イングレスエンドポイントは常にポート 443 で公開されています。

gRPC は、HTTP/2 によって高速化された通信が可能で、クライアントとサーバー間での双方向なストリーミング通信ができます。

ローカルでのアーキテクチャ
image.png

Azure でのアーキテクチャ
image.png

ローカルと Azure では、起動しているアプリケーションは構造は同じですが、公開ポートなど若干異なる点があります。また、マイクロサービスごとの名前、フレームワークと言語、役割についてそれぞれ以下の表にまとめます。

マイクロサービス名 マイクロサービスのフレームワークと言語 役割
Web(front) React(JavaScript) りんご・ばななの在庫個数の表示画面
Web(backend) Express(Node.js) りんご・ばななの在庫個数伝達サービス
Service Flask(Python) りんご・ばななの受注と在庫管理サービス
Worker1 なし(Python) りんごの注文サービス
Worker2 なし(Python) ばななの注文サービス

また、果物の個数が更新されるまでのデータフローは以下になります。

  1. Worker1Worker2dapr に向けて果物注文のための POST リクエストを行います
  2. dapr 間で gRPC Request が行われ、dapr-Service 間で HTTP 通信が行われます
  3. Service で在庫数を変更した後、Service-dapr 間で HTTP 通信が行われます
  4. dapr 間で gRPC 通信が行われた後、Web backendHTTP 通信が行われます
  5. Web backendWeb frontendWebSocket で繋がっており、HTTP 通信が行われます
  6. Web frontend で果物の在庫個数が更新されます

ローカル実行

サンプルアプリの紹介・デモでは、ローカル実行した様子を録画したものを載せています。dapr run を実行して dapr を使用するには、どうやら以下の 3 パターン方法しかないようだったので、ローカルで実行するときはアプリと dapr はプロセスとして起動し、コンテナーは利用しませんでした。当然、Azure Container Apps にデプロイする際には Docker コンテナ化する必要がありますが。

  • アプリと dapr をプロセスとして起動する方法
  • アプリがプロセスで daprDocker コンテナとして起動する方法
  • アプリと dapr を 1 つの Docker コンテナ内で起動する方法

ローカル実行をするためのコマンドは サンプルアプリを公開している GitHub リポジトリREADME.md にまとめているので必要であればそちらをご確認ください。

デプロイ

ローカルで実行したマイクロサービスアプリケーションのデプロイは、以下の公式ドキュメントを参考にして Azure CLI にて実行しました。コマンドの詳細についてはローカル実行と同様に、 サンプルアプリを公開している GitHub リポジトリREADME.md にまとめているので必要であればそちらをご確認ください。

デプロイ結果

Webfrontend のフロント画面

image.png

Webbackend のログ

image.png

service のログ

image.png

worker1 のログ

image.png

worker2 のログ

image.png

無事、デプロイができました。

おわりに

初めて、dapr に挑戦してみて戸惑う点も多かったですが、慣れてくると確実に便利な技術だと感じました。今回のマイクロサービスアーキテクチャでは dapr コンポーネントは扱わず、サービス呼び出し機能しか扱いませんでしたが、PubSubSecretBind など、他にも dapr には数多くの機能があるので、試してみようと思います。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?