NTT DATA TECH
⛓️

VPC LatticeとPrivateLinkの基礎 - 実践で理解するトラフィックの流れと性能特性

に公開

はじめに

先日、AWS(Amazon Web Services) 主催の「AWS Application Networking Roadshow Japan 2025」というイベントに参加し、VPC LatticeについてDive Deepしました。

  • KeyNoteでAWSのNetworkingサービスの変遷から、今後VPC Latticeが担っていく役割について学び
  • SAさんのセッションではVPC LatticeとPrivateLinkの統合や
  • EKS、ECSのコンテナワークロードのコンポーネントをどうLatticeが担うかを学び
  • 午後はハンズオンで実際に手を動かす

といろいろな角度からVPC Latticeを学ぶことができ、非常に有意義なイベントでした。

参加前までなんとなくとっつきにくかったVPC Latticeの解像度が上がった気がするので、ラップアップを兼ねて執筆に至りました。

本記事の対象読者

  • VPC Latticeのトラフィックについて理解を深めたい方
  • VPC Latticeについてハンズオンベースで理解を深めたい方
  • VPC LatticeとPrivateLinkの統合について理解を深めたい方
  • VPCの関連付けとVPCエンドポイントの関連付けの使い分けについて迷っている方
  • VPC LatticeとPrivateLinkの使い分けについて迷っている方

😵‍💫個人的にとっつきにくかった理由

VPC Latticeの説明文を公式ドキュメントから引用してきました。

Amazon VPC Lattice は、アプリケーションのサービスとリソースの接続、保護、モニタリングに使用するフルマネージド型のアプリケーションネットワークサービスです。

https://docs.aws.amazon.com/ja_jp/vpc-lattice/latest/ug/what-is-vpc-lattice.html

フルマネージド型とは、利用者側での設定が少なく抽象化されたネットワークだと私は理解しています。これは「ネットワークは複雑でとっつきにくいもの」という開発者の認識に対するアピール文句でしょう。しかし私は「よしなにやってくれすぎていてよくわからない…」という印象を持っていました。

また、なんとなく「サービスメッシュを実現するサービスなんだよな~」という雑な理解にとどまっていて、特定のユースケースでしか利用する場面がないと勘違いしていました。

ということで今日はマネージドなネットワークを、可能な限りログやパケットを確認するなどしてできるだけ具体的に見て、VPC Lattice/PrivateLinkを理解していきたいと思います。

検証構成図

今回の検証で利用する環境の構成図について確認していきます。

Client-VPCは文字通り、接続を確立するクライアントが存在するVPCです。ここから、リソースを共有している各Provider-VPCに接続します。
続いて画面右上のOn-premises-VPCですが、オンプレミス環境からの接続を模擬するためのVPCです。実際のオンプレミス環境ではなく、AWS内でオンプレミスの状況を再現しています。


検証構成図

VPC Latticeの世界で見てみる

検証に入る前にVPC Latticeの主要コンポーネントをおさらいしつつ、先ほどの構成図をVPC Latticeの世界を考慮して見てみます。
まずは構成図です。VPC Latticeの概念を構成図上にマッピングしています。
あくまで理解を促すための図なので厳密には異なるかもしれません。


検証構成図(Latticeの世界)

VPC Lattice/PrivateLinkの基本的なコンポーネントについて

上記のVPC Latticeの世界に登場する基本的なコンポーネントについては、参考になる記事が溢れているため、本記事では改めて説明はしません。
AWS Black Belt Online Seminarの「PrivateLink and Lattice – Amazon VPC Lattice Service 編」がわかりやすいので是非参考にしてみてください。Lattice登場の背景含めよくまとまっているのですべて読むことをお勧めしますが、基本的なコンポーネントの理解だけであればp18~p29を確認するのがよいです。

環境構築

