ECS(Fargate)からTiDB Cloud(Serverless)にPrivateLink経由で接続してみた

ECS(Fargate)からTiDB Cloud(Serverless)にPrivateLink経由で接続してみた

Clock Icon2023.10.24

こんにちは、ゲームソリューション部のsoraです。
今回は、ECS(Fargate)からTiDB Cloud(Serverless)にPrivateLink経由で接続してみたことについて書いていきます。

構成

プライベートサブネットにあるECS(Fargate)からPrivateLinkを経由して、TiDB Cloudのクラスターへ接続する構成です。
TiDB管理側の環境やVPCを明示的に記載していますが、ユーザー側で意識する必要はありません。 TiDB Cloudとは何か、TiDB Cloudのアカウント作成手順の説明は割愛します。
詳細については、以下記事をご参照ください。

TiDB Cloudでの準備

クラスタの作成

TiDB Cloudにてクラスタを作成します。
Tierは無料枠があるServerlessを利用し、リージョンは東京(ap-northeast-1)を選択します。
クラスタが作成できるとダッシュボードでクラスタの情報を確認することができます。

データインポート

TiDB Cloudのインポート機能を使用して、テスト用のデータをインポートします。
インポートの方法として、ローカルかS3を選択したり、データのフォーマットとしてCSV・Parquet・Aurora Snapshot・SQL Fileを選択することができます。
今回はCSVで作成したテストデータをインポートします。
インポートするCSVファイルは以下です。

prefecturename,prefecturalcapital,region
Hokkaido,Sapporo,Hokkaido
Tokyo,Tokyo,Kanto
Aichi,Nagoya,Chubu
Osaka,Osaka,Kansai
Hukuoka,Hakata,Kyushu

インポートのプレビュー画面にて、自動で読み取られたテーブル構造が表示されます。
プライマリキーを選択してインポートを行います。
インポートができたため、実際にインポートされたデータを、自然言語処理を用いたSQLジェネレータであるChat2Queryで確認してみます。
Chat2QueryはSQL文を理解していなくても、簡単にSQL文を生成することができます。

接続情報の取得

クラスタを作成し、データも準備できたため、クラスタに接続するための情報を取得します。
クラスタのダッシュボードからConnectを押下して、接続情報を表示します。
サービス名・AZ・リージョンIDが、PrivateLink作成に必要な情報です。
接続用コードは、ECSで実行するタスクで使用します。/testの部分はデータベース名のため書き換える必要があります。
これでTiDB Cloud側の準備は完了です。

AWS環境での準備

ここからはAWS側の準備をしていきます。
以降のAWS側の設定については、TiDB Cloudがかかわる部分を中心に説明し、その他のリソースの作成については適宜割愛します。

TiDB Cloud接続用のエンドポイントの作成

まずTiDB Cloud接続用のエンドポイント作成を作成します。
その他のエンドポイントサービスで、サービス名にTiDB Cloudで取得したサービス名を入力して、サービスの検証を行います。
DNS名は有効化する必要があります。

ECSで使用するエンドポイントの作成

プライベートサブネットでECS(Fargate)を使用するために必要なエンドポイントを作成します。
作成するのはECRを利用するための3つと、CloudWatch Logsへの接続用の1つです。

  • com.amazonaws.region.ecr.dkr
  • com.amazonaws.region.ecr.api
  • com.amazonaws.region.s3
  • com.amazonaws.region.logs

必要なエンドポイントについての詳細は、以下が参考になりました。

エンドポイントの作成手順については、今回の本筋とはずれるため割愛します。

イメージの作成

TiDB Cloudへ接続する際のタスクを作成します。
ECRへpushする環境にはCloud9を使用しました。(dockerもデフォルトでインストールされています)
ディレクトリ構成は以下です。

$ tree
.
├── dockerfile
└── src
    └── main.go

TiDB Cloud接続用のソースコードは以下です。
TiDB Cloudで取得した接続コードにてDB接続し、テーブル内の全てのデータを取得します。

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// TiDB Cloudにて表示された接続コード
	db, err := sql.Open("mysql", "<接続情報>:4000)/GoECSTest")
	if err != nil {
		fmt.Println("err", err)
		fmt.Println("DB connection error")
	}
	defer db.Close()

	// SQL実行
	rows, err := db.Query("SELECT * from PrefecturesTable")
	if err != nil {
		fmt.Println("err", err)
		fmt.Println("SQL error")
	}
	defer rows.Close()

	fmt.Println("都道府県名, 県庁所在地, 地域")
	for rows.Next() {
		var prefecturename, prefecturalcapital, region string
		err := rows.Scan(&prefecturename, &prefecturalcapital, &region)
		if err != nil {
			fmt.Println("Scan error")
			return
		}
		fmt.Printf("%s, %s, %s\n", prefecturename, prefecturalcapital, region)
	}
}

Dockerfileは以下です。

FROM golang:1.21.3-alpine

WORKDIR /app

RUN apk update && apk add git

COPY /src .
RUN go mod init app
RUN go get github.com/go-sql-driver/mysql
RUN go mod tidy
CMD go run main.go

ファイルが準備できたら、ECRへイメージをpushします。

接続

ECSからTiDB Cloudへ接続するための準備ができたため、ECSにてタスクを実行します。
タスクを実行した後、CloudWatch Logsを確認すると、データが取得できていることが確認できました。

参考ページ

公式ページ(Connect to TiDB Serverless via Private Endpoint)

最後に

今回は、ECS(Fargate)からTiDB Cloud(Serverless)にPrivateLink経由で接続してみたことを記事にしました。
今後もTiDBやTiDB Cloudを試してみて、記事にしていきたいと思います。

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.