🙌

SRE 部入社時課題の詰まりポイント 〜 Cloud SQL Auth Proxy を用いた DB 接続編 〜

2024/04/25に公開

こんにちは、クラウドエース SRE 部所属の笠原です。
SIer・コンサルティングファームを経て 2024 年 3 月にクラウドエースへ中途入社しました。

クラウドエースでは入社時の研修の一環としてオンボーディング課題というものに取り組みます。
今回のブログでは、私がこの題材を実施するなかで「ココ詰まったな〜」というポイントと、どうやって解決したかを記載したいと思います。

はじめに

今回取り組んだ課題の概要は以下の通りです。
※あまり書きすぎると後進の方々へのネタバレになってしまうので、少し省略して記載します。

  • Google Cloud 上にプロジェクトを作成し、Virtual Private Cloud(以下、VPC)内に Virtual Machine(以下、VM)と データベース(以下、DB)インスタンスをホストする。
  • VM から DB インスタンスにセキュアにプライベート接続できるようにする。
  • VM には Nginx をインストールして外部からアクセスできるようにする。
  • 非機能要件としてセキュリティや運用監視、CI/CD(Continuous Integration / Continuous Delivery & Deployment)の仕組みを実装する。

今回は 2 点目の部分、VM と DB インスタンスのセキュアなプライベート接続の実装に特に苦労したのでその部分を記載したいと思います。

今回やりたかったこと

Nginx をインストールした Google Compute Engine(以下、GCE)インスタンスから、DB インスタンスである Cloud SQL にセキュアなプライベート接続を実装しました。
図で表すと以下枠線の部分です。

image001

今回は Terraform を使わず、コンソールからの作成手順を実施します。
事前作業として、VPC+Subnet 、GCE インスタンス、CloudSQL インスタンスを作成しておきます。

Cloud SQL Auth Proxyとは

承認済みネットワークや SSL(Secure Socket Layer)の構成を必要とせず、安全にインスタンスにアクセスできる Cloud SQL コネクタのことです。
これを使用することによって、Cloud SQL と他のリソース(VM インスタンスやコンテナ等)を暗号化された通信によって安全に接続することができます。
また、Identity and Access Management(以下、IAM)権限を活用した認証認可を提供し、データベースへのアクセスを制御することもできます。

作業の流れ

以下の Google Cloud 公式ドキュメントを参照し、下記の 1 〜 7 の流れで作業をしました。

