最近仕事でGCPを触りはじめ、特にGKEを使ったアプリケーションの構築に興味を持っています。基本的には、まず公式ドキュメントやチュートリアルで理解を深めているのですが、それだけでは分からなかった点があったので、まとめました。
今回は、冗長構成したCloud SQLに対して、GKE上のコンテナから接続する方法を紹介します。一般的に高可用性や負荷分散を目的として、データベースを冗長構成することがあると思います。Cloud SQLの場合、Masterインスタンスに対して、Failover Replicaを作成することで、耐障害性と負荷性能を高める構成をとることができます。GKEからCloud SQLインスタンスに接続するには、Cloud SQL Proxy Docker イメージを使うことが一般的で、単一のCloud SQLインスタンスに接続する方法は、公式ドキュメントにも記載されていますが、複数のインスタンスへの接続設定はなかったため、実際に試した設定をまとめました。
サービス構成
- 最終的に以下の構成を構築します
- GKE
- 接続の検証のために、mysql-clientコンテナを立てます
- Cloud SQLに接続するために、cloudsql-proxyコンテナを立てます
- Cloud SQL
- Master, Failover Replica, Read Replicaの3種類があります
- Failover ReplicaはRead Replicaとしても使うことができ、ゾーン障害時にはMasterに昇格します
- 耐障害性と負荷性能を高めるため、Master(write専用)とFailover Replica(read専用)の構成としました
構築手順
Cloud SQLの設定
- 公式ドキュメントを参考に、Masterインスタンスを作成
- https://cloud.google.com/sql/docs/mysql/create-instance?hl=jaCloud
- 設定オプションを表示>自動バックアップと高可用性の有効化 からフェイルオーバーレプリカの作成にチェックを入れると、自動でFailover Replicaが生成される
GKEの設定
Cluster作成
- 公式ドキュメントを参考にClusterを作成
- 今回の構成を作成するにあたっては、zoneは適宜選択してよい
- GPCではデフォルトのVPCネットワークが用意されているので、指定しなければデフォルトのVPCに構築され、ファイヤウォールルールも適用される
- 今回は外部にアプリケーションを公開する想定はないので、ネットワークに関しても気にする必要はない
Cloud SDKインストール
- 公式ドキュメントを参考にCloud SDKをインストール
- Webブラウザ上のcloud Shellからもgcloudコマンドは使えるが、後続の設定でローカルでの作業が必要になるため、用意しておく
-
gcloud init
でgcloudコマンドを使用できるようにする
-
操作するクラスターの指定とkubectlコマンドの取得
- 以下のコマンドをCloud SDKで実行
$ gcloud config set container/cluster [NAME]
$ gcloud container clusters get-credentials [NAME] --zone=[zone name]
$ gcloud auth application-default login
接続のための認証情報設定
- 公式ドキュメントを参考に、1. APIを有効にする から 5. シークレットの作成 まで実施
- コマンドは全てインストールしたCloud SDKで実行する
Dockerイメージのデプロイ
- デプロイするイメージは以下の2つ
- mysql-client:接続を確認するためのDockerイメージ
- cloudsql-proxy:Cloud SQL Proxy Docker イメージ ※公式のイメージを使う
mysql-clientのイメージを作成
- Dockerfileからイメージを作成する
FROM mysql
ENTRYPOINT ["tail", "-f", "/dev/null"]
- pullしたイメージをContainer registoryにpushする
$ docker tag [image_id] asia.gcr.io/[project_id]/[image]:tag
$ gcloud docker -- push asia.gcr.io/[project_id]/[image]:tag
イメージのデプロイ
- GKEにイメージをデプロイする際には、Kubernetesのコマンドを使用する
- Kubernetesにはコンテナの集合体であるPodという概念があり、Podを作成するために、以下のyamlファイル(Deployment)を作成する
- cloudsql-proxyの接続先をカンマ区切りで並べ、ポートは違うものにするのがポイント
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: gke-sql-test
spec:
replicas: 1
template:
metadata:
labels:
app: gke-sql-test
spec:
imagePullSecrets:
- name : gcp-registry-key
containers:
- image: asia.gcr.io/[project_id]/[image]:tag
name: mysql-client
- image: gcr.io/cloudsql-docker/gce-proxy:1.11
name: cloudsql-proxy
command: ["/cloud_sql_proxy", "--dir=/cloudsql",
"-instances={Master接続名}=tcp:3306,{Failover Replica接続名}=tcp:3307",
"-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: ssl-certs
mountPath: /etc/ssl/certs
- name: cloudsql
mountPath: /cloudsql
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
- name: ssl-certs
hostPath:
path: /etc/ssl/certs
- name: cloudsql
emptyDir:
- 以下のコマンドを実行する
$ kubectl create -f test-deployment.yaml
以上で設定は終了です。
最後に実際にインスタンスに接続することができるか、mysql-clientコンテナにログインして確認を行いたいと思います。
検証
- mysql-clientコンテナにログイン
$ kubectl exec -it gke-sql-test -c mysql-client /bin/bash
- mysqlのコマンドで接続を確認する
$ mysql -h 127.0.0.1 -P 3306 -u [user-name] -p
$ mysql -h 127.0.0.1 -P 3307 -u [user-name] -p