AWS PrivateLink を用いてTiDB Serverless Cluster にVPC内部からPrivate 接続を行う
先日PingCapの関口さんから、TiDB Serverless Cluster は無償でAWS PrivateLink経由の接続が可能とお伺いして、早速試してみました。
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
3. PrivateLink セットアップ
先ほどと同様に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