Amazon Web Services ブログ

ゴールドマンサックスが AWS PrivateLink を使用して、Amazon MSK クラスターへのクロスアカウント接続を構築した方法



このゲスト投稿では、AWS アカウントや Amazon Virtual Private Cloud (Amazon VPC) の枠を越えて AWS PrivateLink を使用して、Amazon Managed Streaming for Apache Kafka にアクセスする方法をご紹介します。さらに、ゴールドマンサックスのトランザクションバンキングチーム (TxB) がクロスアカウントへのアクセスに選んだ方法、その選択の理由、TxB が Amazon MSK でセキュリティ要件を満たす方法についても解説します。この投稿はゴールドマンサックスの実装をユースケースとして使用し、Amazon MSK 環境の実装時における一般的なガイダンスを目的としています。

概要

Amazon MSK は、Apache Kafka を使ってストリーミングデータを処理するアプリケーションを、簡単に構築および実行できるようにする完全マネージドサービスです。MSK クラスターを作成すると、同じ Amazon VPC 内の参加者がクラスターリソースを利用できます。このため、VPC の特定のサブネット内でクラスターを起動し、クラスターをセキュリティグループに関連付け、Elastic Network Interface (ENI) を介して VPC のアドレススペースから IP アドレスを添付できます。クライアントとクラスター間のネットワークトラフィックは AWS ネットワーク内に留まり、デフォルトではクラスターへのインターネットアクセスはできません。

同じまたは異なる AWS アカウント内の別の VPC にある MSK クラスターへのクライアントアクセスを許可する必要がある場合があります。VPC ピアリングトランジットゲートウェイ などのオプションがあるため、どちらかの VPC 内のリソースが同じネットワーク内にあるかのような相互通信が可能となります。アクセスオプションの詳細については、「Amazon MSK クラスター へのアクセス」をご参照ください。

これらのオプションは有効ですが、この投稿では AWS PrivateLink を使用する別のアプローチを取り上げています。ですから、実際のパターンを深く掘り下げる前に、AWS PrivateLink がクロスアカウントおよびクロス VPC アクセスにより適切な戦略である場合について簡単に説明します。

以下に示す VPC ピアリングは 2 つの VPC 間の双方向ネットワーク接続です。これで、プライベート IPv4 アドレスまたは IPv6 アドレスを使用して、VPC 間のトラフィックをルーティングできます。

VPC ピアリングは、VPC をピアリングする関係者間で高い信頼関係がある環境に適しています。これは、VPC ピアリング接続が確立された後、2 つの VPC が相互に広範囲にアクセスできるようになり、どちらの VPC のリソースでも接続を開始できるためです。セキュリティグループを使用したきめ細かなネットワークアクセス制御を実装し、到達可能である特定のリソースのみがピアリングされた VPC 間でアクセスできる必要があります。

CIDR が重複していない VPC 間でのみ VPC ピアリング接続を確立できます。異なる組織のアカウント間でピアリングするなど、重複する CIDR で VPC をピアリングする必要がある場合、これは問題となることがあります。

さらに、大規模で実行している場合には数百個の Amazon VPC が存在する可能性がありますが、VPC ピアリングは単一の Amazon VPC に対し 125 個のピアリング接続という制限があります。トランジットゲートウェイのようなネットワークハブを使用できます。これで拡張性が高くなり、数千個の Amazon VPC を接続できるようになりますが、VPC ピアリングと同様の双方向の信頼と重複しない CIDR が必要です。

対照的に AWS PrivateLink は、デフォルトではすべてのリソースではなく VPC 内の特定のリソースに対してきめ細かいネットワークアクセス制御ができるため、信頼度が低いモデルのアプローチを使用する環境により適しており、リスクを減らすことが可能です。次の図は、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスで実行しているサービスがあり、Network Load Balancer (NLB) が前面にあるサービスプロバイダー VPC を示しています。このサービスプロバイダーは、サービスプロバイダー VPC に NLB を指す VPC エンドポイントサービスと呼ばれる設定を作成します。このエンドポイントサービスは別の Amazon VPC (サービスコンシューマー VPC) と共有できます。これで、AWS PrivateLink が提供するインターフェイス VPC エンドポイントを使用してサービスに接続できます。サービスコンシューマーはこのインターフェイスエンドポイントを使用して、エンドアプリケーションまたはサービスに直接到達します。

