高度な Azure Kubernetes Service (AKS) マイクロサービス アーキテクチャ

Azure Application Gateway
Azure Container Registry
Azure Kubernetes Service (AKS)
Azure Virtual Network

この参照アーキテクチャでは、Azure Kubernetes Services でマイクロサービスを実行するときに考慮すべきいくつかの構成について詳しく説明します。 トピックには、ネットワーク ポリシーの構成、ポッドの自動スケール、マイクロサービスベースのアプリケーション全体での分散トレースなどが含まれています。

このアーキテクチャは、Microsoft が推奨する AKS インフラストラクチャの開始点である AKS ベースライン アーキテクチャに基づいています。 AKS ベースラインでは、Microsoft Entra ワークロード ID、イングレスとエグレスの制限、リソース制限、その他のセキュリティで保護された AKS インフラストラクチャ構成などのインフラストラクチャ機能が詳しく示されています。 これらのインフラストラクチャの詳細については、このドキュメントでは説明されていません。 マイクロサービスのコンテンツに進む前に、AKS ベースラインについて理解を深めておくことをお勧めします。

GitHub logo このアーキテクチャのリファレンス実装は、GitHub で入手できます。

アーキテクチャ

Network diagram showing the hub-spoke network with two peered virtual networks and the Azure resources this implementation uses.

このアーキテクチャの Visio ファイルをダウンロードします。

AKS のより基本的なマイクロサービスの例から始める場合は、AKS でのマイクロサービス アーキテクチャに関するページを参照してください。

ワークフロー

この要求フローでは、パブリッシャー/サブスクライバー競合コンシューマー、およびゲートウェイ ルーティングのクラウド設計パターンが実装されます。 メッセージング フローは次のように進みます。

  1. ドローンによる集荷をスケジュールするための HTTPS 要求が送信されます。 要求は Azure Application Gateway を経由して、AKS のクラスター内マイクロサービスとして実行されているインジェスト Web アプリケーションに渡されます。

  2. インジェスト Web アプリケーションによってメッセージが生成され、Service Bus メッセージ キューに送信されます。

  3. バックエンド システムではドローンを割り当て、ユーザーに通知します。 ワークフローは次のようになります。

    • Service Bus メッセージ キューからメッセージ情報が使用されます。
    • HTTPS 要求が配信マイクロサービスに送信され、これによって Azure Cache for Redis 外部データ ストレージにデータが渡されます。
    • HTTPS 要求がドローン スケジューラ マイクロサービスに送信されます。
    • HTTPS 要求がパッケージ マイクロサービスに送信され、これによって MongoDB 外部データ ストレージにデータが渡されます。
  4. HTTPS GET 要求を使用して、配信状態が返されます。 この要求は、Application Gateway 経由で配信マイクロサービスに渡されます。

  5. 配信マイクロサービスでは、Azure Cache for Redis からデータを読み取ります。

Components

このアーキテクチャは、次の Azure コンポーネントを使用します。

Azure Kubernetes Service は、マネージド Kubernetes クラスターを提供する Azure オファリングです。 AKS を使用する場合、Kubernetes API サーバーは Azure によって管理されます。 Kubernetes ノードまたはノード プールにはアクセス可能で、これらはクラスター オペレーターによって管理できます。

このアーキテクチャで使用される AKS インフラストラクチャには、次のものが含まれています。

Azure Virtual Network は 、仮想マシン (VM) とアプリケーションを実行するための分離された安全性の高い環境です。 この参照アーキテクチャでは、ピアリングされたハブスポーク仮想ネットワーク トポロジを使用します。 ハブ仮想ネットワークには、Azure ファイアウォールと Azure Bastion サブネットが保持されます。 スポーク仮想ネットワークには、AKS システムおよびユーザー ノード プールのサブネット、および Azure Application Gateway サブネットが保持されます。

Azure Private Link では、AKS システムおよびユーザー ノード プールのサブネット内のプライベート エンドポイントから Azure Container Registry および Key Vault にアクセスするための特定のプライベート IP アドレスを割り当てます。

