【ハンズオン風】AWS Privatelinkを使って異なるVPCのEC2上で動くサービスに接続しよう

記事タイトルとURLをコピーする

サーバーワークスアドベントカレンダー2024 12月04日の記事です! ぜひ、他の記事も見てみてください! qiita.com

概要

この記事では、「AWS Privatelinkを使用して、異なるVPC/AZに構築されたEC2上で稼働するWebページにプライベート接続する方法」をハンズオン風に紹介します。

注意:
ハンズオン"風"であるのは、詳細な設定パラメータは省くためです。 また、Privatelinkを設定時に学んだ 4つのポイント も紹介します。 最後に、到達性確認に「Reachability Analyzer」を使用したのでその使い方も紹介しています。

【本記事でわかること】

  • PrivateLinkを用いたVPC間通信の設定方法
  • Reachability Analyzerを用いた接続確認とトラブルシューティング

はじめに

こんにちは!CS部CS1課の圡井です。 白菜がお手ごろになってきて鍋活がはかどっています。

最近Privatelink環境を構築することがあり、その際に検証した基本の構成をハンズオン風の記事にしたいと思います。 構築する際に驚いた/学びになった3つのポイントも盛り込みます。

本編

ハンズオンの構成図

それでは構築していきましょう!

今回作成するネットワークの構成図は図1のようになります。 左側のVPCを「サービス利用側VPC」、右側を「サービス提供側VPC」とします。 図1内の赤線が今回の主題となるサービス間のプライベート通信経路です。

(図1)全体の構成図

ポイントその①:Privatelinkの正体

さっそく1つ目のポイントです。 実際に着手して驚いたのは 「Privatelinkはサービスではなかった!」 ということです。 よく一口に「Privatelink」という名前で呼ばれているため、てっきりそのようなサービスがあるものだと思っていました。 しかし実際は、「VPC間のPrivate通信を許可する設定および構成」のことを指しています。 同じようにVPC間通信を行うVPC Peeringと異なるのは、「特定の通信のみを許可できる」ということです。 より細かな説明はポイントその②で説明します。

気を取り直して、構築を進めていきましょう。

VPCを構築する

VPCコンソールからVPCを構築していきます。

VPCの設定項目でVPCなどを選択することで自動的にサブネットも構築されます。

以下の要点に沿って構築します。

リソース・サービス 設定・要点
VPC
(privatelink-A-vpc)
サービス利用側のVPCです。
Availability Zone-A/CにPublic/Privateサブネットを作成します。
NATゲートウェイを1つ作成します。
VPC
(privatelink-B-vpc)
サービス提供側のVPCです。
Availability Zone-A/CにPublic/Privateサブネットを作成します。
NATゲートウェイを1つ作成します。

EC2を構築する

サービスに利用するEC2-A、サービスを提供するEC2-Bを構築します。 合わせて必要なSecurity Group(SG), IAMロールも作成します。

以下のパラメータで構築します。

リソース・サービス 設定・要点
Security Group
(EC2-A-sg)
サービス利用側EC2(EC2-A)のSGです。
インバウントルールは後ほど設定します。
Security Group
(EC2-B-sg)
サービス提供側EC2(EC2-B)のSGです。
インバウントルールは後ほど設定します。
IAMロール
(SSM-role)
EC2にSSM接続をするためのIAM Roleです。
AmazonSSMManagedInstanceCoreポリシーをアタッチします。
EC2
(EC2-A)
サービス利用側のEC2です。
上記で作成したSG, IAM Roleをアタッチします。
AZ-a側のPrivate Subnetに配置します。
EC2
(EC2-B)
サービス提供側のEC2です。
上記で作成したSG, IAM Roleをアタッチします。
AZ-c側のPrivate Subnetに配置します。

(図2)VPCの構築

Webサービスの設定

EC2-Bで提供するサービスを設定します。 今回はWebサービスを提供するようにします。

EC2-BにSSMでログインします。 以下のコマンドを利用して、Webサービスインストール・起動します。

# Apacheのインストール
sudo dnf install httpd

# ページを作成
sudo touch /var/www/html/index.html

# 好きなメッセージを書き込む(今回は "Hello!")
sudo vi /var/www/html/index.html

# 動作確認(上のコマンドで入力したメッセージが表示されればOK)
curl http://localhost:80
> Hello!

NLBを構築する

エンドポイントサービスとして提供するためのNetwork Load Balancer(NLB)を構築します。 合わせてNetwork Load Balancerで利用する、SG, Target Group(TG)を作成します。

以下のパラメータで構築します。