AWS PrivateLink は、特定のネットワークリソースセットに対して開始する接続が単方向であることを確認します。接続はサービスコンシューマー VPC からのみ開始でき、サービスプロバイダー VPC へ流れ、逆には流れません。インターフェイスエンドポイントがサポートするネットワークリソース以外で、サービスプロバイダー VPC 内の他のリソースは公開されません。AWS PrivateLink では VPC CIDR 範囲を重複させることができ、数千個の Amazon VPC が各サービスを利用できるため、比較的うまくスケーリングできます。

したがって、VPC ピアリングと AWS PrivateLink はさまざまな信頼モデルとユースケースに適した 2 つの接続オプションといえます。

トランザクションバンキングのマイクロアカウント戦略

AWS アカウントは強力な分離境界で、デプロイと設定エラーが原因で発生する可能性のある問題に対して、アクセス制御と爆発半径の縮小のどちらも行います。この強力な分離が可能なのは、アカウントの境界を越えるフローを意図的かつ積極的に設定する必要があるためです。TxB は各システムを独自の AWS アカウントに移動する戦略を設計しました。それぞれのアカウントを TxB マイクロアカウントと呼んでいます。TxB ではこの戦略で、設定ミスから複数のシステムが公開される可能性を最小限に抑えることができています。TxB マイクロアカウントの詳細については、YouTube で「AWS re:Invent 2018: Policy Verification and Enforcement at Scale with AWS」の動画をご覧ください。

TxB マイクロアカウントのセグメンテーションにより実現した強力な利点をさらに補完するため、TxB はシステムのクロスアカウントとクロス VPC アクセスに AWS PrivateLink を選択しました。TxB サービスプロバイダーは AWS PrivateLink を使用することで、サービスをエンドポイントサービスとして公開し、ホワイトリストを使ってこれらのサービスへのインターフェースエンドポイントを作成できる他の AWS アカウントを明示的に設定できます。これにより、各サービスのアクセスパターンをきめ細かく制御することも可能です。エンドポイントサービスの定義では、NLB に接続しているリソースへのアクセスのみが許可されるため、アクセス全体の範囲を簡単に把握できます。サービスコンシューマーからサービスプロバイダーへ一方向で接続が開始されることで、すべての接続がポイントツーポイントで制御されます。 さらに AWS PrivateLink では、VPC の CIDR ブロックを TxB マイクロアカウント間で重複させることもできます。つまり AWS PrivateLink を使用すると、数千個の TxB マイクロアカウント VPC が必要に応じて各サービスを使用できるため、デフォルト設定の一部として将来起こる拡大に備えて TxB をセットアップできます。

AWS PrivateLink を使用した MSK ブローカーのアクセスパターン

TxB はマイクロアカウント戦略の一環として、独自の専用 AWS アカウントで MSK クラスターを実行します。このクラスターとやり取りするクライアントは、それぞれのマイクロアカウントに属しています。このセットアップと、アカウント間の接続に AWS PrivateLink を使用するための設定を考慮し、TxB はアカウント間のブローカーアクセス用の次の 2 つのパターンを評価しました。

パターン1: 各 MSK ブローカーを一意の専用インターフェイスエンドポイントで前面に配置する

このパターンでは、各 MSK ブローカーは MSK クラスターをホストしている TxB MSK アカウント内の一意の専用 NLB に向き合っています。TxB MSK アカウントにはすべての NLB のエンドポイントサービスが含まれており、クライアントアカウントと共有します。クライアントアカウントには、エンドポイントサービスに対応するインターフェースエンドポイントが含まれています。最後に、ブローカーの DNS 名と同一の DNS エントリは、それぞれのインターフェースのエンドポイントを指しています。次の図は、米国東部 (オハイオ) リージョンにおけるこのパターンを示しています。