Web アプリケーション ファイアウォール (WAF) を使用する Azure Application Gateway では、AKS クラスターへの HTTP(S) ルートを公開し、Web アプリケーションへの Web トラフィックを負荷分散します。 このアーキテクチャでは、Azure Application Gateway イングレス コントローラー (AGIC) を Kubernetes イングレス コントローラーとして使用します。

Azure Bastion では、Secure Socket Layer (SSL) を使用して仮想ネットワーク内の VM へのセキュア リモート デスクトップ プロトコル (RDP) および Secure Shell (SSH) アクセスが提供されるため、パブリック IP アドレスを使用して VM を公開する必要はありません。

Azure Firewall は、すべての Azure Virtual Network リソースを保護するネットワーク セキュリティ サービスです。 このファイアウォールでは、承認されたサービスと完全修飾ドメイン名 (FQDN) のみをエグレス トラフィックとして許可します。

外部ストレージとその他のコンポーネント:

Azure Key Vault では、AKS サービスのセキュリティ キーを格納および管理します。

Azure Container Registry には、AKS クラスターで実行できるプライベート コンテナー イメージが格納されます。 AKS は、その Microsoft Entra マネージド ID を使用して Container Registry に対して認証します。 Docker Hub などの他のコンテナー レジストリも使用できます。

Azure Cosmos DB では、オープンソースの Azure Cosmos DB for MongoDB を使ってデータが格納されます。 マイクロサービスは通常ステートレスであり、その状態は外部データ ストアに書き込まれます。 Azure Cosmos DB は、MongoDB および Cassandra 用のオープンソース API を使用する NoSQL データベースです。

Azure Service Bus では、信頼性の高いサービスとしてのクラウド メッセージングとシンプルなハイブリッド統合が実現されます。 Service Bus では、マイクロサービス アプリケーションで一般的な非同期メッセージング パターンがサポートされます。

Azure Cache for Redis ではアプリケーション アーキテクチャにキャッシュ レイヤーを追加して、負荷が高いトラフィックの速度とパフォーマンスを向上させます。

Azure Monitor では、アプリケーション テレメトリや Azure プラットフォームおよびサービスのメトリックなど、メトリックとログが収集されて格納されます。 このデータを使用して、アプリケーションを監視したり、アラートやダッシュボードを設定したり、障害の根本原因を分析したりできます。

その他のオペレーション サポート システム (OSS) コンポーネント:

Helm は Kubernetes のパッケージ マネージャーであり、Kubernetes オブジェクトを発行、デプロイ、バージョン管理、および更新が可能な 1 つの単位にバンドルします。

Azure Key Vault シークレット ストア CSI プロバイダー では、Azure Key Vault に格納されているシークレットを取得し、シークレット ストア CSI ドライバー インターフェイスを使用してそれらを Kubernetes ポッドにマウントします。

Flux は、GitOps Toolkit を利用した、Kubernetes 用のオープンで拡張可能な継続的デリバリー ソリューションです。

シナリオの詳細

前の図に示した Fabrikam ドローン配送出荷アプリの例では、この記事で説明するアーキテクチャ コンポーネントと手順が実装されています。 この例では、架空の会社である Fabrikam, Inc. が複数のドローンを管理しています。 企業がサービスに登録すると、ユーザーは、ドローンで商品を集荷して配送するように依頼できます。 顧客が集荷のスケジュールを設定すると、バックエンド システムによってドローンが割り当てられ、配送予定時刻がユーザーに通知されます。 配送中、ETA は常時更新され、顧客はドローンの場所を追跡できます。

考えられるユース ケース

このソリューションは、航空機、航空宇宙、航空の各業界に最適です。

Recommendations

高度な AKS マイクロサービス アーキテクチャをデプロイするときは、次の推奨事項を実装してください。

Application Gateway イングレス コントローラー (AGIC)

API ゲートウェイ ルーティングは、一般的なマイクロサービスの設計パターンです。 API ゲートウェイは、要求をクライアントからマイクロサービスにルーティングするリバース プロキシとして機能します。 Kubernetes の "イングレス" リソースと "イングレス コントローラー" は、次の方法でほとんどの API ゲートウェイ機能を処理します。