本章では検証用の環境を構築します。
VPC LatticeやPrivateLinkをマネコンで構築していくことで、コンポーネントの設定について理解を深めていきます。(慣れないサービスはマネコンで構築するほうが頭に入ってくる派の人間なので。)

なお、上記以外のリソースはterraformで定義しています。
ハンズオン形式で理解したい方は、以下のterraformでVPCやECS等を構築した後、この章を使って実際に構築しながら読んでいただければと思います。
https://github.com/Omanju23/zenn-lattice

逆にある程度LatticeやPrivateLinkについて構築経験がある方は本章を読み飛ばしていただいて構いません。

環境構築(Lattice)

まずはVPC Lattice関連のコンポーネントを構築していきます。
この章の構築が終わると、VPC Latticeのサービスネットワーク経由でECSとLambdaにアクセスできるようになります。

ターゲットグループの作成

ELBと同じく、まずはターゲットグループから作成します。
今回は2つのルールによってECSとLambdaに振り分けるので、それぞれのターゲットグループを作成します。

Lambda用ターゲットグループの作成

ターゲットタイプをLambdaにして、ターゲットグループ名を入力

terraformで構築済みのLambda関数をプルダウンから選択し、作成

ECS用ターゲットグループの作成

Latticeに接続したいクラスターにアクセスし、接続するサービスを選択し、「更新」をクリックします。

VPC Latticeオプションを展開し、「VPC Latticeを使う」を選択。
ロールを選択し、ターゲットグループ、ポート名、プロトコル、ポートを指定して画面下部の「更新」をクリックします。

サービス/リスナー/ルールの作成

続いてサービスとリスナーを作成します。
パスベースのルールによってECSとLambdaを使い分けるため、1つのサービス、1つのリスナーに2つのルールを作成します。

サービス/リスナー/ルールの作成

VPCコンソールから、Latticeサービスの作成を開始します。
サービス名を入力して「次へ」をクリックします。(今回は後続でログを確認するので、CloudWatch ロググループへの配信設定を行っています。)

続いて、リスナーを作成します。
「リスナーの追加」をクリックします。
ポートを入力し、デフォルトアクションに先ほど作成したECS用のターゲットグループを指定します。

次にLambdaに転送するためのルールを追加します。
画面中央の「ルールを追加する」をクリックし、ルール名やルール条件、ルールアクションを指定します。
今回は/lambdaの場合、lambda-tgに転送するように設定します。

サービスネットワークへの関連付けは後程実施しますのでそのまま作成してください。

サービスネットワークの作成

続いてサービスネットワークの作成です。

サービスネットワークの作成とサービス関連付け

サービスネットワーク名を入力し、先ほど作成したサービスを関連付けます。
関連付けたサービスに対して、サービスネットワーク経由でアクセスできるようになります。

下にスクロールし、VPCへ関連付けを行います。
今回はvpc-lattice-clientを選択し、「サービスネットワークを作成」をクリックします。

サービスネットワークエンドポイント(SNE)の作成

最後にサービスネットワークエンドポイントを作成します。
結局はVPCエンドポイントを作るだけなので、皆さん慣れ親しんでいると思います。
タイプを「サービスネットワーク」にし、エンドポイントからアクセスするサービスネットワークを指定する以外は、インターフェース型エンドポイントを作る要領で進めることができます。

サービスネットワークエンドポイントの作成

タイプ、関連付けるサービスネットワークを指定し、
エンドポイントをデプロイするVPCの情報を指定して、エンドポイントを作成します。

環境構築(PrivateLink)

続いてPrivateLink経由のVPCリソース(RDS)アクセスを検証するための環境構築を実施します。

リソースゲートウェイの構築

アクセス対象のRDSと同じVPCにリソースゲートウェイを構築します。
このリソースゲートウェイからRDSにアクセスします。

リソースゲートウェイの構築

VPCコンソールの「リソースゲートウェイ」から「リソースゲートウェイを作成」をクリックします。

