如何在 AWS ECS 上連線 GCP CloudSQL

雖然實務上不太建議大家這樣搭配...

近期遇到一個業務需求,需要在 AWS ECS 上透過 BI 工具 Metabase 連線到 GCP 上一個 CloudSQL 的資料庫。

CloudSQL 遠端連線做法

CloudSQL 官方推薦兩種方式做遠端連線:

  1. 透過 IP 白名單的方式,將會連線進來的 IP 做設定

  2. 透過 CloudSQL Proxy 來做連線

由於在我本次的環境當中主機的 IP 並不固定,所以使用後者的作法。然而多數 CloudSQL Proxy 的教學,包含官方都是使用 Kubernetes(應該一點都不意外?),但卻沒有使用 ECS 的範例。

CloudSQL Proxy 在 ECS 上的設定

大邏輯就是在 task definition 上多跑一個 containerDefinitions,然後透過主要 container 的 links 將兩邊串在一起。

如下方為例,請注意 cloudsql 相關定義:

{
    "family": "awesome-service",
    "containerDefinitions": [
        {
            "name": "awesome-service",
            "image": "awesome-service/awesome-service:v1.0.0",
            "cpu": 0,
            "links": [
                "cloudsql"
            ],
            "portMappings": [],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": []
        },
        {
            "name": "cloudsql",
            "image": "asia.gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.6.0",
            "cpu": 0,
            "portMappings": [],
            "essential": false,
            "command": [
                "PROJECT:REGION:INSTANCE",
                "--address",
                "0.0.0.0",
                "--json-credentials",
                "{\"type\": \"service_account\", ...}"
            ],
            "environment": [],
            "mountPoints": [],
            "volumesFrom": []
        }
    ],
    "networkMode": "bridge",
    "memory": "1024"
}

其中主要設定的點在 command 的部分:

  • 第一個參數 PROJECT:REGION:INSTANCE 可以從 CloudSQL 的管理介面當中取得

  • 第五個參數則為 Service Account 的 JSON,注意要處理雙引號等字串跳脫

在 Container 中連線到 CloudSQL

設定完成之後,就可以在主要的 container 中,透過 cloudsql 這個 hostname 來進行連線,例如:mysql://username:password@cloudsql:3306