DataSync で VPC エンドポイントを使用して転送する際にエージェントが名前解決できる必要があるか検証してみた

検証の背景

DataSync ではVPC エンドポイントを使用してデータの転送を行うように設定することが可能です。

例えば下記のような構成でオンプレミスのファイルサーバから Direct Connect を経由してデータを S3 に送信する際、VPC エンドポイントを使用することでインターネットを経由せずにデータを転送できます。

DataSync エージェント は VPC エンドポイントを通して DataSync サービスとの通信を行います。また、DataSync のタスクを作成する際に裏で ENI が 4 つ作成され、データの転送にはこれらの ENI が使用されます。

この際、DataSync エージェントは VPC エンドポイントの DNS 名から名前解決をできる必要があると思っていました。 マネジメントコントロールから DataSync の エージェント をアクティベートしたり、タスクを実行する際に VPC エンドポイントの IP を指定した記憶が無かったからです。 マネジメントコントロールからエージェントをアクティベーションする際は下記のようにエンドポイントを選択する形となります。

Interface 型 VPC エンドポイントの DNS 名はインターネット経由で名前解決可能なので、これを使って上手く名前解決しているのかなくらいに思っていました。 しかし、公式ドキュメントに記載されているネットワーク要件としては VPC エンドポイントの IP に到達可能な必要があるくらいの書き方で名前解決が必要という記載は見つけられませんでした。 オンプレミスでインターネットへ出て名前解決したり Route53 Resolver を使用して Amazon Provided DNS を参照できない環境でも DataSync が正しく動作するかを確認するため、疑似環境を作成して検証を実施しました。

疑似環境を作ってみた

検証を実施するにあたり Direct Connect を使用した環境は用意できなかったため、下記のような疑似環境を作成しました。

オンプレミス環境に見立てた Private サブネットに EC2 として DataSync エージェント をデプロイし、同一サブネットにある NFS サーバからデータを取得して 別 VPC にある VPC エンドポイントを使用してデータをS3 に転送します。 このままだと DataSync エージェントは Amazon Provided DNS を使用して名前解決可能な状態のため、/etc/resolve.confを下記のように修正して名前解決できないように設定します。

; generated by /usr/sbin/dhclient-script
search ap-northeast-1.compute.internal
options timeout:2 attempts:5
nameserver 127.0.0.1

また、/etc/sysconfig/network-scripts/ifcfg-eth0PEERDNS=noと設定して DHCP で DNS サーバ情報を更新させないようにします。 この状態だと、下記のようにconnection timed out; no servers could be reachedと表示されて名前解決を実施できなくなります。

$ dig vpce-005a3f27822122c71-rsdiamu1.datasync.ap-northeast-1.vpce.amazonaws.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> vpce-005a3f27822122c71-rsdiamu1.datasync.ap-northeast-1.vpce.amazonaws.com
;; global options: +cmd
;; connection timed out; no servers could be reached

AMI は下記コマンドの実行結果より、aws-datasync-2.0.1652202786.1-x86_64-gp2を使用します。

$aws ssm get-parameter --name /aws/service/datasync/ami --region ap-northeast-1 --query "Parameter.Value"
"ami-02ca27e738216ad85"

アクティベーションしてみた

DataSync を使用して転送する際、タスクを実行する前に DataSync エージェント をアクティベーションする必要があります。 また、エージェントのアクティベーションはアクティベーション用のキーを取得してからそのキーを取得してエージェント作成を完了するという 2 段階の作業が必要になります。 この際、エージェントの 80 番ポートと AWS マネジメントコンソールに同時にアクセスできる端末が存在すればマネジメントコンソールから一貫した流れでアクティベーションを実施することができます。下記のようにエージェントの IP を入力することで、マネジメントコンソール経由でキーを取得してセットしてくれます。キーがセットされればそのままエージェントの作成を実行することでアクティベーションが完了します。

オンプレミス環境でないと DataSync エージェントの 80 番ポートにアクセスできないが、そこではインターネットにアクセスできないという場合、curl コマンド等で DataSync エージェントからアクティベーションキーを取得し、そのキーを使用してエージェントの作成を完了する必要があります。ここでエージェントの作成を完了させるためにはマネジメントコンソールにアクセスして作業を行うか、AWS CLI を実行可能な環境でaws datasync create-datasyncコマンドを実行する必要があります。(VM の場合、local console 経由でアクティベーションキーを取得することが可能ですが、その後もマネジメントコンソールか AWS CLI での作業が必要です。) 今回はエージェント の 80 番ポートに接続可能かつマネジメントコンソールに到達できる端末は無い想定なので(オンプレミスからインターネットへの経路は無い)、curl コマンドを使用してアクティベーションキーを取得します。 curl コマンドと AWS CLI を使用する手順は下記ドキュメントに記載があるので、この通りに進めます。

既出の図ですが、下記構成図におけるコマンド実行用端末を使用してアクティベーションキーを取得してみます。この端末も DataSync エージェント同様名前解決はできないように設定します。

下記コマンドを実行すると、アクティベーションキーが返却されます。

$ curl "http://<agent-ip-address>/?gatewayType=SYNC&activationRegion=aws-region&privateLinkEndpoint=<IP address of VPC endpoint>&endpointType=PRIVATE_LINK&no_redirect"