リソースゲートウェイ名を入力、共有対象のリソースがあるVPCを選択、リソースゲートウェイ用のENIをデプロイするサブネットと関連付けるSGを選択し、「リソースゲートウェイを作成」をクリックします。

リソース設定の構築

続いてリソース設定を構築します。
リソース設定ではPrivateLink経由でアクセスするリソースを指定します。

リソース設定の作成

作成したリソースゲートウェイの画面から「リソース設定を作成」をクリックします。

リソース設定名と設定タイプを入力します。
今回はARNで接続するのでARNリソース定義で、プルダウンから共有するRDSを選択します。
必要な項目の入力が終わったら「リソース設定を作成」をクリックします。

サービスネットワークへの関連付け

最後にリソース設定をサービスネットワークへ関連付けします。
PrivateLink単体だと、リソース型のVPCエンドポイントを利用してPrivateLinkに接続しますが、Latticeと組み合わせると不要になります。
これによりSNEやVPC関連づけされたVPC経由で、PrivateLinkリソースにアクセスできるようになります。

サービスネットワークへの関連付け

リソース設定画面からサービスネットワークの関連付けをクリック。

関連付けるVPC Latticeサービスネットワークを選択し、「変更内容の保存」をクリック。

以上で検証環境の構築は完了です!
早速検証に入っていきます。

検証

本記事では2つの観点について検証していきます。
まずは、VPC LatticeやPrivateLinkの1.抽象化されたネットワークを理解するために、ステップバイステップでトラフィックを確認します。
次に2.VPC Latticeの特徴であるオブザーバビリティに着目して検証します。VPC Latticeはアプリケーション開発者向けにテレメトリーデータを取得できることをうたっていますが、実装の裏にはパケットに対して追加の情報が付与されていることが想定されます。パケットの中身を確認しつつ、追加情報付与によりレイテンシに違いがあるのか検証していきます。

トラフィックの流れ

それでは実際にトラフィックを検証していきます。
サービスネットワークへアクセスするための2つの方式(VPC関連付けとVPCエンドポイント(SNE)関連付け)と、PrivateLinkによるアクセスを確認します。

VPC関連付けによるサービスネットワーク接続

いよいよ本題です。まずはVPC関連付けから検証していきます。
先の説明の通り、VPC関連付けによってサービスネットワークに接続する際は、サービス割り当てられたDNS名を利用してアクセスします。

早速、Client-VPCにデプロイしたCloudShellから疎通確認を行います。
下のスクショから無事にECSやLambdaにアクセスできていることが確認できます。

クライアントからサービスネットワークまで

まずはクライアントからLatticeのサービスネットワークまでを見ていきます。

名前解決

まずは名前解決によってどのようなIPが解決されているのかを確認します。
Client-VPCのRoute53 クエリログを見てみると、「169.254.171.1」というリンクローカルアドレスが返却されています。
AWSにおいてリンクローカルアドレスは、インスタンスメタデータやRoute53 Resolver、Amazon Time Sync Service等のサービスで利用されています。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-instance-addressing.html#link-local-addresses

このリンクローカルアドレスを利用して、マネージドなサービスネットワークにアクセスしているということですね。

クエリログ抜粋
{
    "version": "1.100000",
    "vpc_id": "vpc-0b458dd7bf5d9075c",
    "query_name": "service-032c32a4127a4037f.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws.", // LatticeサービスのDNS名
    "query_type": "A",
    "query_class": "IN",
    "rcode": "NOERROR",
    "answers": [
        {
            "Rdata": "169.254.171.1", // リンクローカルアドレスが返却
            "Type": "A",
            "Class": "IN"
        }
    ],
    "srcaddr": "10.0.25.81", // CloudShellのIP
}
VPCフローログ

次に名前解決後に発生したトラフィックをVPCフローログから確認します。
先ほど解決したIPアドレスの443ポート宛にトラフィックが飛んでいることがわかります。

