Amazon Web Services ブログ
AWS App Mesh と Kong を使って Amazon EKS 上でマイクロサービスを実行する
この記事は、Running microservices in Amazon EKS with AWS App Mesh and Kong を翻訳したものです。
本投稿は、Kong ソリューションエンジニアの Claudio Acquaviva、Kong アライアンスの Morgan Davies と共同で作成されたものです。
サービスメッシュはサービス間通信のための一般的なアーキテクチャパターンとなっている透過的なインフラストラクチャレイヤーです。Amazon EKS と AWS App Mesh を組み合わせることでマイクロサービスのための強力なプラットフォームを形成し、ロードバランシング、サービスディスカバリ、可観測性、アクセスコントロール、トレース、ヘルスチェック、サーキットブレーカーなどサービス間通信で発生する技術的な要件に対応する事ができます。
モダンなエンタープライズソリューションでは、次のカテゴリの明確な管理制御が必要です。
- API エンドポイントへの外部からのイングレストラフィックをカバリングする API 管理
- 運用管理とサービスの状態に焦点を当てたサービス管理機能
サービスメッシュは主に 2 つ目のカテゴリに対応していますが、イングレストラフィックも同様に重要であり、スロットリング、アプリケーションとユーザの認証、リクエストログとトレース、データのキャッシングなどクラスタ全体のポリシーをサポートするソリューションから恩恵を受けることができます。これらのポリシーに加えてイングレスは使用状況の把握、課金システムの追加、運用上の閾値を超えたアラートの生成などの機能により、API のマネタイズを可能にするレイヤーです。
これらの機能はクラスタ外の周辺ツールを利用することで実現することも可能ですが、Kong for Kubernetes Ingress Controller は HPA、自己修復、RBAC、cert-manager などの Kubernetes の機能を活用して、アプリケーションと並行して稼働しているサービスメッシュを保護するソリューションを提供します。
この記事では、Amazon EKS、AWS App Mesh、Kong for Kubernetes を利用してサービスメッシュを安全に実装する方法について説明します。ここで取り上げる課題の範囲は API や外部トラフィックの管理だけでなく、より深い統合シナリオも含みます。イングレスを Kubernetes ネイティブな方法で処理するだけでなく、サービスメッシュの一部にすることで可観測性、セキュリティ及びトラフィック制御を向上させます。
Kubernetes Ingress Controller のための AWS App Mesh と Kong の設定
AWS App Mesh は、お客様がサービスメッシュを実装するために利用できるフルマネージド型サービスです。このサービスを利用することで複数タイプのコンピューティングインフラストラクチャに跨がり内部のサービス間通信を簡単に管理できます。Kong for Kubernetes はサービスメッシュを外部コンシューマに公開する ingress を通過するトラフィックを制御する為に、ingress に対してポリシーの定義、適用、実行を行います。
Kong for Kubernetes は次の機能をサポートしています。
- スケーラビリティ: Kong for Kubernetes は Kong API ゲートウェイをベースに ingress を管理する役割を担います。アプリケーションのトラフィック量が大きく変動し ingress に影響を与えることはよくあることです。Kong for Kubernetes は、Horizontal Pod Autoscaler (HPA) などの標準の Kubernetes スケーラビリティコントロールを活用しており、需要に合わせてシームレスにスケーリングします。
- セキュリティ: Kubernetes の名前空間ベースの RBAC モデルを活用し一貫したアクセス制御を実現します。これらの制御はソフトウェアのデリバリーや運用に於いてそれぞれの役割を担うプラットフォームチーム、API チーム、アプリケーションチームの間で責任を分離するために必要なものです。例えば、それぞれの名前空間に制限されているアプリケーションチームは ingress オブジェクトを定義することができますが、ingress コントローラと API 管理コンポーネントへのアクセスは専門チームに制限することができます。
- 拡張性: 幅広いプラグインエコシステムはサービスメッシュを保護するためのさまざまなオプションを提供します。例えば、OpenID Connect や相互 TLS 認証と認可、レート制限、IP 制限、Kong Enterprise Developer Portal を介したセルフサービスのクレデンシャル登録などがあります。
- 可観測性: Prometheus、Jaeger、Amazon CloudWatch などのモニタリング、トレース、ロギングツールと完全に統合できます。
こちらが Kong for Kubernetes のアーキテクチャ図です。
Kong for Kubernetes アーキテクチャ
次の図は、Kong for Kubernetes アーキテクチャを示しています。
Kong for Kubernetes のポッドには、次の 2 つのコンテナが含まれています。
- Kong Gateway コンテナは、API トラフィックの処理と Kong for Kubernetes で利用可能なプラグインによって定義されたポリシーの適用を担当するデータプレーンになります。
- Controller コンテナは、Kubernetes マニフェストと CRD を Kong の構成に変換するコントロールプレーンになり、プロキシと Kubernetes の構成を別々に管理する必要がなくなります。
Kong for Kubernetes の前には、Kong Gateway を外部コンシューマーに公開する Classic Load Balancer (CLB) または Network Load Balancer (NLB) があります。さらに Kong for KubernetesはKubernetes クラスタ内で実行されている ClusterIP
タイプのサービスや、クラスタ内で公開されている外部サービスなど後にあるすべてのサービスを保護しています。
前提条件
このプロセスを開始する前に、次の前提条件が整っていることを確認してください。
- EKS 1.15 以降のクラスタが既にデプロイされている。この演習では、eksctl を使用しました。
- Kubectl 1.15 以降がローカルにインストールされている
- Helm V3
- Curl またはその他の HTTP クライアント
ソリューションのデプロイ
今回のデプロイは DJ Service Mesh Application の拡張版であり、その上に ingress コントローラレイヤーを追加したものです。Kong for Kubernetes には認証、ログ処理、キャッシングなど多数のポリシーを実装するためのプラグインが豊富に提供されています。
まずは、API キーベースのセキュリティレイヤーとレート制限ポリシーを実装して、イングレスの使用量を制御してみましょう。
ステップ 1: DJ サービスメッシュアプリケーションをデプロイする
EKS ワークショップで説明されている次の手順に従って、DJ サービスメッシュアプリケーションをデプロイして下さい。
これらの手順では、metal と jazz のマイクロサービス (それぞれ 2 つのバージョン) で構成されるシンプルなソリューションをインストールし、 CRD と App Mesh コントローラーを含む AWS App Mesh コンポーネントをインストールします。これらのコンポーネントはアドミッションコントローラーとして機能し、デプロイしたポッドには Envoy Proxy のサイドカーを挿入します。prod
名前空間は、サイドカーコンテナの自動挿入を可能にするように構成され、トラフィックを制御するために必要な抽象度を提供します。
アプリケーションのメッシュ化により、DJ ポッドと既存のマイクロサービス間の通信が抽象化されます。API は jazz や metal のマイクロサービスのエンドポイントに直接通信するのではなく、仮想サービスを経由して新しい仮想ルーターを使用してトラフィックを制御します。最終的な論理アーキテクチャはこのようになります。
始める前に、クラスタ内にどのような仮想サービス、仮想ルータ、仮想ノードがあるのかを確認してみましょう。
DJ ノードはトラフィックをルーティングせず主にテスト目的で使用されるため、余剰なノードであることに注意してください。重要なのは、App Mesh を使用して jazz-v2 および metal-v2 サービスのカナリアリリースを実装し、全てのトラフィックの 5% を両方のサービスのバージョン 2 にルーティングしていることです。
なぜそれが重要なのでしょうか? サービスの利用方法に関係なく外部入力、もしくは内部の他のサービスを通じて、全ての通信はカナリアリリースによりトラフィックの 5% を新しいバージョンに送信します。
それは素晴らしいことですが、開発プロセスの一環ではカナリアリリースをどのようにテストしますか? DJ ポッドから curl
コマンドを実行できることは可能ですが、CI/CD パイプライン及び API のコンシューマーが外部でなければならない ような (実際の環境と同様) 適切な API テスト戦略では機能しません。
つまり、API を外部に公開することを計画しているのであれば、現状のソリューションを改善すべきであるという事実を浮き彫りにしています。適切な API 管理には、( API キーで識別される) API クライアント 、レート制限、そして最後には使用量の取得と請求に対する制御機能を追加する必要があります。
ステップ 2: Kong for Kubernetes Ingress Controller をデプロイする
このブログ記事では、Kong for Kubernetes で完全に置き換えることができる余剰な DJ ノードを置き換えます。すべてのサービスを外部コンシューマーに公開する ingress オブジェクトを定義します。
次の図は、最終的なトポロジを示しています。
Kong for Kubernetes 名前空間
Kong for Kubernetes コンポーネントが存在する Kubernetes 名前空間は既存のメッシュの一部にし、App Mesh サイドカーの自動挿入を適用するために適切なラベルを設定する必要があります
Kong for Kubernetes 仮想ノード
Kong for Kubernetes のための仮想ノード宣言:
宣言は次の通りです。
- インストールする Kong for Kubernetes ポッドを選択します。
- Jazz および Metal サービスは許可されている唯一のイングレスポイントであるためバックエンドとして定義します。
- Kong for Kubernetes のサービス FQDN を DNS サービスディスカバリとして設定します。
kubectl
を使用して適用します。
仮想ノードを再度確認してください。Kong for Kubernetes 固有のものは、「dj-app」メッシュに組み込まれていることを意味します。
Kong for Kubernetes のインストール
今回は Helm を使って Kong の chart リポジトリを追加し、Kong for Kubernetes をインストールしていきます。
デフォルトでは、App Mesh はメッシュで明示的に定義されているノード以外からの egress を許可しません。その為、ingress コントローラコンテナが API サーバと通信できなくなるので Kong ポッドのデプロイは失敗します。この問題に対処するため App Mesh の機能を使用して、 UID 1337 (デフォルト) のセキュリティコンテキストで実行されているコンテナの egress フィルタリングをバイパスします。ingress コントローラにこのセキュリティコンテキストオプションを設定することで API サーバとの通信が可能になりますが、サービスメッシュ内の他のノードはメッシュ内で定義されたノードとのみ通信するように制限されています。
パッチを適用したらデプロイを検証してすべてのコンテナが実行されていることを確認してみましょう。
ポッド内のすべてのコンテナとイメージをリストアップして、Kong for Kubernetes ポッドに Envoy サイドカーが挿入されていることを確認します。
ステップ 3: サービスメッシュを公開および保護するための Ingress を定義する
サービス構成
Kong for Kubernetes は対応する Kubernetes のエンドポイントに基づいてターゲットを構成します。つまり、Kong 自体が直接ポッドと通信し、エンドポイントの検出メカニズムとしてサービスの抽象化を行なっているということです。これにより、Kong は kube-proxy を通過する余分なホップをバイパスし、最適化された負荷分散アルゴリズムでバランシングすることができます。
AWS App Mesh の場合、サービスへの通信はサービスの完全修飾ドメイン名を介してのみ許可されることに注意が必要です。例えば、 jazz.prod.svc.cluster.local
へのルーティングは許可されていますが、サービスをホスト名で直接呼び出すことはできません (例: curl jazz:9080
) 。ホスト名でサービスを呼び出す機能は AWS App Mesh のロードマップにあるので将来的にはこの設定はもっとシンプルになるでしょう。
幸いなことに、Kong は両方の制約に対処する設定を提供することができます。以下のコマンドは両方の処理を行い、Kong ingress にアップストリームを設定し、ルーティングにサービスのホスト名ではなく FQDN を有効にする設定を使用するように指示します
Kong for Kubernetes Ingress
次のステップは、Kong が提供する適切なセキュリティとトラフィック制御機能を使用して、jazz と metal の両方の仮想サービスを外部に公開するルーティングルールを持つ Kubernetes の ingress オブジェクトを定義します。ingress オブジェクトは標準の Kubernetes オブジェクトです。
- アノテーション
konghq.com/strip-path: "true"
は、ターゲットの仮想サービスに送信する前にリクエストから “/dj/jazz” などの拡張パスを削除します。 - アノテーション
konghq.com/override: do-no-preserve-host
は、リクエスト元のホストを削除する構成オブジェクトを参照します。サービスに適用されている FQDN アノテーションと組み合わせることで、サイドカーが適切な権限に基づいてリクエストをルーティングできるようになります。
ingress 定義で参照される構成オプション「do-not-preserve-host」は、以下を参照しています。
この構成オプションを prod 名前空間の ingress に適用します。
kubectl
で ingress もチェックします。この ingress は Kong proxy 用にプロビジョニングされたものと同じロードバランサーを使用していることに注意してください。
指定した外部アドレスを使用して ingress を利用します。
ループを実行して、カナリアリリースの動作を確認します。
URL パスを /dj/metal
に変更して、メタルサービスにも同じことを行うことができます。
このステップでは、カナリア機能を維持したままサービスを外部に公開しました。さらにサービスメッシュ上に ingress と API 管理のための重要なレイヤーを得ました。ingress は基礎となる仮想サービスへのトラフィックをルーティングする DJ の機能を完全に実装しており、DJ 仮想ノードを削除することができます。
ステップ4:レート制限ポリシーを適用する
ingress が設定されたらその消費量を制御するためのポリシーを定義する必要があります。最初のものはレート制限です。ingress にポリシーを適用するプロセスは非常にシンプルです。
- ポリシーを宣言及び作成する
- ingress にアノテーションでパッチを当てる
以下に示すレート制限ポリシーでは、1 分間に 3 回のリクエストが許可されます。
こちらのポリシーを適用します。
一度作成したポリシーは、それを必要とする ingress に適用することができます。
1 分間に 3 回以上サービスを利用しようとするとエラーが発生します。Kong Ingress を使用すると、基礎実装の一部となる DJ サービスへのトラフィックを制御することができます (後で “classic” や “country” のようなサービスを追加することを想定しています) 。
こちらのページを参考に Kong が提供しているプラグインを確認してログ処理、リアルタイム監視、トレースツールなどの豊富なリストと統合することができます。
ステップ 5:API キーのセキュリティポリシーを定義する
レート制限ポリシーと同様、最初にポリシーを作成してから、このポリシーを ingress に適用する必要があります。
ingress に別のアノテーションを追加して API キーポリシーを適用します。今回は両方のポリシーを適用していることに注目してください。
これで、ingress を利用しようとするとエラーが表示されるようになりました。
キーをプロビジョニングしてコンシューマーに関連付けます。
コンシューマーを作成して、それを consumerapikey
と関連付けましょう。
コンシューマーを識別できるようになったので、API キーを付けて ingress を利用してみましょう。 (curl コマンドに渡されるヘッダーに注意してください) 。
まとめ
Kong for Kubernetes と AWS App Mesh は、複数のプラットフォームにまたがって構築されたサービスに対して一貫した可視性とネットワークトラフィックの制御機能を提供することでサービスの実行を容易にします。AWS App Mesh と Kong for Kubernetes の公式ドキュメントにて、このブログで紹介した製品についての詳細を学ぶことができます。
次の記事では可観測性の追加、トレース、モニタリング、及び AWS X-Ray と Elasticsearch を網羅したインテグレーションを通じて、AWS エコシステムとのより深い統合を紹介していきます。さらに、OIDC やAmazon Cognito を使用した認証・認可の側面にも焦点を当てていきます。
この記事で使用されているポリシーを自由に変更して、キャッシュ、ログ処理、OIDC ベースの認証、カナリア、GraphQL 統合など、Kong が提供する豊富なプラグインリストを使用してポリシーの実装を体験してみてください。
この記事で使用した宣言はすべて GitHub で公開されています。
ー Mikhail Shapirov
翻訳はソリューションアーキテクト黄 光川が担当しました。