Google Kubernetes Engine から接続する

このページでは、Google Kubernetes Engine(GKE)で実行中のアプリケーションから Cloud SQL インスタンスへの接続を設定する方法について説明します。

Cloud SQL に接続された Google Kubernetes Engine のサンプル ウェブ アプリケーションを実行する手順ガイドについては、Google Kubernetes Engine から接続するためのクイックスタートをご覧ください。

Cloud SQL は、クラウド内のリレーショナル データベースの設定、維持、管理に役立つフルマネージド データベース サービスです。

Google Kubernetes Engine を使用すると、簡単に Kubernetes を自動的にデプロイ、スケーリング、管理できます。

Google Kubernetes Engine から Cloud SQL への接続について

Google Kubernetes Engine で動作しているアプリケーションから Cloud SQL インスタンスにアクセスするには、(パブリック IP またはプライベート IP で)Cloud SQL Auth Proxyを使用するか、プライベート IP アドレスを使用して直接接続します。

プライベート IP を使用している場合でも、Cloud SQL への接続には、Cloud SQL Auth Proxy を使用することをおすすめします。これは、Cloud SQL Auth Proxy により IAM を使用した強力な暗号化と認証が提供され、データベースを安全に保つためです。

データベース接続は、サーバーと接続元アプリケーションのリソースを消費します。アプリケーションのフットプリントを最小限に抑え、Cloud SQL の接続制限を超える可能性を少なくするには、常に適切な接続管理方法を採用してください。詳細については、データベース接続の管理をご覧ください。

始める前に

Cloud SQL に接続するには、次に挙げるものが必要です。

  • kubectl コマンドライン ツールがインストールされ、クラスタと通信するように構成された GKE クラスタ。

    GKE の使用開始方法については、アプリを GKE クラスタにデプロイするをご覧ください。

    プライベート IP を使用して接続する場合、GKE クラスタは VPC ネイティブであり、Cloud SQL インスタンスと同じ Virtual Private Cloud(VPC)ネットワークとピアリングされている必要があります。

  • 作成されたインスタンス

    Cloud SQL インスタンスの作成方法については、インスタンスを作成するをご覧ください。

  • インスタンスに構成された PostgreSQL のユーザー アカウント。

    アプリケーションは、このアカウントを使用してデータベースに接続します。ユーザー アカウントの作成方法については、ユーザーを作成するをご覧ください。

Kubernetes Secret について

Kubernetes では、Secret は構成の詳細をアプリケーションに渡す安全な方法です。アプリケーションに環境変数として挿入できるデータベース名、ユーザー、パスワードなどの詳細を含む Secret を作成できます。

接続タイプに応じて、Secret を使用するには、さまざまな方法があります。

  • データベース認証情報の Secret には、接続するデータベースのユーザーの名前とユーザーのデータベースのパスワードが含まれます。
  • Cloud SQL Auth Proxy で接続する場合、Secret を使用してサービス アカウントの認証情報ファイルを保持できます。
  • プライベート IP で接続する場合は、Secret を使用して Cloud SQL インスタンスのプライベート IP アドレスを指定できます。

Secret の使用方法の詳細な例については、このページで後述する GitHub リポジトリをご覧ください。

Secret オブジェクトを作成する

  1. kubectl create secret コマンドを使用して Secret オブジェクトを作成します。

    データベース認証情報 Secret を作成するには:

    kubectl create secret generic <YOUR-DB-SECRET> \
      --from-literal=username=<YOUR-DATABASE-USER> \
      --from-literal=password=<YOUR-DATABASE-PASSWORD> \
      --from-literal=database=<YOUR-DATABASE-NAME>
    
  2. オブジェクトを作成すると、Google Cloud コンソールの Google Kubernetes Engine ページの [構成] セクションでオブジェクトを表示できます。

Cloud SQL Auth Proxy を使用して Cloud SQL に接続する