VPCフローログ
2 123456789012 eni-0709baef2eed309e3 10.0.9.251 169.254.171.97 44348 443 6 11 1422 1745069545 1745069545 ACCEPT OK
2 123456789012 eni-0709baef2eed309e3 169.254.171.97 10.0.9.251 443 44348 6 9 5723 1745069545 1745069545 ACCEPT OK

ルートテーブルを見るといくつかサービスネットワークへのルート定義が入っていることがわかります。
今回は「169.254.171.0/24」のルートに従ってトラフィックが転送されています。

サービスネットワーク内部

次にサービスネットワーク内でどのようなトラフィックが発生しているのか確認していきます。

Lattice サービスネットワークログ

サービスネットワークのログを確認してみます。
userAgentの内容やパス、メソッド、Latticeの情報等、様々な情報が確認できます。

サービスネットワークログ 抜粋
{
    "serviceNetworkArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:servicenetwork/sn-0f57c15c43e9a2dd0",
    "targetGroupArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-03164ee7761afeb61",
    "sourceVpcArn": "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0ec5b64fb61968dce",
    "destinationVpcId": "vpc-00d6af11b0a16dfd6",
    "sourceIpPort": "10.0.9.251:44348",
    "listenerId": "-",
    "targetIpPort": "10.1.20.172:80",
    "failureReason": "-",
    "serviceArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-065c2804e0660ceb2",
    "sourceVpcId": "vpc-0ec5b64fb61968dce",
    "startTime": "2025-04-19T13:32:15Z",
    "requestMethod": "GET",
    "requestPath": "/",
    "protocol": "HTTP/2",
    "responseCode": 200,
    "userAgent": "curl/8.5.0",
    "hostHeader": "ecs-service-065c2804e0660ceb2.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
    "serverNameIndication": "ecs-service-065c2804e0660ceb2.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
}

サービスネットワークからECSまで

最後にサービスネットワークからECSに到達する部分について確認します。

VPC フローログ(Provider-VPC-Lattice)

まずはVPCフローログを確認します。
「169.254.171.195」から、「10.1.9.21」の80番ポート宛のトラフィックが確認できます。
「10.1.9.21」はECSタスクのIPで、「169.254.171.195」はサービスネットワークのIPです。


VPCフローログ

サービスがデプロイされているVPCにもLattice用のルートがルートテーブルに追加されています。

ECS ログ

最後にECSのログを確認します。形式はapache common log formatです。
送信元は「169.254.171.195」が記録されており、VPC フローログのIPと同一であることがわかります。
加えて一番最後のX-Forwarded-ForフィールドにCloudShellのIPである10.0.25.81」が記録されています。
送信元のIPアドレスがわかるのは嬉しいですね。

169.254.171.195 - - [20/Apr/2025:06:34:42 +0000] "GET / HTTP/1.1" 200 633 "-" "curl/8.5.0" "10.0.25.81"

VPC関連付け トラフィックの流れ

ここまでのトラフィックの流れを構成図上にマッピングして整理します。

サービスネットワークエンドポイント(SNE)によるサービスネットワーク接続

続いてサービスネットワークエンドポイントを検証していきます。
せっかくなのでSNEの特徴であるVPC外からの接続を検証するため、onprem-vpcから接続してみましょう。

SNEで接続する場合は、SNEに関連付けられたDNS名を利用します。
リソース設定およびサービスごとにDNS名とENIが払い出されます。
レコードはパブリックなので、インターネット経由で名前解決できます。
インターフェースエンドポイントのようにRoute53のPrivate Hosted Zoneを作って関連付けして…という手間はありませんね。

これらの DNS レコードはパブリックです。したがって、これらの DNS 名はパブリックに解決可能です。ただし、VPC の外部からの DNS リクエストは、引き続きサービスネットワークエンドポイントのネットワークインターフェイスのプライベート IP アドレスを返します。これらの DNS 名を使用して、VPN または Direct Connect を介して、サービスネットワークエンドポイントがある VPC にアクセスできる限り、オンプレミスからリソースとサービスにアクセスできます。