クライアント要求を適切なバックエンド サービスにルーティングすることで、クライアントに単一のエンドポイントを提供し、クライアントをサービスから切り離せるようにします。

  • クライアントとバックエンド間での頻繁な通信を減らすために、複数の要求を 1 つの要求に集約する。
  • SSL 終了、認証、IP 制限、クライアントのレート制限または調整などの機能をバックエンド サービスからオフロードする。

AKS クラスターの状態は Application Gateway 固有の構成に変換され、Azure Resource Manager 経由で適用されます。

外部のイングレス コントローラーによって AKS クラスターへのトラフィック インジェストが簡素化され、安全性とパフォーマンスが向上し、リソースが節約されます。 このアーキテクチャでは、Azure Application Gateway イングレス コントローラー (AGIC) をイングレス制御用に使用します。 Application Gateway を使用してすべてのトラフィックを処理することで、追加のロードバランサーが不要になります。 ポッドによって Application Gateway に対する直接接続が確立されるため、必要なホップ数が少なくなり、パフォーマンスが向上します。

Application Gateway には組み込みの自動スケール機能があり、これは、不要な量のコンピューティング リソースを消費する場合にスケールアウトする必要があるクラスター内イングレス コントローラーとは異なります。 Application Gateway では、レイヤー 7 のルーティングと SSL 終了を実行でき、エンドツーエンドのトランスポート層セキュリティ (TLS) が、組み込みの "Web アプリケーション ファイアウォール (WAF) " と統合されています。

AGIC イングレス オプションでは、AKS クラスターを構成するときに CNI ネットワークを有効にする必要があります。これは、Application Gateway が AKS 仮想ネットワークのサブネットにデプロイされるためです。 マルチテナント ワークロードや、開発環境とテスト環境をサポートする単一のクラスターでは、さらに多くのイングレス コントローラーが必要になる場合があります。

ゼロトラスト ネットワーク ポリシー

ネットワーク ポリシーでは、AKS ポッドが相互に通信する方法、および他のネットワーク エンドポイントと通信する方法が指定されます。 既定では、すべてのイングレスおよびエグレス トラフィックがポッドとの間で許可されます。 マイクロサービスが相互に通信する方法、および他のエンドポイントと通信する方法を設計する場合は、サービス、デバイス、アプリケーション、またはデータ リポジトリへのアクセスに明示的な構成が必要になる "ゼロトラストの原則" に従うよう検討してください。

ゼロトラスト ポリシーを実装する方法の 1 つは、ターゲット名前空間内のすべてのポッドへのすべてイングレスおよびエグレス トラフィックを拒否するネットワーク ポリシーを作成することです。 次の例は、backend-dev 名前空間にあるすべてのポッドに適用される "すべて拒否ポリシー" を示しています。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: backend-dev
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

制限の厳しいポリシーが準備できたら、マイクロサービス内の各ポッドとの間で送受信されるトラフィックを許可する特定のネットワーク ルールを定義します。 次の例では、app.kubernetes.io/component: backend に一致するラベルを持つ backend-dev 名前空間内のすべてのポッドにネットワーク ポリシーが適用されます。 このポリシーは、app.kubernetes.io/part-of: dronedelivery に一致するラベルを持つポッドが送信元でない限り、すべてのトラフィックを拒否します。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: package-v010-dev-np-allow-ingress-traffic
  namespace: backend-dev
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/component: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app.kubernetes.io/part-of: dronedelivery
    ports:
    - port: 80
      protocol: TCP

Kubernetes ネットワーク ポリシーと、潜在的な既定のポリシーのその他の例について詳しくは、Kubernetes のドキュメントの「ネットワーク ポリシー」を参照してください。

リソース クォータ

リソース クォータは、管理者が開発チームまたはプロジェクト全体でリソースを予約および制限するための方法です。 名前空間にリソース クォータを設定し、それらを使用して次の制限を設定できます。

  • コンピューティング リソース: CPU とメモリ、GPU など。
  • ストレージ リソース: ボリュームの数または特定のストレージ クラスのディスク領域の量が含まれます。
  • オブジェクト数: 作成可能なシークレット、サービス、ジョブの最大数など。

リソースの要求または制限の累積合計が、割り当てられたクォータを超えると、それ以上のデプロイは成功しません。