Cloud SQL Auth Proxy を使用して接続する場合、Cloud SQL Auth Proxy は、sidecar コンテナ パターンを使用して Pod に追加されます。Cloud SQL Auth Proxy コンテナはアプリケーションと同じ Pod にあるため、アプリケーションは localhost を使用して Cloud SQL Auth Proxy に接続できます。これにより、セキュリティとパフォーマンスが向上します。

Cloud SQL Auth Proxy の詳細については、Cloud SQL Auth Proxy についてをご覧ください。Pod の操作の詳細については、Kubernetes ドキュメントの Pod の概要をご覧ください。

Cloud SQL Auth Proxy を使用して接続する場合は、次のものが必要です。

  1. Cloud SQL インスタンスのインスタンス接続名。

    インスタンスの接続名は、Google Cloud コンソールの [Cloud SQL インスタンスの詳細] ページ、または gcloud sql instances describe INSTANCE_ID コマンドを実行して確認できます。

  2. Cloud SQL インスタンスの適切な権限を持つサービス アカウントに関連付けられた鍵ファイルの場所。

    詳細については、サービス アカウントの作成をご覧ください。

  3. Cloud SQL Admin API が有効になっていること。

    API を有効にする

Cloud SQL Auth Proxy にサービス アカウントを提供する

Google Kubernetes Engine で Cloud SQL Auth Proxy を動作させるための最初の手順は、アプリケーションを表す Google サービス アカウント(GSA)を作成することです。どこでも同じサービス アカウントを使用するのではなく、各アプリケーションに固有のサービス アカウントを作成することをおすすめします。このモデルは、アプリケーションごとに権限を制限できるため、より安全です。

アプリケーション用のサービス アカウントは、次の条件を満たす必要があります。

  • Cloud SQL Admin API が有効になっているプロジェクトに所属している
  • 接続するインスタンスを含むプロジェクトについて、Cloud SQL Client IAM ロール(または同等の権限)が付与されている
  • プライベート IP を使用して接続する場合は、Cloud SQL インスタンスと同じ VPC で VPC ネイティブ GKE クラスタを使用する必要がある

サービス アカウントを Cloud SQL Auth Proxy に提供するように GKE を構成する必要があります。これを行う方法として、Workload Identity またはサービス アカウント キー ファイルの 2 つをおすすめします。

Workload Identity

Google Kubernetes Engine を使用している場合は、GKE の Workload Identity 機能を使用する方法をおすすめします。この方法では、Kubernetes サービス アカウント(KSA)Google サービス アカウント(GSA)にバインドできます。これにより、一致する KSA を使用するアプリケーションに GSA がアクセスできるようになります。

Google サービス アカウント(GSA)は、Google Cloud で自身のアプリケーションを表す IAM ID です。同様に、Kubernetes サービス アカウント(KSA)は、Google Kubernetes Engine クラスタ内で自身のアプリケーションを表す ID です。

Workload Identity は KSA を GSA にバインドし、Google Cloud とのやり取りでは、その KSA を含むデプロイメントに GSA として認証させます。

  1. クラスタの Workload Identity を有効にします
  2. 通常、それぞれのアプリケーションには固有の ID があり、KSA と GSA のペアで表現されます。kubectl apply -f service-account.yaml を実行して、アプリケーションの KSA を作成します。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: <YOUR-KSA-NAME> # TODO(developer): replace these values
  3. YOUR-GSA-NAMEYOUR-KSA-NAME の間の IAM バインディングを有効にします。

    gcloud iam service-accounts add-iam-policy-binding \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:YOUR-GOOGLE-CLOUD-PROJECT.svc.id.goog[YOUR-K8S-NAMESPACE/YOUR-KSA-NAME]" \
    YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
    
  4. YOUR-KSA-NAME にアノテーションを追加して、バインドを完了します。

    kubectl annotate serviceaccount \
    YOUR-KSA-NAME \
    iam.gke.io/gcp-service-account=YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
    
  5. 最後に、K8s オブジェクトのサービス アカウントを指定します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: <YOUR-DEPLOYMENT-NAME>
    spec:
      selector:
        matchLabels:
          app: <YOUR-APPLICATION-NAME>
      template:
        metadata:
          labels:
            app: <YOUR-APPLICATION-NAME>
        spec:
          serviceAccountName: <YOUR-KSA-NAME>