https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/privatelink-access-service-networks.html#sn-endpoint-dns-resolution

では早速、ECSとLambdaにアクセスしてみます。
問題なく接続できました。

クライアントからサービスネットワークまで

まずはクライアントからサービスネットワークまでを確認していきます。

名前解決(サービスネットワークエンドポイント)

まずは名前解決によってどのようなIPが解決されているのかを確認します。
Onprem-VPCのRoute53 クエリログを見てみると、「10.0.16.65」が返却されています。
これはClient-VPCにデプロイしているSNEのIPアドレスです。

クエリログ抜粋
{
    "vpc_id": "vpc-0a61565de22cc37cc",
    "query_name": "vpce-05ad5f2ec114ea619-snsa-0ba0007edef60de13.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws.", // SNEのDNS名
    "query_type": "A",
    "query_class": "IN",
    "rcode": "NOERROR",
    "answers": [
        {
            "Rdata": "10.0.16.65", // Client-VPCにデプロイしているSNEのIPアドレスが返却
            "Type": "A",
            "Class": "IN"
        }
    ],
    "srcaddr": "10.2.24.184", // CloudShellのIP
}

サービスネットワーク内トラフィック

サービスネットワークのログを確認しましたが、VPC関連付けと大きな差がなかったので割愛します。

サービスネットワークログ
サービスネットワークログ
{
    "serviceNetworkArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:servicenetwork/sn-0409e88e4d8f62a59",
    "resolvedUser": "-",
    "listenerType": "-",
    "authDeniedReason": "-",
    "targetGroupArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-09f3c3323b2e0f9ae",
    "sourceVpcArn": "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0b458dd7bf5d9075c",
    "destinationVpcId": "vpc-098b287af1374eec5",
    "sourceIpPort": "10.2.24.184:43310",
    "listenerId": "-",
    "targetIpPort": "10.1.9.21:80",
    "failureReason": "-",
    "serviceArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-032c32a4127a4037f",
    "sourceVpcId": "vpc-0b458dd7bf5d9075c",
    "startTime": "2025-04-20T12:05:09Z",
    "requestMethod": "GET",
    "requestPath": "/",
    "protocol": "HTTP/2",
    "responseCode": 200,
    "bytesReceived": 177,
    "bytesSent": 1335,
    "duration": 5,
    "userAgent": "curl/8.5.0",
    "hostHeader": "vpce-05ad5f2ec114ea619-snsa-0ba0007edef60de13.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
    "serverNameIndication": "vpce-05ad5f2ec114ea619-snsa-0ba0007edef60de13.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
    "requestToTargetDuration": 3,
    "responseFromTargetDuration": 0,
    "sslCipher": "TLS_AES_256_GCM_SHA384",
    "tlsVersion": "TLSv1.3",
    "callerPrincipal": "-",
    "callerPrincipalOrgID": "-",
    "callerX509IssuerOU": "-",
    "callerX509SubjectCN": "-",
    "callerX509SANNameCN": "-",
    "callerX509SANDNS": "-",
    "callerX509SANURI": "-"
}

サービスネットワークからECSまで

最後にサービスネットワークからECSに到達する部分についてもVPC関連付けと目立った差分がなかったので割愛します。
こちらもクライアントのIPアドレスをターゲットで確認することができました。

169.254.171.195 - - [20/Apr/2025:12:04:51 +0000] "GET / HTTP/1.1" 200 633 "-" "curl/8.5.0" "10.2.24.184"

SNE関連付け トラフィックの流れ

SNE関連付けのトラフィックの流れを構成図上にマッピングして整理します。