リソース・サービス 設定・要点
Security Group
(NLB-B-sg)
NLB(NLB-B)のSGです。
インバウントルールは後ほど設定します。
Target Group
(NLB-B-tg)
NLBからEC2に接続するためのTGです。
TCP:80にルーティングを行い、ヘルスチェックパスは/index.htmlとします。
EC2(EC2-B)をターゲットとして追加します。
Network Load Balancer
(NLB-B)
PrivateLinkとしてサービスを提供するためのNLBです。
内部向けのNLBとして構築します。privatelink-B-vpcのAvailability Zone-A/Cにマッピングし、上記のSGをアタッチします。
TCP:80番のリスナーに上記TGをアタッチします。

ここであるミスに気づく方もいらっしゃるかと思いますが、 いったんここではスルーします。 詳細はポイント③④で!

(図3)NLBの構築

NLBからEC2への接続許可をする

NLB(NLB-B)からEC2(EC2-B)に通信するために、SG(EC2-B-sg)のインバウントルールを編集します。

リソース・サービス 設定・要点
Security Group
(EC2-B-sg)
EC2(EC2-B)のSGです。
HTTP(TCP: 80)に対し、NLBのSG(NLB-B-sg)の通信を許可します。

NLB(NLB-B)画面のリソースマップタブより、ヘルスチェック

エンドポイントサービス / エンドポイントを構築する

ポイントその②:エンドポイントとエンドポイントサービスの違いとは

VPCコンソールの左に鎮座する「エンドポイント」と「エンドポイントサービス」。 実際に触ってみるまで、どう違うのか意識していませんでした。

「エンドポイント」はインターネットを経由するAWSサービスに接続する場合の接続口を作成できます。 たとえば、インターネットに接続できないサブネットにエンドポイントを作成することで、 S3やSecrets Managerなどのインターネットを経由するサービスに接続できます。 また、AWSのネットワーク内を経由するため、安全に接続することができます。

対して「エンドポイントサービス」は、AWSサービスだけでなく 独自に構築したサービスをエンドポイントを通じて提供できる 機能です。 「エンドポイントサービス」に設定したサービスは「エンドポイント」を作成でき、異なるVPC間でプライベートな接続が作成できます。

この仕組みを「Privatelink」とよびます。

エンドポイントサービスとしてサービス提供側VPCに構築したNLBを割り当てます。 この設定により、EC2-Bに設定したWebページがNLB経由でエンドポイントから接続できるようになります。

リソース・サービス 設定・要点
VPC Endpoint Service
(privatelink-B-vpces)
Privatelinkを構成するサービスです。
サービス提供側VPCに構築したNLB(NLB-B)をアタッチします。
サポートされいているIPアドレスタイプにはIPv4を設定します。

構築した後に、エンドポイントサービスを選択し、詳細タブよりサービス名を控えておきます。
(com.amazonaws.vpce.ap-northeast-1.vpce-svc-xxxxxx)

次に、接続口となるエンドポイントをサービス提供側VPCのEC2(EC2-A)が構築されたサブネットに構築します。

リソース・サービス 設定・要点
Security Group
(privatelink-A-vpce-sg)
VPC EndpointのSGです。
HTTP(TCP: 80)に対し、EC2のSG(EC2-A-sg)の通信を許可します。
VPC Endpoint
(privatelink-A-vpce)
Privatelinkの入り口となるサービスです。
サービス利用VPCに構築されたEC2と同一のサブネットに配置します。
タイプNLB と GWLB を使用するエンドポイントサービス
サービス名には控えておいたサービス名を入力し、サービスの検証を押下します。
サブネットap-northeast-1aPrivateSubnetのIDを選択します。
セキュリティグループ:privatelink-A-vpce-sg

デフォルトでは、エンドポイント作成時に許可が必要なため、許可を行います。

リソース・サービス 設定・要点
VPC Endpoint Service
(privatelink-B-vpces)
エンドポイント接続タブにて作成したエンドポイントがPending acceptanceとなっているので、
アクションエンドポイント接続リクエストの承諾を選択します。

この設定により、別VPCにあるEC2で提供されるサービスを閲覧できるようになっているはずです!

(図4)PrivateLinkの構築

ネットワーク到達性を確認する

ここでは、「VPC Reachability Analyzer」を利用してネットワークの到達性を確認してみます。 マネジメントコンソール上部から検索すると簡単に見つかります。

※1回の実行毎に 0.10USD 請求されます。あえて2回失敗するので、料金が気になる方は先を見てから実施してください。