サービス アカウント キーファイル

また、Workload Identity を使用できない場合は、サービス アカウント キー ファイルを Cloud SQL Auth Proxy の Pod にマウントし、-credential_file フラグを使用することをおすすめします。

  1. サービス アカウント キーの認証情報ファイルを作成します。

    gcloud iam service-accounts keys create ~/key.json \
    --iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com
    
  2. サービス アカウント キーを K8s Secret に変換します。

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
    
  3. Secret を K8s オブジェクトの spec: の下に Volume としてマウントします。

    volumes:
    - name: <YOUR-SA-SECRET-VOLUME>
      secret:
        secretName: <YOUR-SA-SECRET>
  4. Cloud SQL Auth Proxy の Pod から Volume にアクセスするには、次のセクションの手順を行ってください。

サイドカー パターンで Cloud SQL Auth Proxy を実行する

Cloud SQL Auth Proxy は、sidecar パターンで(Pod をアプリケーションと共有する追加のコンテナとして)動作させることをおすすめします。次のいくつかの理由から、これを個別のサービスとして実行するよりも、この方法をおすすめします。

  • SQL トラフィックがローカルで公開されないようにします。Cloud SQL Auth Proxy は送信接続を暗号化しますが、受信接続の公開を制限する必要があります。
  • 単一障害点を回避します。各アプリケーションのデータベースへのアクセスは他のアプリケーションから独立しているため、復旧しやすくなります。
  • Cloud SQL Auth Proxy へのアクセスを制限し、データベースをクラスタ全体に公開するのではなく、アプリケーションごとに IAM 権限を使用できるようにします。
  • リソース リクエストをより正確にスコープできます。Cloud SQL Auth Proxy はリソースを使用量に比例して消費するため、このパターンにより、アプリケーションのスケーリングに合わせて、リソースをより正確にスコープして、リクエストできます。

  • containers で、Cloud SQL Auth Proxy を Pod の構成に追加します。

    - name: cloud-sql-proxy
      # It is recommended to use the latest version of the Cloud SQL Auth Proxy
      # Make sure to update on a regular schedule!
      image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0
      args:
        # If connecting from a VPC-native GKE cluster, you can use the
        # following flag to have the proxy connect over private IP
        # - "--private-ip"
    
        # Enable structured logging with LogEntry format:
        - "--structured-logs"
    
        # Replace DB_PORT with the port the proxy should listen on
        - "--port=<DB_PORT>"
        - "<INSTANCE_CONNECTION_NAME>"
    
      securityContext:
        # The default Cloud SQL Auth Proxy image runs as the
        # "nonroot" user and group (uid: 65532) by default.
        runAsNonRoot: true
      # You should use resource requests/limits as a best practice to prevent
      # pods from consuming too many resources and affecting the execution of
      # other pods. You should adjust the following values based on what your
      # application needs. For details, see
      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
      resources:
        requests:
          # The proxy's memory use scales linearly with the number of active
          # connections. Fewer open connections will use less memory. Adjust
          # this value based on your application's requirements.
          memory: "2Gi"
          # The proxy's CPU use scales linearly with the amount of IO between
          # the database and the application. Adjust this value based on your
          # application's requirements.
          cpu:    "1"

    サービス アカウント キーを使用している場合は、Secret ボリュームを指定して、コマンドに -credential_file フラグを追加します。

      # This flag specifies where the service account key can be found
      - "--credentials-file=/secrets/service_account.json"
    securityContext:
      # The default Cloud SQL Auth Proxy image runs as the
      # "nonroot" user and group (uid: 65532) by default.
      runAsNonRoot: true
    volumeMounts:
    - name: <YOUR-SA-SECRET-VOLUME>
      mountPath: /secrets/
      readOnly: true
  • IAM データベース認証を使用している場合は、-enable_iam_login フラグを使用して Cloud SQL Auth Proxy を起動します。
  • 最後に、コマンド セクションで指定したどちらの DB_PORT でも、127.0.0.1 を使用して接続するようにアプリケーションを構成します。