次にPrivateLink経由でVPCリソース(RDS)に接続してみます。
今回はLatticeとの統合を紹介するために、リソース設定をサービスネットワークに関連付けし、払い出されたDNSエントリを使って接続します。

Client-VPCにデプロイしたCloudShellから疎通確認を行います。
下のスクショから無事にRDSにアクセスできていることが確認できます。

Client-VPCからリソースVPCエンドポイントまで

まずはクライアントからLatticeのサービスネットワークまでを見ていきます。

名前解決

名前解決によってどのようなIPが解決されているのかを確認します。
Client-VPCのRoute53 クエリログを見てみると、「129.224.24.10」というアドレスが返却されています。

クエリログ抜粋
{
    "version": "1.100000",
    "region": "ap-northeast-1",
    "vpc_id": "vpc-066df44e0efdf7c22",
    "query_timestamp": "2025-04-29T07:07:09Z",
    "query_name": "snra-030159be275b114c6.rcfg-0f8a271670339db06.4232ccc.vpc-lattice-rsc.ap-northeast-1.on.aws.",
    "query_type": "A",
    "query_class": "IN",
    "rcode": "NOERROR",
    "answers": [
        {
            "Rdata": "129.224.24.10",
            "Type": "A",
            "Class": "IN"
        }
    ],
    "srcaddr": "10.0.25.212",
    "srcport": "34762",
    "transport": "UDP",
    "srcids": {
        "instance": "i-09c41b80898489401"
    }
}

このIPアドレスはAWSが所有しているIPだそうで、PrivateLinkがサービスネットワーク関連付けを使用する場合に利用されるIPアドレスとのことです。

サービスネットワーク関連付けを使用する場合、各リソースには、 AWS 所有およびルーティング不可の 129.224.0.0/17 ブロックからサブネットごとに IP が割り当てられます。これは、VPC Lattice が VPC Lattice ネットワーク経由でトラフィックを サービスにルーティングするために使用するマネージドプレフィックスリストに追加されます。これらの IPs の両方が VPC ルートテーブルに更新されます。

https://docs.aws.amazon.com/ja_jp/vpc-lattice/latest/ug/resource-configuration.html

VPCフローログ(Client-VPC)

名前解決したIPアドレス宛ての通信が確認できました。

先ほど紹介したCIDRブロックに対するルートもルートテーブルに挿入されており、このルートに従ってルーティングしています。

サービスネットワーク-PrivateLinkトラフィック

次にサービスネットワークを経由してPrivateLinkに接続する部分を確認します。

リソースログ

リソース設定から出力するログを確認してみます。
VPC Latticeのログと比べると出力されている情報が少ないですね。クライアントのIP情報も記録されていないことがわかります。

リソースログ
{
    "eventTimestamp": "2025-04-29T07:07:14.879Z",
    "serviceNetworkArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:servicenetwork/sn-0d36964b131b9ffbb",
    "serviceNetworkResourceAssociationId": "snra-08271c862edd49029",
    "sourceVpcArn": "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-066df44e0efdf7c22",
    "resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-1:123456789012:resourceconfiguration/rcfg-06734c4846042cef4",
    "protocol": "tcp",
    "sourceIpPort": "10.0.25.212:38916",
    "destinationIpPort": "129.224.24.10:5432",
    "gatewayIpPort": "10.0.27.194:59522",
    "resourceIpPort": "10.0.23.174:5432"
}

PrivateLinkからRDSまで

PrivateLinkからRDSまでの接続を確認します。

リソースゲートウェイのIP

リソースゲートウェイは各AZにデプロイされたENIから構成されます。

VPCフローログ

リソース共有によるトラフィックはリソースゲートウェイから、リソースに向かって送信されます。
先ほど確認したリソースゲートウェイのIPが送信元になっているトラフィックが確認できました。

ここまでのトラフィックの流れを構成図上にマッピングして整理します。


パケット/レイテンシ関連の検証