リソース クォータを使用すると、名前空間に割り当てられた一連のポッドの合計が名前空間のリソース クォータを超えないようにすることができます。 それにより、フロント エンドがバックエンド サービスをリソース不足にすることはなくなり、その逆も同様です。

リソース クォータを定義するときは、名前空間内で作成されるすべてのポッドのポッド仕様で、制限または要求を指定する必要があります。 これらの値が指定されていない場合、デプロイが拒否されます。

次の例は、リソース クォータの要求と制限を設定するポッド仕様を示しています。

requests:
  cpu: 100m
  memory: 350Mi
limits:
  cpu: 200m
  memory: 500Mi

リソース クォータの詳細については、以下を参照してください。

自動スケール

Kubernetes では、デプロイに割り当てられているポッドの数を増やしたり、クラスター内のノードを増やして使用可能なコンピューティング リソースの合計を増やしたりするための "自動スケール" がサポートされています。 自動スケールは、自己修正型の自律的フィードバック システムです。 ポッドとノードを手動でスケーリングすることもできますが、自動スケールを使用すると、高負荷のときにサービスのリソースが不足する可能性を最小限に抑えられます。 自動スケール戦略では、ポッドとノードの両方を考慮に入れる必要があります。

クラスターの自動スケール

"クラスター オートスケーラー" (CA) は、ノードの数をスケーリングします。 リソース制約のためにポッドをスケジュールできない場合、クラスター オートスケーラーにより、追加ノードがプロビジョニングされます。 AKS クラスターとワークロードの稼働を維持する最小数のノードと、トラフィックの負荷が多い場合の最大数のノードを定義します。 CA は、保留中のポッドまたは空のノードを数秒ごとにチェックし、AKS クラスターを適切にスケーリングします。

次の例は、ARM テンプレートの CA 構成を示しています。

"autoScalerProfile": {
    "scan-interval": "10s",
    "scale-down-delay-after-add": "10m",
    "scale-down-delay-after-delete": "20s",
    "scale-down-delay-after-failure": "3m",
    "scale-down-unneeded-time": "10m",
    "scale-down-unready-time": "20m",
    "scale-down-utilization-threshold": "0.5",
    "max-graceful-termination-sec": "600",
    "balance-similar-node-groups": "false",
    "expander": "random",
    "skip-nodes-with-local-storage": "true",
    "skip-nodes-with-system-pods": "true",
    "max-empty-bulk-delete": "10",
    "max-total-unready-percentage": "45",
    "ok-total-unready-count": "3"
},

ARM テンプレートの次の行では、CA の最小および最大ノードの例を設定しています。

"minCount": 2,
"maxCount": 5,

ポッドの自動スケール

"ポッドの水平オートスケーラー (HPA) " は、観察された CPU、メモリ、またはカスタム メトリックに基づいてポッドをスケーリングします。 ポッドの水平スケーリングを構成するには、Kubernetes デプロイ ポッド仕様で、ターゲット メトリックとレプリカの最小数および最大数を指定します。サービスのロード テストを実行して、これらの数値を確認します。

CA と HPA は連携できるため、AKS クラスターで両方のオートスケーラー オプションを有効にしてください。 HPA によりアプリケーションがスケーリングされ、CA によりインフラストラクチャがスケーリングされます。

次の例では、HPA のリソース メトリックを設定します。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: delivery-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: delivery
  minReplicas: 2
  maxReplicas: 5
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 60

HPA では、消費されている実際のリソースや実行中のポッドからのその他のメトリックを調べますが、CA では、まだスケジュールされていないポッドのためにノードをプロビジョニングします。 そのため、CA ではポッド仕様での指定に従って、要求されたリソースを確認します。これらの値を微調整するには、ロード テストを使用します。

正常性プローブ

Kubernetes は、サービスのラベル セレクターに一致するポッドへのトラフィックを負荷分散します。 正常に起動され、正常な状態にあるポッドのみがトラフィックを受信します。 コンテナーがクラッシュした場合、Kubernetes はポッドを削除し、置き換えをスケジュールします。