サンプル構成ファイルを完成させます。

Workload Identity

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      serviceAccountName: <YOUR-KSA-NAME>
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
      - name: cloud-sql-proxy
        # It is recommended to use the latest version of the Cloud SQL Auth Proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0
        args:
          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "--private-ip"

          # Enable structured logging with LogEntry format:
          - "--structured-logs"

          # Replace DB_PORT with the port the proxy should listen on
          - "--port=<DB_PORT>"
          - "<INSTANCE_CONNECTION_NAME>"

        securityContext:
          # The default Cloud SQL Auth Proxy image runs as the
          # "nonroot" user and group (uid: 65532) by default.
          runAsNonRoot: true
        # You should use resource requests/limits as a best practice to prevent
        # pods from consuming too many resources and affecting the execution of
        # other pods. You should adjust the following values based on what your
        # application needs. For details, see
        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        resources:
          requests:
            # The proxy's memory use scales linearly with the number of active
            # connections. Fewer open connections will use less memory. Adjust
            # this value based on your application's requirements.
            memory: "2Gi"
            # The proxy's CPU use scales linearly with the amount of IO between
            # the database and the application. Adjust this value based on your
            # application's requirements.
            cpu:    "1"

サービス アカウント キー

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
      - name: cloud-sql-proxy
        # It is recommended to use the latest version of the Cloud SQL Auth Proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0
        args:
          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "--private-ip"

          # Enable structured logging with LogEntry format:
          - "--structured-logs"

          # Replace DB_PORT with the port the proxy should listen on
          - "--port=<DB_PORT>"
          - "<INSTANCE_CONNECTION_NAME>"

          # This flag specifies where the service account key can be found
          - "--credentials-file=/secrets/service_account.json"
        securityContext:
          # The default Cloud SQL Auth Proxy image runs as the
          # "nonroot" user and group (uid: 65532) by default.
          runAsNonRoot: true
        volumeMounts:
        - name: <YOUR-SA-SECRET-VOLUME>
          mountPath: /secrets/
          readOnly: true
        # Resource configuration depends on an application's requirements. You
        # should adjust the following values based on what your application
        # needs. For details, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        resources:
          requests:
            # The proxy's memory use scales linearly with the number of active
            # connections. Fewer open connections will use less memory. Adjust
            # this value based on your application's requirements.
            memory: "2Gi"
            # The proxy's CPU use scales linearly with the amount of IO between
            # the database and the application. Adjust this value based on your
            # application's requirements.
            cpu:    "1"
      volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>

Cloud SQL Auth Proxy を使用せずに Cloud SQL に接続する

安全性は低下しますが、VPC ネイティブ GKE クラスタから、Cloud SQL Auth Proxy を使用しないプライベート IP を使用して、同じ VPC 上の Cloud SQL インスタンスに接続できます。

  1. インスタンスのプライベート IP アドレスを使用して Secret を作成します。

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. 次に、Secret をアプリケーションのコンテナに追加します。

    - name: DB_HOST
      valueFrom:
        secretKeyRef:
          name: <YOUR-PRIVATE-IP-SECRET>
          key: db_host
  3. 最後に、DB_HOST 環境変数の IP アドレスを使用して接続するようにアプリケーションを構成します。PostgreSQL の正しいポート(5432)を使用する必要があります。

サンプル構成ファイルを完成させます。

プライベート IP

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: <YOUR-PRIVATE-IP-SECRET>
              key: db_host

トラブルシューティング

お困りの場合、プロキシのトラブルシューティングについては、Cloud SQL Auth Proxy 接続のトラブルシューティングまたは Cloud SQL のサポートページをご覧ください。

次のステップ