続いてパケットとレイテンシ関連の検証を行っていきます。
先にもお伝えした通り、VPC Latticeはオブザーバビリティ向上のためにパケットに情報が付加されます。
https://docs.aws.amazon.com/ja_jp/vpc-lattice/latest/ug/http-targets.html

「そのためPrivateLinkと比較して、レイテンシが増大するのでは?」と仮説を立てています。
また、サービスネットワークへのアクセス方法(VPC関連付けとSNE関連付け)によってもレイテンシが変わるのか気になったので確認していきます。

検証条件

検証条件をそろえるために、PrivateLinkの宛先もECSに変更します。
また、プロトコルもHTTPに揃えます。(VPC LatticeのリスナーをHTTPに変更)
ヘッダ情報を確認するために、ECS上で動作させるイメージも差し替えます。先ほどまでは単純なhtmlの表示にとどまっていましたが、JSを動作させてリクエストヘッダをすべて返却するように修正します。

以下の4方式に対して、1000回ずつcurlを実行し、各種時間を計測します。
今回は単純な検証目的のため、1000回のリクエストは完全にシリアルに送ります。

  1. VPC Lattice(VPC関連付け)
  2. VPC Lattice(SNE)
  3. PrivateLink(VPC関連付け)
  4. PrivateLink(SNE)
curlコマンド
curl -s -o /dev/null -w "%{http_code},%{time_connect},%{time_starttransfer},%{time_total}" "$endpoint"

パケットの確認

最初にパケットに追加情報が付加されているのか確認します。
まずはPrivateLinkから確認します。
シンプルなパケットです。送信元のIPアドレスも保持していないですね。

PrivateLink
{
  "message": "Hello from ECS in VPC Lattice demo!",
  "timestamp": "2025-04-28T14:51:55.726Z",
  "headers": {
    "host": "snra-064aa88a2ecad5c82.rcfg-023df193b6168b654.4232ccc.vpc-lattice-rsc.ap-northeast-1.on.aws",
    "user-agent": "curl/8.5.0",
    "accept": "*/*"
  }
}

次にLatticeのパケットを確認します。

Lattice
{
  "message": "Hello from ECS in VPC Lattice demo!",
  "timestamp": "2025-04-28T14:48:50.812Z",
  "headers": {
    "host": "service-0663557ef270828d0.7d67968.vpc-lattice-svcs.ap-northeast-1.on.aws",
    "user-agent": "curl/8.5.0",
    "accept": "*/*",
    "x-forwarded-for": "10.0.24.152",
    "x-amzn-lattice-network": "SourceVpcArn=arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-066df44e0efdf7c22",
    "x-amzn-lattice-target": "ServiceArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-0663557ef270828d0; ServiceNetworkArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:servicenetwork/sn-0d36964b131b9ffbb; TargetGroupArn=arn:aws:vpc-lattice:ap-northeast-1:123456789012:targetgroup/tg-094d8da0ef0fa2f6f",
    "x-amzn-source-vpc": "vpc-066df44e0efdf7c22",
    "x-amzn-tls-version": "TLSv1.3",
    "x-amzn-tls-cipher-suite": "TLS_AES_256_GCM_SHA384"
  }
}

「x-forwarded-for」や「x-amzn-」ヘッダが追加されていることがわかります。

レイテンシ検証結果

続いてレイテンシの検証です。

以下の表は、1000回のリクエストに対する各接続方式の応答時間を比較したものです。平均応答時間は全リクエストの平均値、標準偏差はばらつきの大きさを示しています。
表からもわかるように全体的にPrivateLinkのほうが高速そうです。
標準偏差も小さく、どの方式もある程度一貫した応答時間であることが見て取れます。

サービス 平均応答時間 標準偏差 95%信頼区間
PrivateLink VPC 7.87 ms 1.43 ms [7.78, 7.96]
Lattice VPC 8.93 ms 1.72 ms [8.82, 9.03]
PrivateLink SNE 7.88 ms 1.73 ms [7.78, 7.99]
Lattice SNE 8.83 ms 1.52 ms [8.73, 8.92]