https://cloud.google.com/sql/docs/postgres/sql-proxy?hl=ja

  1. プロジェクトで Cloud SQL Admin API を有効化する。

    • コンソール上で「API とサービス」に移動する。
      image002
    • トップの上側「+API とサービスを有効にする」を押下する。
      image003
    • Cloud SQL Admin API を検索して有効化する。
      image004
      image005
  2. サービス アカウントに Cloud SQL クライアント ロールを付与する。

    • あらかじめ当該ロールを付与するための任意のサービス アカウントを作成しておく。
      image006
    • IAM と管理からプロジェクトの IAM を表示し、「アクセス権を付与」を押下する。
      image007
    • 「ロールを割り当てる」から、あらかじめ作成したサービス アカウントに対し「Cloud SQL クライアント」を割り当てて保存する。
      image008
  3. VM の API を有効化する。

    • あらかじめ作成しておいた VM を停止する。
      image009
      image010

    • VM のインスタンス詳細画面から「編集」を押下する。
      image011

    • 「Identity and API access > サービス アカウント」を作成したサービス アカウントに変更し保存する。
      image012

    • VM を再開する。
      image013

  4. Cloud SQL Auth Proxy、MySQL を VM にインストールする。

    • VM に SSH ログインする。
      image014
      image015
      image016

    ※IAP(Identity aware Proxy)経由の通信を許可する FW(Firewall)設定を追加していない場合は追加すること。(例では対象のサービス アカウントをターゲットとし、35.235.240.0/20 から上りの tcp:22 を許可する通信ルールを設定。)
    image017

    • VM で以下コマンドを発行する。
      • Cloud SQL Auth Proxy のインストール

        • curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.7.1/cloud-sql-proxy.linux.amd64
          ※最新バージョンは都度変わるので注意すること。
        • chmod +x cloud-sql-proxy
      • MySQL のインストール

        • sudo apt-get update
        • sudo apt-get -y install default-mysql-server
  5. Cloud SQL Auth Proxy を起動、別ウインドウで MySQL コマンドを発行し DB への疎通確認を実施する。

    • 以下コマンドを発行し Cloud SQL Auth Proxy を起動する。

      • ./cloud-sql-proxy --port 3307 <プロジェクト名>:<リージョン>:<DB インスタンス名> --private-ip
    • 別ウインドウで SSH を起動し、VM で以下コマンドを発行し DB へ接続する。

      • mysql -u <DB ユーザー名> -p --host 127.0.0.1
      • PW を聞かれるので PW を入力する。
  6. Cloud SQL Auth Proxy をサービス化して常時プロセス起動させる。

    • 以下のコマンドを発行してフォルダを作成し、必要なファイルを編集する。

      • sudo ls /etc/systemd/system/cloud_sql_proxy
      • sudo mkdir /etc/systemd/system/cloud_sql_proxy
        ※ひとつ前のコマンドでフォルダが存在しなければ作成する。
      • sudo vi /etc/systemd/system/cloud_sql_proxy\@.service
        ※中身は以下。
      [Unit]
      Description = CloudSQL Proxy %i
      After = network.target
      
      [Service]
      ExecStart = /home/[ユーザ名]/cloud-sql-proxy --port 3307 <プロジェクト名>:<リージョン>:<DB インスタンス名> --private-ip
      ExecStop = /bin/kill ${MAINPID}
      ExecReload = /bin/kill -HUP ${MAINPID}
      Restart = always
      Type = simple
      
      [Install]
      WantedBy = multi-user.target
      
    • 以下を実行し、サービス化したプロセスが正常起動していることを確認する。
      sudo systemctl status cloud_sql_proxy@<DB インスタンス名>.service
      ※コマンドの出力結果が "Active: active(running)" になっていれば OK。

  7. VM を再起動しても前項目の設定が効いていることを確認したうえ、MySQL コマンドを発行し DB への疎通確認を実施する。

    • sudo systemctl status cloud_sql_proxy@<DB インスタンス名>.service
    • mysql -u < DB ユーザー名> -p --host 127.0.0.1

ハマったポイント

    1. の Cloud SQL Admin API の有効化漏れ。
    • 作業自体は単純ですが、これをしないまま VM の設定をし始めてしまうと DB 接続時に googleapi: Error 403: Cloud SQL Admin API has not been used in project・・・ というエラーが出て接続に失敗します。
    1. では GCE の VM のデフォルト サービス アカウントは使用せず、別途サービス アカウントを作って作業する。
    • デフォルト サービス アカウントには IAM の組み込みロールである「編集者」が自動で付与されます。「編集者」は広範なリソースに対して編集権限を持っているため、今回の用途では必要以上に権限を持ち過ぎてしまうことになり、セキュリティ観点で望ましくない実装になってしまいます。

https://cloud.google.com/compute/docs/access/service-accounts?hl=ja#default_service_account

    1. Cloud SQL Auth Proxy のサービス化では、@.service ファイルの記述を試行錯誤しました。
    • cloud-sql-proxy のプロセスを起動する以下の行に"--private-ip"の記述が漏れていて、接続に失敗していることがわかりました。
      ExecStart = /home/[ユーザ名]/cloud-sql-proxy --port 3307 <プロジェクト名>:<リージョン>:<DB インスタンス名> --private-ip
    • @.service ファイルの記述を修正して、以下オペレーションを繰り返し、systemd のプロセスが正しく動くまで確認しました。
      @.service ファイルの記述を直す
      sudo systemctl daemon-reload
      sudo systemctl start cloud_sql_proxy@<DB インスタンス名>.service
      sudo systemctl status cloud_sql_proxy@<DB インスタンス名>.service

おわりに

今回は Cloud SQL Auth Proxy を使った VM からのプライベート DB 接続の方法について記載しました。
よく使いそうな実装方法だとは思うのですが、Google の公式サイトの解説や他記事を読んでいて少しつまずくポイントもあったので、本記事にて自身の作業を振り返るとともに記載をしてみました。
同じような要件を実装される方の一助になれば幸いです。

Discussion