高レベルのフロー

セットアップ後、自身のアカウントのクライアントはプロビジョニングされたデフォルトの DNS 名を使用して、ブローカーと次のように通信します。

  1. クライアントは、ブローカー DNS 名をクライアント VPC 内のインターフェースエンドポイント IP アドレスに解決します。
  2. クライアントはポート 9094 を介して、インターフェイスエンドポイント IP への TCP 接続を開始します。
  3. AWS PrivateLink テクノロジーを使うと、この TCP 接続は TxB MSK アカウント内の同じポートでリッスンするそれぞれのブローカーの専用 NLB セットアップにルーティングされます。
  4. NLB は、TCP ポート 9094 で背後に登録されている単一のブローカー IP への接続をルーティングします。

高レベルのセットアップ

このセクションでのセットアップの手順は、米国東部 (オハイオ) リージョン用です。別のリージョンを使用している場合は、変更してください。TxB MSK アカウントで、以下を実行します。

  1. ターゲットタイプを IP、プロトコル TCP、ポート 9094 とし、MSK クラスターと同じ VPC にターゲットグループを作成します
    • MSK ブローカーを IP アドレスでターゲットとして登録します
  2. TCPポート9094のリスナーを使用して NLB を作成し、前の手順で作成したターゲットグループに転送します。
    • 対応する MSK ブローカーと同じ AZ およびサブネットに対して、NLB を有効にします。
  3. このエンドポイントサービスへの接続を作成できるように、クライアントアカウントへの受け入れと許可を必要とする各 NLB のエンドポイントサービス設定を作成します

クライエントアカウントで、以下を実行します。

  1. クライアントと同じ VPC にインターフェースエンドポイントを作成します (この接続要求は TxB MSK アカウント内で受け入れられる必要があります)。
  2. Route 53 プライベートホストゾーンを作成し (ドメイン名 kafka.us-east-2.amazonaws.com)、クライアントと同じ VPC に関連付けます。
  3. ブローカーの DNS 名と同じ A- エイリアスレコードを作成して、TLS ハンドシェイクの失敗を回避し、それをそれぞれのブローカーのインターフェースエンドポイントにポイントします。

パターン2: すべての MSK ブローカーを単一の共有インターフェースエンドポイントで前面に配置する

この 2 つ目のパターンでは、クラスター内のすべてのブローカーを、ゾーン間負荷分散が有効になっている単一の固有の NLB で前面に配置します。各 MSK ブローカーの advertised.listeners 設定を変更して、一意のポートをアドバタイズすることで、これを行います。各ブローカーに一意の NLB リスナー – ターゲットグループのペアを、およびすべてのブローカーに単一の共有リスナー – ターゲットグループのペアを作成します。この単一 NLB 用のエンドポイントサービス設定を作成し、クライアントアカウントと共有します。クライアントアカウントで、エンドポイントサービスに対応するインターフェースエンドポイントを作成します。最後に、単一のインターフェースを指すブローカー DNS 名と同じ DNS エントリを作成します。次の図は、米国東部 (オハイオ) リージョンにおけるこのパターンを示しています。

高レベルのフロー

セットアップ後、自身のアカウントのクライアントはプロビジョニングされたデフォルトの DNS 名を使用して、ブローカーと次のように通信します。

  1. クライアントは、ブローカー DNS 名をクライアント VPC 内のインターフェースエンドポイント IP アドレスに解決します。
  2. クライアントはポート 9094 を介して、インターフェイスエンドポイントへの TCP 接続を開始します。
  3. ポート 9094 の TxB MSK アカウント内の NLB リスナーが、接続を受信します。
  4. NLB リスナーの対応ターゲットグループは、それに登録されているブローカーの 1 つ (ブローカー 1) へのリクエストの負荷を分散します。それに応じて、ブローカー 1 はアドバタイズされた DNS 名とポート (9001) をクライアントに送り返します。
  5. クライアントは、ブローカーエンドポイントアドレスを再度インターフェースエンドポイント IP に解決し、TCP ポート 9001 を介して同じインターフェースエンドポイントへの接続を開始します。
  6. この接続は、TCP ポート 9001 の NLB リスナーにルーティングされます。
  7. この NLB リスナーの対応ターゲットグループは、TCP ポート 9094 でトラフィックを受信するように設定され、同じポートでリクエストを唯一の登録済みターゲットであるブローカー 1 に転送します。

