🌟

AWS PrivateLink を用いてTiDB Serverless Cluster にVPC内部からPrivate 接続を行う

2024/11/27に公開

先日PingCapの関口さんから、TiDB Serverless Cluster は無償でAWS PrivateLink経由の接続が可能とお伺いして、早速試してみました。

AWS PrivateLinkとは仮想プライベートクラウド (VPC)、サポートされる AWS サービス、およびお客様のオンプレミスネットワーク間のプライベート接続を、トラフィックを公衆インターネットに公開することなく実現可能なサービスです。
一般的にPrivateLink経由でAWSで稼働しているSaaSなどへ接続する場合、接続を受ける側は専用のNWエンドポイントを準備し、そこに対してPrivateLink接続を行う形態ととります。このため、多くのSaaS等ではPrivateLink接続は有償オプションとなっており、事前問い合わせが必要となるなど手順は煩雑になります。
一方TiDB Serverless Cluster は共用型となっておりエンドポイントも共用されています。

このため特殊な設定を行うことなくPrivatLink経由での接続が可能です。

ただし通信を出す側(TiDB Serverlessを操作するユーザー側)はPrivateLinkを保持する費用はAWS側で発生します。

通信料の他に時間課金ですので、検証が終わったら忘れず削除しましょう!

1. TiDB Serverles Cluster の起動とPublic接続

いつも通り普通にServerless Cluster を起動します。PrivateLink接続の場合、リクエストを出すクライアント(Amazon EC2)が存在しているVPCおよびSubnetはTiDB Serverless用ネットワークエンドポイントと同じ場所に存在している必要があります。またPrivateLinkはVPC単位ではなくサブネット単位で作成する必要があります。これは後の手順で重要になりますので覚えておいてください。

まずは東京リージョンでTiDB Serverless Cluster を起動します。
Clusterが出来たら、右上のConnectをクリックします。

初回アクセス時はGenerate Passwordボタンが出来ますので、クリックするとパスワードが表示されますのでメモしておきます。
My SQL CLIをドロップダウンから選択すると以下のような接続コマンドが出てきます。
IDやパスワードはそのまま皆さんの環境に即したものが入っているはずです。

mysql --comments -u 'xxxxx.root' -h gateway01.ap-northeast-1.prod.aws.tidbcloud.com -P 4000 -D 'test' --ssl-mode=VERIFY_IDENTITY --ssl-ca=<CA_PATH> -p'password'

AWS のCloudShellで実行する場合--ssl-mode=VERIFY_IDENTITYが古いパラメータとして認識されませんので、削除して以下を実行します。

wget https://letsencrypt.org/certs/isrgrootx1.pem
mv isrgrtttx1.pem cacert.pem
mysql --comments -u 'xxxxx.root' -h gateway01.ap-northeast-1.prod.aws.tidbcloud.com -P 4000 -D 'test' --ssl-ca=cacert.pem -p'password'

以下が表示されれば接続完了です。

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 7053368
Server version: 5.7.28-TiDB-Serverless TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [test]>

2. Public アクセスのブロック

では次にServerless Clusterに対するパブリックアクセスを禁止します。
マネージメントコンソール左ペインのNetworkingをクリックします。

Disableをクリックします。

再度先ほどのmysqlコマンドを実行して接続を試みると以下のエラーとなります。

ERROR 1105 (HY000): Public endpoint is disabled on your cluster. See https://docs.pingcap.com/tidbcloud/connect-via-standard-connection-serverless#disable-a-public-endpoint

先ほどと同様にClusterのConnectボタンをクリックします。

ドロップダウンからPrivate Endpointを選択します。

以下の値を手元にコピーしておきます。

Availability Zone ID:について少し補足をします。AWSのSubnetは通常,a,b,c,d等で区別されますが、これはAWSアカウント毎に異なるデータセンター群を指しているケースがあります。負荷分散を目的としているためです。このためTiDB Serverless Clusterが起動しているデータセンター群と、接続を試みるユーザー側のデータセンター群を合わせるためデータセンター群を識別するコードを用います。これがapne1-az4です。これはどのAWSアカウントであっても常に同じデータセンター群を指します。
(PrivateLinkはVPC毎ではなくSubnet毎に設定する必要があるためです)

AWSマネージメントコンソールでVPCにアクセスし、左ペインからエンドポイントをクリックします。

エンドポイント作成をクリックします。

NLB と GWLB を使用するエンドポイントサービスを選択してサービス名に先ほどコピーした値(com.amazonaws.vpce.ap-northeast-1.vpce-svc-0d5e3d6da8b5b03aaと近しい文字列です)を入力し、サービスの検証を押します。

接続を行いたいVPCを選択し、DNS名を有効化にチェックを入れます。

クライアントであるEC2を起動させるsubnetを指定します。

Security Groupを設定します。これは、今から作成されるTiDB Serverless Cluster へのPrivateLink用セキュリティグループです。つまりEC2から出るポート4000番宛のTCP通信を受け付ける(Inbound)ものが必要です。なければdefault等適当なものを設定するか、別画面で作成してください。クライアントであるEC2用ではないためOutboundのTCP4000番ポートは不要です。
少しややこしいですが注意してください。
最後にエンドポイントを作成ボタンを押します。

4. EC2 の起動とテスト

先ほどPrivateLinkエンドポイントを作成したSubnetにEC2を起動します。EC2の通常起動画面ではSubnetを指定する箇所がありませんが、VPCを指定する画面で詳細の編集ボタンを押すと出てきますので、正しいものに変更して下さい。

まずEC2にMySQLクライアントをインストールします。

sudo dnf -y localinstall  https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
sudo dnf -y install mysql mysql-community-client
sudo dnf -y install mariadb105

次にTiDBのマネージメントコンソールのConnect画面からMySQL CLI用の接続文字列を入手します。

先ほどのPublic用と異なり証明書が不要になっています。
以下の通り接続が成功すれば設定完了です。

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 1792123
Server version: 5.7.28-TiDB-Serverless TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [test]>

たとえばPrivateLinkにアタッチされているセキュリティグループを以下のようにTCP80番しか受け付けないように設定変更した場合、MySQLへの接続は失敗(タイムアウト)します。確かにPrivateLink経由であることがわかります。

Discussion