Kubernetes では、ポッドは 2 種類の正常性プローブを公開できます。

  • "liveness probe" は、ポッドが正常に開始されて正常であるかどうかを Kubernetes に伝えます。
  • "readiness probe" は、ポッドが要求を受け付ける準備ができたかどうかを Kubernetes に通知します。

liveness probe は、まだ実行中だが、異常があるためリサイクルする必要があるポッドを処理します。 たとえば、HTTP 要求を処理しているコンテナーがハングした場合、コンテナーはクラッシュしませんが、要求の処理を停止します。 HTTP liveness probe は応答を停止します。これにより、ポッドを再起動するように Kubernetes に通知されます。

ポッドが正常に起動されたにもかかわらず、そのポッドがトラフィックを受信する準備ができていない場合があります。 たとえば、コンテナーで実行されているアプリケーションが初期化タスクを実行している可能性があります。 readiness probe は、ポッドがトラフィックを受信する準備ができているかどうかを示します。

マイクロサービスでは、実行するチェック用に特別に調整された遅延とタイムアウトを指定して、正常性プローブを促進するエンドポイントをコード内で公開する必要があります。 HPA 式のキーは、ポッドの準備フェーズからほぼ外れているため、正常性プローブが存在して正確であることが重要です。

監視

マイクロサービス アプリケーションにおいて、"アプリケーション パフォーマンス管理 (APM) " での監視は、異常を検出し、問題を診断し、サービス間の依存関係をすばやく理解するために重要です。 Azure Monitor の一部である Application Insights では、.NET Core、Node.js、Java、およびその他の多くのアプリケーション言語で記述されたライブ アプリケーション向けの APM 監視が提供されます。

Application Insights:

  • 待機時間や結果コードなど、HTTP 要求が記録されます。
  • 分散トレースが既定で有効になります。
  • トレースに操作 ID が含まれるので、すべてのトレースを特定の操作と照合できます。
  • 多くの場合、トレースに追加のコンテキスト情報が含まれます。

サービス テレメトリを Kubernetes でコンテキスト化するには、Azure Monitor テレメトリを AKS と統合して、コントローラー、ノード、コンテナーのほか、コンテナーとノードのログからメトリックを収集します。 .NET を使用している場合 Application Insights for Kubernetes ライブラリでは、イメージ、コンテナー、ノード、ポッド、ラベル、レプリカ セットの情報を使用して Application Insights テレメトリを強化します。

次の図は、AKS マイクロサービス テレメトリ トレース用に Application Insights で生成されるアプリケーション依存関係マップの例を示しています。

Example of an Application Insights dependency map for an AKS microservices application.

Application Insights 統合用の共通言語をインストルメント化するためのオプションの詳細については、Kubernetes 用のアプリケーション監視に関する記事を参照してください。

考慮事項

以降の考慮事項には、ワークロードの品質向上に使用できる一連の基本原則である Azure "Well-Architected Framework" の要素が組み込まれています。 詳細については、「Microsoft Azure Well-Architected Framework」を参照してください。

スケーラビリティ

スケーラビリティを計画する際には、次の点を考慮してください。

  • レプリカの数の自動スケールと命令型または宣言型の管理を組み合わせないでください。 ユーザーと自動スケーラーの両方がレプリカの数を変更しようとすると、予期しない動作が発生する可能性があります。 HPA が有効になっている場合は、レプリカの数をデプロイする最小数に減らします。

  • ポッドの自動スケールの副作用は、スケールアウトおよびスケールイン イベントが発生すると、ポッドがより頻繁に作成または削除される可能性があることです。 これらの影響を軽減するには、次の手順を実行します。

    • 準備プローブを使用して、新しいポッドがトラフィックを受け付ける準備ができたら Kubernetes に認識されるようにします。
    • ポッド中断バジェットを使用して、サービスから一度に削除できるポッドの数を制限します。
  • クラスターを作成した後に VM サイズを変更することはできないため、クラスターの作成時にエージェント ノードの適切な VM サイズを選択するために、初期の容量計画を実行する必要があります。

  • マルチテナントまたは他の高度なワークロードには、より多くのおそらく小さいサブネットを必要とするノード プール分離要件がある場合があります。 一意のサブネットを持つノード プールの作成の詳細については、「一意なサブネットを持つノード プールを追加する」をご覧ください。 ハブスポーク実装の基準は組織によって異なります。 必ず組織のガイドラインに従ってください。