高レベルのセットアップ

このセクションでのセットアップの手順は、米国東部 (オハイオ) リージョン用です。別のリージョンを使用している場合は、変更してください。TxB MSK アカウントで、以下を実行します。

  1. 実行中の各ブローカーに対して次のコマンドを実行し、MSK ブローカーがアドバタイズしているポートを変更します。次のコマンド例は、特定のブローカー b-1 がアドバタイズしたポートを 9001 に変更している様子を示しています。以下のコマンドを実行するブローカーごとに、 bootstrap-serverentity-nameCLIENT_SECUREREPLICATIONREPLICATION_SECURE の値を変更する必要があります。REPLICATIONREPLICATION_SECURE の値を変更するときは、ブローカー名に -internal を追加する必要があることに注意してください。以下に示すポート 9093 と 9095 では値を変更しないでください。
    ./kafka-configs.sh \
    --bootstrap-server b-1.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9094 \
    --entity-type brokers \
    --entity-name 1 \
    --alter \
    --command-config kafka_2.12-2.2.1/bin/client.properties \
    --add-config advertised.listeners=[\
    CLIENT_SECURE://b-1.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9001,\
    REPLICATION://b-1-internal.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9093,\
    REPLICATION_SECURE://b-1-internal.exampleClusterName.abcde.c2.kafka.us-east-2.amazonaws.com:9095]
  2. ターゲットタイプを IP、プロトコル TCP、ポート 9094 とし、MSK クラスターと同じ VPC にターゲットグループを作成します。前の図は、これを B-ALL として表しています。
    • MSK ブローカーを IP アドレスでターゲットとして B-ALL登録します
  3. 各ブローカー専用のターゲットグループ (B1, B2) を、B-ALL と同じプロパティを使用して作成します。
    • それぞれの MSK ブローカーを IP アドレスで各ターゲットグループに登録します。
  4. 必要に応じて追加したブローカーに対して同じ手順を実行し、各ブローカーのアドバタイズされたポートに対応する一意のリスナー – ターゲットグループを作成します。
  5. MSK ブローカーが存在するのと同じサブネットに対して有効で、クロスゾーン負荷分散が有効になっているNLB を作成します
    • 作成した対応ターゲットグループ (B1B2) に転送するすべてのブローカーのアドバタイズされたポート (9001、9002) の TCP リスナーを作成します。
    • B-ALL ターゲットグループに転送する特別な TCP リスナー 9094 を作成します。
  6. このエンドポイントサービスへの接続を作成するには、承諾が必要な NLB のエンドポイントサービス設定を作成し、クライアントアカウントにアクセス許可を付与します。

クライエントアカウントで、以下を実行します。

  1. クライアントと同じ VPC にインターフェースエンドポイントを作成します (この接続要求は TxB MSK アカウント内で受け入れられる必要があります)。
  2. Route 53 プライベートホストゾーンを作成し (ドメイン名 kafka.us-east-2.amazonaws.com)、クライアントと同じ VPC に関連付けます。
  3. このホストゾーンで、ブローカーの DNS 名と同じ A- エイリアスレコードを作成して、TLS ハンドシェイクの失敗を回避し、それをインターフェースエンドポイントにポイントします。

この投稿では、これらのパターンの両方が TCP ポート 9094 で TLS を使用して MSK ブローカーと通信することを示しています。セキュリティー方針がクライアントとブローカー間のプレーンテキスト通信の使用を許可している場合、これらのパターンは TCP ポート 9092 を使用するシナリオにも適用できます。

これら両方のパターンでは、Amazon MSK がブローカーの障害を検出した場合、異常なブローカーを新しいブローカーに交換することで障害を低減します。さらに、新しい MSK ブローカーは同じ IP アドレスを保持し、変更された advertised.listener 設定など、同じ Kafka プロパティを持っています。

Amazon MSK では、クライアントは TCP ポート 9092、9094、2181 でサービスと通信できます。パターン 2 での advertised.listener の変更からの副産物として、クライアントはアドバタイズされたポートでブローカーと話すように自動的に要求されます。Amazon MSK と同じアカウントのクライアントがブローカーにアクセスする必要がある場合は、NLB DNS 名を指す同一のブローカー DNS 名で、Amazon MSK アカウントに新しい Route53 ホストゾーンを作成する必要があります。Route53 レコードセットは MSK ブローカー DNS を上書きして、ブローカーへのすべてのトラフィックが NLB を経由できるようにします。

トランザクションバンキングの MSK ブローカーアクセスパターン

TxB は TxB マイクロアカウントを介したブローカーアクセスにパターン 1 を選択しました。この場合、ブローカーごとに 1 つのインターフェースエンドポイントをクライアントアカウントに公開します。TxB は、手動での介入なしに、TxB MSK アカウント内のエンドポイントサービスとクライアントアカウント内のインターフェースエンドポイントの作成を自動化し、この全体的なプロセスを合理化しました。

クラスターの作成時に Amazon MSK API を呼び出すことでブートストラップブローカーの設定を取得し、クライアントアカウントの AWS Systems Manager パラメータストアに格納します。このため、ブートストラップブローカーの設定をアプリケーションの起動時に取得できます。これにより、クライアントは完全に異なるアカウントで起動している Kafka ブローカーの DNS 名を指定することがなくなります。

TxB がパターン 1 を選択した主な要因は、アドバタイズされたポートのようなブローカープロパティを変更する必要がないことです。パターン 2 では、TxB がどのブローカーがどのポートをアドバタイズしているかを追跡し、新しいブローカーが同じポートを再利用していないことを確認する必要が生じます。そのため、ライブで起動する新しいブローカーのアドバタイズされたポートを変更および追跡し、これらのブローカーに対応するリスナー – ターゲットグループのペアを作成する必要があるというオーバーヘッドが追加されます。TxB はパターン 1 を選択することにより、この追加のオーバーヘッドを回避したのです。

一方、パターン 1 ではより多くのブローカーをクラスターに追加する際に、追加の専用 NLB とインターフェースエンドポイント接続を作成する必要があります。TxB は自動化でこの管理オーバーヘッドを制限していますが、追加のエンジニアリング作業が必要となります。

また、クラスター内の各ブローカーには専用の NLB とインターフェイスエンドポイントがあるため、パターン 1 の使用ではパターン 2 に比べてコストが高くなります。単一のブローカーの場合、エンドツーエンドの接続インフラストラクチャの維持に月額 37.80 USD かかります。毎月の接続コストの内訳は、次のようになります。

  • NLB のランニングコスト – 1 NLB x 0.0225 USD x 720 時間/月=16.20 USD/月
  • 3 つの AZ にわたる 1 つの VPC エンドポイント – 1 VPCE x 3 ENI x 0.01 USD x 720時間/月= 21.60 USD/月

使用した NLB 容量と処理した AWS PrivateLink データに対する追加料金が適用されます。料金の詳細については、「Elastic Load Balancing 料金」と「AWS PrivateLink の料金」をご参照ください。

まとめると、パターン 1 は次の場合に最適です。

  • アドバタイズされたポートなどのブローカープロパティの変更に関連する管理オーバーヘッドを最小限に抑えたい場合
  • 新しいブローカーが作成または破棄されたときに、インフラストラクチャの追加と削除を自動で処理している場合
  • 主に簡単で均一なデプロイが目的で、二次的な懸念事項としてコストが伴う場合

Amazon MSK に対するトランザクションバンキングのセキュリティ要件

TxB マイクロアカウントは強力なアプリケーション分離境界を提供しており、パターン 1 の AWS PrivateLink を使用して MSK ブローカーにアクセスすることで、これらの TxB マイクロアカウント間の接続フローを厳密に制御することが可能となります。TxB では、Amazon MSK で利用できるインフラストラクチャとデータ保護コントロールを追加して、この基盤をさらに構築しています。詳細については、「Amazon Managed Streaming for Apache Kafka でのセキュリティ」をご参照ください。

TxB 内部のセキュリティチームが Amazon MSK を使用するために必要な中心的なセキュリティ原則は次のとおりです。

  • カスタマーマスターキー (CMK) を使用した保存時の暗号化 – TxB は 保管時の暗号化に Amazon MSK マネージドサービスを使用しています。Amazon MSK は AWS Key Management Service (AWS KMS) と統合し、透過的なサーバー側の暗号化を実行して、保存データを常に暗号化します。MSK クラスターを作成する際、AWS KMS が保存データを暗号化するデータキーの作成に使用する AWS KMS CMK を指定できます。詳細については、「CMK とデータキーの使用」をご覧ください。
  • 転送中の暗号化 – Amazon MSK では転送中の暗号化に TLS 1.2 を使用します。TxB は、クライアントブローカーの暗号化と MSK ブローカー間での暗号化を必須にしています。
  • TLS によるクライアント認証 – Amazon MSK は AWS Certificate Manager Private Certificate Authority (ACM PCA) をクライアント認証に使用しています。ACM PCA はルート認証機関 (CA) または下位 CA のいずれかです。ルート CA の場合、自己署名証明書をインストールする必要があります。下位 CA の場合、その親を ACM PCA ルート、下位 CA、または外部 CA として選択できます。この外部 CA は、証明書を発行し、ACM PCA 証明書としてインストールすると証明書チェーンの一部になる独自の CA にすることができます。TxB はこの機能を活用し、クライアントアカウントに配布する ACM PCA が署名した証明書を使用しています。
  • Kafka のアクセスコントロールリスト (ACLs) を使用した認証 – Amazon MSK では、クライアントの TLS 証明書の識別名を Kafka ACL のプリンシパルとして使用して、クライアントリクエストを認証できます。Kafka ACL を有効にするには、最初に TLS を使用したクライアント認証を有効にする必要があります。TxB は Kafka 管理 API を使用して、コンシューマーおよびプロデューサークライアントインスタンスにデプロイされた証明書の証明書名で、トピックごとに Kafka ACL を作成しています。詳細については、「Apache Kafka ACLs」をご参照ください。

まとめ

この投稿では、ゴールドマンサックスのトランザクションバンキングチームが TxB マイクロアカウント戦略を通じてアプリケーション分離境界にアプローチする方法と、AWS PrivateLink でこの戦略を補完する方法を説明しました。 加えてこの投稿では、TxB チームが TxB マイクロアカウント全体で MSK クラスターへの接続を構築する方法、および Amazon MSK がコアセキュリティ要件を達成できるようにすることで TxB から差別化につながらない手間のかかる作業を取り除く方法についても解説しました。この投稿を参考にして、Amazon MSK 環境を実装する際に同様のアプローチを構築できます。

 


著者について

Robert L. Cossin 氏はニューヨークのゴールドマンサックスのバイスプレジデントです。 2004 年にゴールドマンサックスに入社して以来、同社の現金および証券フローに関する多くのプロジェクトに参加してきました。近年はトランザクションバンキングチームのテクニカルアーキテクトとして活躍し、クラウドの有効化とセキュリティに取り組んでいます。

 

 

 

Harsha W. Sharma はニューヨーク在住の AWS ソリューションアーキテクトです。 2016 年に AWS に入社し、グローバルファイナンシャルサービスのお客様ととも AWS のアーキテクチャのデザインや開発に携わり、クラウドへの移行をサポートしています。