mysql dockerコンテナなGCEインスタンスに Cloud Runとローカル両方でセキュアにつなぐ方法

公開:2020/10/10
更新:2020/10/10
3 min読了の目安(約3000字TECH技術記事

セキュアの定義→特別にファイアウォールルールを追加しない

はじめにタイトルの補完ですが、今回のセキュアの意味合いとしてはファイアウォールルールに「IP範囲0.0.0.0/0、tcp:3306」を追加し、GCEインスタンスのネットワークタグにこれを設定しないことを指します
この設定を足すことで、世界中からこのインスタンスの3306ポートが狙われるためあまり良くないですね

セキュアの敷居が低い気はしますが、この記事ではこの一点にしぼりCloudRunとローカルからmysql接続する方法を記述します

まずmysqlなコンテナイメージを作成しGCEインスタンスを立ち上げる

コンテナのイメージについては各々だと思いますので、参考程度のDockerfileだと思ってください
コメント部分は余談ではありますが、公式mysqlイメージでの環境変数をファイルから設定する方法と初期スクリプトの設定方法です
secrets/**においたファイルに書いてある文字列が対応する環境変数に設定されます
また01_create_database.sqlには書いたスクリプトがビルド時に実行されます

# Dockerfile
FROM mysql:5.7

# ENV MYSQL_ROOT_PASSWORD_FILE=/run/secrets/root-pw
# ENV MYSQL_USER_FILE=/run/secrets/user
# ENV MYSQL_PASSWORD_FILE=/run/secrets/pw
# ENV MYSQL_DATABASE_FILE=/run/secrets/db

# COPY secrets/root-pw /run/secrets/root-pw
# COPY secrets/user /run/secrets/user
# COPY secrets/pw /run/secrets/pw
# COPY secrets/db /run/secrets/db

# COPY my.cnf /etc/mysql/conf.d/my.cnf
# COPY 01_create_database.sql /docker-entrypoint-initdb.d/01_create_database.sql

EXPOSE 3306

CMD ["mysqld"]

ビルドしてGoogleContainerRegistryにPushしましょう

docker build . --tag gcr.io/${projectName}/${tagName}
docker push gcr.io/${projectName}/${tagName}

GCEのインスタンスを作成しましょう。コンソール上からは以下で設定できます

SSH接続して、docker exec経由でmysqlに接続できたら成功です

docker ps
# ↑でコンテナIDを確認して
docker exec -it ${コンテナID} mysql -u ${MYSQL_USER} -p
Enter password: ${MYSQL_PASSWORD}

コンテナイメージを利用したGCEインスタンスはDockerfileでEXPOSEしたポートがそのままホスト側から利用できます
なのでこの状態で「IP範囲0.0.0.0/0、tcp:3306」なファイアウォールルールを追加すると、ホスト名にインスタンスの外部IPを指定すれば3306ポートで接続できてしまうんですね


余談ですが、f1-microタイプで無料枠つかったろ!をしたかったのですが、初期データが多かったのか何かが悪かったのかいつまで経っても接続できなかったです
同じ設定のままg1-smallタイプにしたら問題なかったため、おそらくインスタンスのパワー不足かなと推測されます

Cloud Runから接続する

フルマネージドCloudRunを対象としています

Cloud Run のドキュメント

CloudRunはコンテナイメージを用意すればサーバレスなWebサーバを準備してくれるサービスです
軽く触ってみた程度ではありますが、このようなPaaSサービスでは取っ付きやすさと手軽さはピカイチではないかと思います

サーバレスVPCアクセスを作成する

GCPのサーバレスサービスでプライベートIPを使って各サービスを連携する方法として提供されているものです
CloudRunでは、CloudSQLと連携が簡単にできるのでそちらが情報が多かった気がします

CloudRunサービスを作成する

mysqlサーバに依存するWebサーバのDockerイメージを作成して、CloudRegistryにPushしてください
そのイメージを利用し、詳細設定からVPCコネクタ設定で先につくったサーバレスVPCアクセスを設定してください

DBホスト名はGCEインスタンスのプライベートIPアドレスを指定しください

ローカルから接続する

ローカルからはvia SSHでmysql接続するのが一番簡単かと思います
sshコマンドでGCEインスタンスにつなげるようにしてください
gcloudコマンドがローカルで使えるのであれば、gcloudコマンドでSSHログインしてからgcloud compute config-sshを実行すると簡単です

gcloud compute config-ssh --project=${projectName}
# ~/.ssh/config に色々追記される

あとは各々のDBクライアントツールでvia SSHで接続すればOKです
サンプルとしてTablePlusの接続情報を載せておきます

終わりに

以上になります。当然のような話ではありますが、mysqlのdockerイメージを利用したGCEインスタンスに接続する情報が少なかったので、誰かの助けになれば幸いです

単純にデータベースがほしいだけならCloudSQLを利用するほうが手っ取り早いし情報も多いですね
サーバレスVPCアクセスは、データベースに限らずどうしてもサーバインスタンスの助けがほしい時に簡単に連携できるので便利だなぁって思いました