curlを使用した手順を確認してから気づいたのですが、curlを実行してアクティベーションキーを取得する際はきちんと VPC エンドポイントの IP をパラメータとして指定していました。エージェントはここで指定した IP を保持して今後の通信を行うようです。 マネジメントコンソールを使用してアクティベーションキーを取得する際はエンドポイントをプルダウンで選択すれば勝手に作業を実施してくれましたが、この時も裏では対応する IP をエージェントに渡してくれていると思われます。 アクティベーションキーの取得が完了した後、VPC フローログを確認すると下記のようにエージェントの IP から VPC エンドポイントへの 1027 番ポートを使用した通信が定期的に実行されていました。

2 123456789012 eni-0902ac38c35acd2ec 10.0.200.186 172.16.200.48 57760 1027 6 1 60 1654704368 1654704390 ACCEPT O

この状態になってはじめてアクティベーションを完了させることができます。 次に AWS CLI を使用してエージェントのアクティベーションを完了します。

$ aws datasync create-agent \
  --agent-name <agent-name> \
  --vpc-endpoint-id <vpc-endpoint-id> \
  --subnet-arns <subnet-arns> \
  --security-group-arns <security-group-arns> \
  --activation-key <obtained-activation-key>

このコマンドの実行には、以下を名前解決してその名前解決先にリクエストが到達できる必要があります。

datasync.ap-northeast-1.amazonaws.com

名前解決を一切できず、インターネットへの到達経路も無いEC2でコマンドを実行した場合、下記が表示されてアクティベーションが失敗しました。

Could not connect to the endpoint URL: "https://datasync.ap-northeast-1.amazonaws.com/"

あくまでキーの取得のみ curl で行い、そのキーを持ち帰ってインターネット経由等で名前解決できる所でアクティブ化を完了する必要があります。(アクティベーションキーを取得した後はエージェントは何らかのポーリング作業を実施しており、いつでもエージェントを使用可能にする準備ができていると考えられる) 今回はインターネット経由で名前解決できる環境で下記コマンドを実行しアクティベーションが完了しました。

$ aws datasync create-agent \
  --agent-name <agent-name> \
  --vpc-endpoint-id <vpc-endpoint-id> \
  --subnet-arns <subnet-arns> \
  --security-group-arns <security-group-arns> \
  --activation-key <obtained-activation-key>
{
    "AgentArn": "arn:aws:datasync:ap-northeast-1:123456789012:agent/agent-07b63dd9e540e1ef3"
}

キーさえ取得できてしまえば、マネジメントコンソールでエージェントのアクティベーションキーを手動で入力するを選択することでもアクティベーションを完了できます。

転送してみた

アクティベーションは無事完了しましたが、この後も DataSync エージェントは ENI 等と通信してデータを転送する必要があります。エージェントが名前解決できなくてもちゃんと転送できるのかタスクを実行して試してみました。 NFS サーバにダミーデータを作成して送信元ロケーションとして設定します。

エージェントは先程アクティベーションしたものを指定します。DNSサーバが無い想定なので、NFS サーバとして直接 IP を指定します。

次に送信先の S3 バケットも用意して、送信先ロケーションとして設定します。

これらのロケーションを使用してタスクを作成し、実行しました。タスク設定は全てデフォルトを選択しました。

項目 設定値
データ検証オプション 転送されたデータのみを確認する
帯域幅の設定 無し
スキャンするデータ 送信元ロケーション全体
転送モード 変更されたデータのみを転送する
削除されたファイルを保持する はい
ファイルを上書きする はい

タスクを実行した所、無事成功になり S3 にもファイルが転送されていることが確認できました。

転送に必要な IP をエージェントに教える部分は DataSync が全て面倒を見てくれるようです。タスクを作成したタイミングで ENI が 4 つ作成され、タスクを実行するとそれらがIn-useになります。VPC フローログを確認すると、DataSync エージェントからENIの IP に対して 443 ポートを使ってデータを送りつけている部分は確認できました。タスクが実行された時に使用する ENI の IP も含めて情報を置いておき、エージェントがそれらをポーリングしているのでしょうか。詳しい実装まではわかりませんが、名前解決無しで転送も完了しました。

2 123456789012 eni-0a593f3430cd92eb0 10.0.200.186 172.16.200.181 57952 443 6 27 7315 1654706727 1654706750 ACCEPT OK

VPC エンドポイント の IP は変わらない?

あまり意識したことが無かったので確認してみたのですが、公式ドキュメントに下記記載がありました。DataSync エージェントに最初に IP を渡してしまえば変更の心配は無いんですね。

エンドポイントネットワークインターフェイスには、サブネットの IP アドレス範囲からプライベート IP アドレスが割り当てられます。この IP アドレスは、インターフェイスエンドポイントが削除されるまで保持されます。

まとめ

DataSync が VPC エンドポイントを使用して転送を実行するには名前解決が必要と思い込んでいたので良い勉強になりました。s3 sync等の AWS CLI を使って S3 にデータを上げる際も名前解決を意識する必要はあるので、裏で良い感じにやってくれる DataSync はとても便利ですね。