パスの作成を分析ボタンを押下し、以下のように項目を設定することで、対象間の到達性の確認をできます。 また分析の詳細からは、通過しているElastic Network Interface(ENI)やSGを見ることができるため、トラブルシューティングに役立ちます。

リソース・サービス 設定・要点
パスの作成と分析
(EC2A-B)
到達性の設定をします。
送信元タイプinstances
送信元EC2-A (id)
送信先タイプinstances
送信先EC2-B (id)
プロトコルTCP

正しく設定されていれば、EC2-A/B同士が接続できるはず・・・

ですが、「到達不可能」と出てしまいました!

詳細を見てみると、次のセキュリティグループの ingress ルールはいずれも適用されませんというエラーの様です。 その原因は、以下のポイント③にありました。

ポイントその③:PrivateLinkの通信セキュリティ

この接続が失敗した理由は、NLBのセキュリティグループがエンドポイントサービスに適用されていたためです。 デフォルトの設定では、NLBに設定されているSGがPrivateLinkの通信に適用されます。 PrivateLinkの通信セキュリティはエンドポイントのSGで制御しているため、この関連付けを解除します。

リソース・サービス 設定・要点
NLB
(NLB-B)
セキュリティタブより編集ボタンを押下します。
PrivateLink トラフィックにインバウンドルールを適用する のチェックを外します。

(再度)ネットワーク到達性を確認する

設定が完了したので、再度、到達性の検証をします。 2回目以降は通信先を設定する必要は無く、先ほど作成したパス(EC2A-B)を選択し、パスの分析ボタン → 確認ボタンを押下します。

しかし、またもや「到達不可能」と出てしまいました!

詳細を見てみると、ロードバランサー loadbalancer/net/NLB-B/xxx のリスナーは、いずれも適用されません。というエラーの様です。 その原因は、以下のポイント④にありました。

ポイントその④:クロスゾーン負荷分散

この接続が失敗した理由は、EC2-A/Bがそれぞれ別のAZに配置されていたためです。 デフォルトの設定では同一のAZ内で通信を行うため、AZ間で通信できるようにするためには、 NLBの設定から「クロスゾーン負荷分散」機能を有効化する必要があります。

(図5)デフォルトの負荷分散ルーティング

クロスゾーン負荷分散を有効化する

NLBがAZをまたいだルーティングを可能にするために、クロスゾーン負荷分散の設定を行います。

リソース・サービス 設定・要点
NLB
(NLB-B)
NLBを選択しアクションロードバランサーの属性を編集を選択します。
ロードバランサーのターゲット選択ポリシー項目でクロスゾーン負荷分散を有効にするを選択します。

設定編集画面より、NLB以降でAZ間に通信ができるイメージ画像に変わります。

(再々度)ネットワーク到達性を確認する

今度こそ、設定不足が無いかチェックしながら、再々確認します。

「到達可能」となりました!よかったです!

実際に接続してみる

サービス利用側EC2(EC2-A)からサービス提供EC2(EC2-B)のWebページが閲覧できることを確認します。

EC2-Aのアクセス先は、作成したエンドポイントとなるので、アクセス先DNS名を取得します。

リソース・サービス 設定・要点
VPC Endpoint
(privatelink-A-vpce)
エンドポイントのアクセス先DNS名を取得します。
詳細タブより、DNS名を控えておきます。
合わせて、サブネットタブより、IPv4アドレスを控えておきます。

EC2-AにSSMでログインし、以下のコマンドを用いてWebページへアクセスします。

# エンドポイントからIPv4アドレスを引けることを確認
dig <控えておいたエンドポイントDNS名>
> 10.0.0.xxx

# ページにアクセス
curl <控えておいたエンドポイントDNS名>
> Hello!

おわりに

この記事では、PrivateLinkの設定方法についてほんのちょっと詳しく記載しました。 実際に設定してみると、意外な躓きが多く、とても勉強になりました。

今回設定した、Webサーバソフトウェア(HTTP:80)に関する部分を独自のサービス(プロトコル)に置き換えることで、AWSネットワーク間で安全に通信することができます。
また、インスタンス間の到達性可能性テストに使用したVPC Reachability Analyzerではinstance以外にも送信元/先を設定でき、送信ヘッダも制御できるため、柔軟にテストケースを作成できます。

(図6)送信元/先となるタイプ

(図7)設定できるパケットヘッダー情報

ぜひ、ご自身のユースケースに合わせて試してみてください!

ここまで読んでいただきありがとうございました!

圡井一磨(執筆記事の一覧)

23年度新卒入社しました。最近は自炊にはまっています。アパートのキッチンが狭くて困ってます。