有意差検証

次に方式ごとに統計的に有意な差が出ているのか確認してみました。
VPC LatticeとPrivateLinkの比較は仮説通り、PrivateLinkの方が有意に高速(約12-13%)なようです。
とはいえその差は1msと小さく、多くのユースケースでは問題にならない程度ではないでしょうか。
一方で、VPC関連付けとSNE関連付けに関しては有意な差はないようです。

比較 差異 p値 有意差 速い方
PrivateLink VPC vs Lattice VPC 1.06 ms (13.5%) <0.0001 あり PrivateLink VPC
PrivateLink SNE vs Lattice SNE 0.94 ms (11.9%) <0.0001 あり PrivateLink SNE
PrivateLink VPC vs PrivateLink SNE 0.01 ms (0.1%) 0.8073 なし -
Lattice VPC vs Lattice SNE 0.10 ms (1.1%) 0.1606 なし -

HTTP通信プロセスの各ステップの時間比較

最後にHTTP通信プロセスの各ステップの処理時間比較です。
こちらはVPC Latticeは接続の確立は高速でサーバ処理時間やデータ転送時間はPrivateLinkの方が高速です。

接続確立時間VPC Lattice(約2.0-2.1ms)はPrivateLink(約4.9ms)の半分以下の時間で接続を確立しています。
サーバー処理時間: 逆に、VPC Lattice(約6.4-6.5ms)はPrivateLink(約2.9ms)の2倍以上の処理時間を要しています。
データ転送時間VPC Lattice(約0.34ms)はPrivateLink(約0.08ms)の4倍以上の時間を要しています。

VPC Latticeの接続確立の高速化(約2.8ms改善)よりも、サーバー処理とデータ転送の遅延(約3.9ms悪化)の方が大きいため、トータルではPrivateLinkが速い結果となっています。
内部構造がわからないため断定はできませんが、当初仮説通りVPC Latticeのヘッダ追加が少し響いているのかもしれません。

考察とまとめ

検証した結果を基に考察していきます。

VPC関連付けとSNEの使い分け

今回検証した限りは、CIDR範囲に余裕がある限りは機能性が高いSNE方式を採用するほうがよさそうです。
CIDRに余裕がない場合でも、VPCを新設してSNE型を採用するという考え方もアリかなと思います。

SNEの優位性

  • VPC外からのアクセスが可能
  • 複数のサービスネットワークにアクセス可能
  • VPC関連付けと比較して性能に有意な差はない
  • Interface型エンドポイントのように追加コストも不要

VPC LatticeとPrivateLinkの使い分け

一方、VPC LatticeとPrivateLinkは用途によって使い分けをするのがよさそうです。

VPC Latticeを使うケース

  • IAM認証をかけたいケース
  • ヘッダやパスベースなどの高度なルーティングや負荷分散が必要なケース
  • 大量の短期接続を行うケース(接続確立が速いため)
  • オブザーバビリティを重要視するケース(取得できるテレメトリが多いため)

PrivateLinkを使うケース

  • RDSとの通信など、Latticeでは対応できない通信要件があるケース
  • レイテンシに厳しい要件があるケース(Latticeより高速なため)
  • リソースグループを利用したリソースの階層化を行いたいケース

まとめ

個人的にとっつきにくかったVPC Latticeを触ってみました。
実際に構築したり、仮説を立てて検証していく中で、思った以上に簡単に接続性を担保できることや、サービスメッシュだけでなく、幅広いワークロードで活用できるサービスであることがわかりました。
Transit Gatewayとの並行運用や移行もできるとのことなので、通信要件やコスト如何によっては今後乗り換えが進むかもしれません。この辺りも今後検証していきたいなと思います。

NTT DATA TECH
NTT DATA TECH

Discussion