管理の容易性

管理容易性を計画する際には、次の点を考慮してください。

  • 自動デプロイ パイプラインを使用して、AKS クラスター インフラストラクチャを管理します。 このアーキテクチャのリファレンス実装では、パイプラインを構築するときに参照できる GitHub Actions ワークフローが提供されます。

  • ワークフロー ファイルでは、ワークロードではなくインフラストラクチャのみが、既存の仮想ネットワークと Microsoft Entra 構成にデプロイされます。 インフラストラクチャとワークロードを個別にデプロイすることで、ライフサイクルと運用上のさまざまな問題に対処できます。

  • ワークフローは、リージョンで障害が発生した場合に別のリージョンにデプロイするメカニズムとして考えます。 パラメーターと入力を変更して、新しいリージョンで新しいクラスターをデプロイできるようにパイプラインを構築します。

セキュリティ

セキュリティは、重要なデータやシステムの意図的な攻撃や悪用に対する保証を提供します。 詳細については、「セキュリティの重要な要素の概要」を参照してください。

セキュリティを計画する際には、次の点を考慮してください。

  • AKS ポッドは、Microsoft Entra ID に格納されている "ワークロード ID" を使用して自身を認証します。 クライアント シークレットが不要なため、ワークロード ID を使用することをお勧めします。

  • マネージド ID を使用すると、実行中のプロセスで Azure Resource Manager OAuth 2.0 トークンをすばやく取得できます。パスワードや接続文字列は必要ありません。 AKS では、Microsoft Entra ワークロード ID を使用して、ID を個々のポッドに割り当てることができます。

  • マイクロサービス アプリケーションの各サービスには、最小特権の RBAC 割り当てを支援するための一意のワークロード ID を割り当てる必要があります。 ID は、それを必要とするサービスにのみ割り当てる必要があります。

  • アプリケーション コンポーネントで Kubernetes API アクセスが必要な場合、API アクセスが適切にスコープ設定されたサービス アカウントを使用するようにアプリケーション ポッドが構成されていることを確認します。 Kubernetes サービス アカウントの構成と管理の詳細については、「Managing Kubernetes Service Accounts (Kubernetes サービス アカウントの管理)」を参照してください。

  • すべての Azure サービスが、Microsoft Entra ID を使用したデータ プレーン認証をサポートしているわけではありません。 これらのサービス、サード パーティのサービス、または API キーの資格情報またはアプリケーション シークレットを格納するには、Azure Key Vault を使用します。 Azure Key Vault では、一元管理、アクセス制御、保存時の暗号化、すべてのキーとシークレットの監査が行われます。

  • AKS では、1 つ以上のシークレットを Key Vault からボリュームとしてマウントできます。 ポッドはその後、これらの Key Vault シークレットを通常のボリュームと同様に読み取ることができます。 詳細については、GitHub の secrets-store-csi-driver-provider-azure プロジェクトに関するページを参照してください。

コストの最適化

コストの最適化とは、不要な費用を削減し、運用効率を向上させる方法を検討することです。 詳しくは、コスト最適化の柱の概要に関する記事をご覧ください。

  • Microsoft Azure Well-Architected Framework のコスト セクションには、コストに関する考慮事項が記載されています。 具体的なシナリオのコストを見積もるには、Azure 料金計算ツールを使用します。

  • AKS には、Kubernetes クラスターのデプロイ、管理、操作に関連付けられたコストはありません。 ユーザーは、クラスターで消費される VM インスタンス、ストレージ、およびネットワーク リソースについてのみ支払います。 クラスターの自動スケールでは、空または未使用のノードを削除することで、クラスターのコストを大幅に削減できます。

  • 必要なリソースのコストを見積もるには、コンテナー サービスの計算ツールに関するページを参照してください。

  • Kubernetes 固有のコンストラクトによる詳細なクラスター インフラストラクチャ コストの割り当てに対して、AKS コスト分析を有効にすることを検討してください。

次のステップ