GKEからCloud SQLに接続する方法
Deisのpostgresをoff-clusterにする(Cloud SQLを利用) - まーぽんって誰がつけたの?やDeisのpostgresをoff-clusterにする(postgresql on GCEを利用) - まーぽんって誰がつけたの?でCloud SQLをdeisのdatabaseとしようともがいてたけど解決した話。
Cloud SQLはRDSと違う
Cloud SQLはAWSでいうRDS的なやつ。ただちょっと違うのが、同じVPC的な論理的に同じネットワーク内に存在することができずに、別ネットワークになってしまう。 なので、GKE(Google Container Engine)のネットワークとCloud SQLはインターネットを経由しないとつながらないということになる。
GCPが用意してるCloud SQL接続方法
1. 接続してくるグローバルIPアドレスを許可する
GKEのCluster内に存在するNodeは単なるGCEのインスタンスなので一つ一つはグローバルIPを持っている。なので、このIPを指定してあげる。 ただ、Nodeが増えたり減ったりしたときに常にIPアドレスを管理しないといけずあまりよい方法とはいえない :no_good:
2. SSLで接続する
IPアドレスを許可しない場合、SSL証明書を使って接続する。 基本的にdriverはSSL接続は対応してるからまぁこれでもいいんだけど、たまに対応してないミドルウェアなんかがあって取り扱いがちょっと面倒。特にDeisの場合、そういうオプションは用意されてないので、PRをして変更を受け入れてもらわないといけないという状況だった :rolling_eyes:
3. CloudSQL Proxyを使う
これが一番よい方法。Googleが用意してるProxyで、binaryやDocker Imageでinstallして起動するだけで接続できるようになる。Cloud SQL Proxyを起動する際に、Cloud SQLに接続可能なAPI Key的なものと、Cloud SQLのインスタンス名を渡してあげるだけで接続をproxyしてくれる。 あとは、普通にproxyが起動しているインスタンス上で、127.0.0.1に対して接続しにいけばCloud SQLにつながってくれる :100:
ただ、単純なVMインスタンスであればこれでいいが、GKE(Kubernetes)上で使う場合は、ちょっと一工夫がいる :wrench:
公式で紹介されてるGKEからCloud SQLに接続しに行く方法
Kubernetesでは、Pod
というのがContainerの集まりで、それらを何個起動するかとかRolling Updateリリースとかを管理しているDeployment
というリソースがある。
で、公式で紹介されてるのは、DeploymentのPodにCloudSQL ProxyをDocker Imageからcontainerを立てる方法。
https://cloud.google.com/sql/docs/mysql/connect-container-engine
こんな風に、podの中にwordpressっていうimageでcontainerを起動させてるとしたら、そこに、cloud sqlのproxyのimageを追記する。 そうすると、wordpressのcontainerからは、127.0.0.1で接続しにいける。ただ、これだと、Deis本体に手を入れる必要がある。
- image: wordpress:xxx name: wordpers ・ 略 ・ - image: gcr.io/cloudsql-docker/gce-proxy:1.09 name: cloudsql-proxy command: ["/cloud_sql_proxy", "--dir=/cloudsql", "-instances=[INSTANCE_CONNECTION_NAME]=tcp:[PORT]", "-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:
で、実際に、DeisのChartという設定ファイルを書き換えることで、proxy経由で無事接続することができた🎉 これはPRチャンスということで、Contribution.md読むと、PR出す前にSlackで一言相談してみてねとのことで、入ろうとするがlimitエラーかなんかでジョインできない。Deisの問い合わせから頼む入れてくれって送って入れてもらった。
これはDeisにPRチャンス!! 意気揚々とチャンネルに書き込んだ😎
すると、フィーチャーフラグとかつけてくれたらいいよ!でも、なんでわざわざそんなことするの?みたいに言われて、あっさり別の解決策を教えてもらった。わざわざ同じpod内に作る必要なんてないとのこと。
Cloud SQL Proxyを単に一つのDeploymentとServiceとして起動する
Kubernetes上で、あるPodから別のDeploymentのPodには接続しにいけないのかなーって思ってたのが間違いだった。実は、Kubernetes上では、Pod
間の通信はService
を利用すれば簡単にできる。しかもNameSpaceをまたがっていても!
KubernetesがCluster内のDNSもいい感じに設定していてくれて、Service名.NameSpace名
というホスト名でつながることができる!!
最終的な構成はこういう感じ。
NameSpace deis <host: pg-sqlproxy.sql-proxy> | deis-controller |-----------| | -------------------------------|--- NameSpace sql-proxy | ▼ | Service: pg-sqlproxy | | ▼ | Pod: gce-proxy | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~ Cloud SQL | ▼ | PostgreSQL |
この概念を利用すれば、Deisの1アプリとして、Cloud SQL Proxyをdeployしたっていい。Communityではそういうやり方も教えてもらった。
まとめ
Deisのことを調べていくとKubernetesのことを知っていかないといけないんだけど、知れば知るほど奥が深いというか至れり尽せりな機能が用意されててほんとすごい🚢