エンジニアの桂です。
今日は Cloud Build から Cloud SQL に接続する方法について紹介していきます。
どちらも Google Cloud Platform 上のサービスなので一見簡単にできそうですが、 Cloud Build というサービスは予想外に不器用で、こういう作業はかなり苦手だったりします。
今回は Cloud SQL Proxy を立てながら並列的にSQL 接続を行う手法を使います。この手法は @kshibata101 氏の Cloud BuildでCloud SQLのマイグレーションをしたい をベースにしていますが、最近 Cloud SQL Proxy のイメージから sh
が削除されたため、この手法は使えません。
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown.
time="2019-11-01T07:13:46Z" level=error msg="error waiting for container: context canceled"
そこで、この GitHub Issue 内で ffjeremy 氏が提案している方法に近いものを紹介します。
Cloud Build 設定
Cloud SQL Proxy を起動して UNIX ソケットを介して Cloud SQL に接続すると言う流れですが、 Cloud SQL Proxy は SQL 実行の際にバックグラウンドで実行する必要があるので、工夫が必要です。
並列で実行するだけであれば、waitFor
オプションを使って簡単に実現できますが、それだけだと Cloud SQL Proxy は永遠に終わらないので、用が終わってから docker kill
を使って Cloud SQL Proxy のコンテナを終了させます。
これらを踏まえて、以下の cloudbuild.yaml
を用意しました。『SQL 実行』と substitutions
をタスクに合わせて変更して利用します。(_DB_USER
と _DB_PASS
はコマンドラインから渡します。)
steps:
- id: Cloud SQL Proxy 起動
name: gcr.io/cloudsql-docker/gce-proxy
args:
- /cloud_sql_proxy
- -dir=/cloudsql
- -instances=${_INSTANCE_CONNECTION_NAME}
volumes:
- name: cloudsql
path: /cloudsql
- id: Cloud SQL Proxy 起動待機
name: mysql:5.7.28 # 『SQL 実行』で使うイメージをここで pull しておくとお得
entrypoint: bash
args:
- -c
- |
while [ ! -e "/cloudsql/${_INSTANCE_CONNECTION_NAME}" ]; do
sleep 1
done
volumes:
- name: cloudsql
path: /cloudsql
waitFor: ['-']
- id: SQL 実行
name: mysql:5.7.28
entrypoint: bash
args:
- -c
- |
# ここを目的に合わせて変更します
mysql -u"${_DB_USER}" -p"${_DB_PASS}" -S"/cloudsql/${_INSTANCE_CONNECTION_NAME}" -D"${_DB_NAME}" \
-e 'SHOW TABLES'
volumes:
- name: cloudsql
path: /cloudsql
waitFor: ['Cloud SQL Proxy 起動待機']
- id: Cloud SQL Proxy 終了
name: gcr.io/cloud-builders/docker
entrypoint: bash
args:
- -c
- docker kill -s TERM $$(docker ps -q --filter ancestor=gcr.io/cloudsql-docker/gce-proxy)
waitFor: ['SQL 実行']
substitutions:
_DB_NAME: <DB 名を指定>
_INSTANCE_CONNECTION_NAME: <Cloud SQL のインスタンス接続名を指定>
Cloud Build 実行の準備
Cloud SQL Proxy を使うために、まずこちらから Cloud SQL Admin API を有効にします。
また、 Cloud Build から Cloud SQL にアクセスするために、 サービスアカウントにroles/cloudsql.client
を付与します。
$ PROJECT_NAME=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(NAME)")
$ PROJECT_NUMBER=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)")
$ gcloud projects add-iam-policy-binding ${PROJECT_NAME} --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role=roles/cloudsql.client
Cloud Build の実行
前述の通り、 _DB_USER
と _DB_PASS
を渡して実行します。
$ gcloud builds submit --config=cloudbuild.yaml --substitutions=_DB_USER=<DB ユーザ名>,_DB_PASS=<DB パスワード>
終わりに
Cloud Build は便利ではありますが、 VPC に繋げなかったり色々不便な箇所が目立ちます。今後の改善が期待されますね。
さて、最後に、ジラフでは仲間を絶賛募集中ですので、興味がある方は是非ともご連絡ください。