高可用性 PostgreSQL データベースを GKE にデプロイする


PostgreSQL は、信頼性とデータの整合性で有名なオープンソースのオブジェクト リレーショナル データベースです。ACID に準拠し、外部キー、結合、ビュー、トリガー、ストアド プロシージャをサポートしています。

このドキュメントは、高可用性 PostgreSQL トポロジを Google Kubernetes Engine にデプロイすることに関心があるデータベース管理者、クラウド アーキテクト、運用の担当者を対象としています。

目標

このチュートリアルの学習内容は次のとおりです。

  • Terraform を使用して GKE のリージョン クラスタを作成する。
  • 高可用性 PostgreSQL データベースをデプロイする。
  • PostgreSQL アプリケーションのモニタリングを設定する。
  • PostgreSQL データベースと GKE クラスタのアップグレードを実行する。
  • クラスタの中断と PostgreSQL レプリカのフェイルオーバーをシミュレートする。
  • PostgreSQL データベースのバックアップと復元を行う。

アーキテクチャ

このセクションでは、このチュートリアルで構築するソリューションのアーキテクチャについて説明します。

2 つの GKE クラスタを異なるリージョン(プライマリ クラスタとバックアップ クラスタ)にプロビジョニングします。このチュートリアルでは、プライマリ クラスタは us-central1 リージョンにあり、バックアップ クラスタは us-west1 リージョンにあります。このアーキテクチャでは、このチュートリアルで後述するように、高可用性 PostgreSQL データベースをプロビジョニングし、障害復旧をテストできます。

ソースクラスタの場合は、Helm チャート(bitnami/postgresql-ha)を使用して、高可用性 PostgreSQL クラスタを設定します。

高可用性 PostgreSQL クラスタのアーキテクチャの例を示す図。
図 1: 高可用性 PostgreSQL クラスタのアーキテクチャの例

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

プロジェクトを設定する

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.

    Enable the APIs

ロールを設定する

  1. Grant roles to your user account. Run the following command once for each of the following IAM roles: role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin

    $ gcloud projects add-iam-policy-binding PROJECT_ID --member="USER_IDENTIFIER" --role=ROLE
    • Replace PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.

環境を設定する

このチュートリアルでは、Cloud Shell を使用して Google Cloud でホストされるリソースを管理します。Cloud Shell には、Dockerkubectlgcloud CLIHelmTerraform を含む、このチュートリアルに必要なソフトウェアがプリインストールされています。

Cloud Shell を使用して環境を設定する方法は次のとおりです。

  1. Google Cloud コンソールで「Cloud Shell をアクティブにする」アイコン Cloud Shell 有効化アイコン をクリックして、Google Cloud コンソールから Cloud Shell セッションを起動します。これにより、Google Cloud コンソールの下部ペインでセッションが起動します。

  2. 環境変数を設定します。

    export PROJECT_ID=PROJECT_ID
    export SOURCE_CLUSTER=cluster-db1
    export REGION=us-central1
    

    次の値を置き換えます。

  3. デフォルトの環境変数を設定します。

    gcloud config set project PROJECT_ID
    
  4. コード リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  5. 作業ディレクトリを変更します。

    cd kubernetes-engine-samples/databases/gke-stateful-postgres
    

クラスタ インフラストラクチャを作成する

このセクションでは、Terraform スクリプトを実行して、カスタム Virtual Private Cloud(VPC)、PostgreSQL イメージを保存する Artifact Registry リポジトリ、および 2 つの GKE リージョン クラスタを作成します。1 つ目のクラスタは us-central1 にデプロイされ、バックアップ用の 2 つ目のクラスタは us-west1 にデプロイされます。

クラスタの作成手順は次のとおりです。

Autopilot

Cloud Shell で、次のコマンドを実行します。

terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply -var project_id=$PROJECT_ID

プロンプトが表示されたら、「yes」と入力します。

Terraform の構成を理解する

Terraform 構成ファイルは、次のリソースを作成して、インフラストラクチャをデプロイします。

  • Docker イメージを保存するための Artifact Registry リポジトリを作成します。
    resource "google_artifact_registry_repository" "main" {
      location      = "us"
      repository_id = "main"
      format        = "DOCKER"
      project       = var.project_id
    }
  • VM のネットワーク インターフェース用に VPC ネットワークとサブネットを作成します。
    module "gcp-network" {
      source  = "terraform-google-modules/network/google"
      version = "< 8.0.0"
    
      project_id   = var.project_id
      network_name = "vpc-gke-postgresql"
    
      subnets = [
        {
          subnet_name           = "snet-gke-postgresql-us-central1"
          subnet_ip             = "10.0.0.0/17"
          subnet_region         = "us-central1"
          subnet_private_access = true
        },
        {
          subnet_name           = "snet-gke-postgresql-us-west1"
          subnet_ip             = "10.0.128.0/17"
          subnet_region         = "us-west1"
          subnet_private_access = true
        },
      ]
    
      secondary_ranges = {
        ("snet-gke-postgresql-us-central1") = [
          {
            range_name    = "ip-range-pods-db1"
            ip_cidr_range = "192.168.0.0/18"
          },
          {
            range_name    = "ip-range-svc-db1"
            ip_cidr_range = "192.168.64.0/18"
          },
        ],
        ("snet-gke-postgresql-us-west1") = [
          {
            range_name    = "ip-range-pods-db2"
            ip_cidr_range = "192.168.128.0/18"
          },
          {
            range_name    = "ip-range-svc-db2"
            ip_cidr_range = "192.168.192.0/18"
          },
        ]
      }
    }
    
    output "network_name" {
      value = module.gcp-network.network_name
    }
    
    output "primary_subnet_name" {
      value = module.gcp-network.subnets_names[0]
    }
    
    output "secondary_subnet_name" {
      value = module.gcp-network.subnets_names[1]
    }
  • プライマリ GKE クラスタを作成します。

    Terraform は us-central1 リージョンに限定公開クラスタを作成し、Backup for GKE で障害復旧を、Managed Service for Prometheus でクラスタのモニタリングを有効にします。

    Managed Service for Prometheus は、GKE バージョン 1.25 以降を実行している Autopilot クラスタでのみサポートされます。

    module "gke-db1-autopilot" {
      source                          = "../modules/beta-autopilot-private-cluster"
      project_id                      = var.project_id
      name                            = "cluster-db1"
      kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
      region                          = "us-central1"
      regional                        = true
      zones                           = ["us-central1-a", "us-central1-b", "us-central1-c"]
      network                         = module.network.network_name
      subnetwork                      = module.network.primary_subnet_name
      ip_range_pods                   = "ip-range-pods-db1"
      ip_range_services               = "ip-range-svc-db1"
      horizontal_pod_autoscaling      = true
      release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
      enable_vertical_pod_autoscaling = true
      enable_private_endpoint         = false
      enable_private_nodes            = true
      master_ipv4_cidr_block          = "172.16.0.0/28"
      create_service_account          = false
    }

  • 障害復旧のために us-west1 リージョンにバックアップ クラスタを作成します。

    module "gke-db2-autopilot" {
      source                          = "../modules/beta-autopilot-private-cluster"
      project_id                      = var.project_id
      name                            = "cluster-db2"
      kubernetes_version              = "1.25" # Will be ignored if use "REGULAR" release_channel
      region                          = "us-west1"
      regional                        = true
      zones                           = ["us-west1-a", "us-west1-b", "us-west1-c"]
      network                         = module.network.network_name
      subnetwork                      = module.network.secondary_subnet_name
      ip_range_pods                   = "ip-range-pods-db2"
      ip_range_services               = "ip-range-svc-db2"
      horizontal_pod_autoscaling      = true
      release_channel                 = "RAPID" # Default version is 1.22 in REGULAR. GMP on Autopilot requires V1.25 via var.kubernetes_version
      enable_vertical_pod_autoscaling = true
      enable_private_endpoint         = false
      enable_private_nodes            = true
      master_ipv4_cidr_block          = "172.16.0.16/28"
      create_service_account          = false
    }

Standard

Cloud Shell で、次のコマンドを実行します。

terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply -var project_id=$PROJECT_ID

プロンプトが表示されたら、「yes」と入力します。

Terraform の構成を理解する

Terraform 構成ファイルは、次のリソースを作成して、インフラストラクチャをデプロイします。

  • Docker イメージを保存するための Artifact Registry リポジトリを作成します。
    resource "google_artifact_registry_repository" "main" {
      location      = "us"
      repository_id = "main"
      format        = "DOCKER"
      project       = var.project_id
    }
    resource "google_artifact_registry_repository_iam_binding" "binding" {
      provider   = google-beta
      project    = google_artifact_registry_repository.main.project
      location   = google_artifact_registry_repository.main.location
      repository = google_artifact_registry_repository.main.name
      role       = "roles/artifactregistry.reader"
      members = [
        "serviceAccount:${module.gke-db1.service_account}",
      ]
    }
  • VM のネットワーク インターフェース用に VPC ネットワークとサブネットを作成します。
    module "gcp-network" {
      source  = "terraform-google-modules/network/google"
      version = "< 8.0.0"
    
      project_id   = var.project_id
      network_name = "vpc-gke-postgresql"
    
      subnets = [
        {
          subnet_name           = "snet-gke-postgresql-us-central1"
          subnet_ip             = "10.0.0.0/17"
          subnet_region         = "us-central1"
          subnet_private_access = true
        },
        {
          subnet_name           = "snet-gke-postgresql-us-west1"
          subnet_ip             = "10.0.128.0/17"
          subnet_region         = "us-west1"
          subnet_private_access = true
        },
      ]
    
      secondary_ranges = {
        ("snet-gke-postgresql-us-central1") = [
          {
            range_name    = "ip-range-pods-db1"
            ip_cidr_range = "192.168.0.0/18"
          },
          {
            range_name    = "ip-range-svc-db1"
            ip_cidr_range = "192.168.64.0/18"
          },
        ],
        ("snet-gke-postgresql-us-west1") = [
          {
            range_name    = "ip-range-pods-db2"
            ip_cidr_range = "192.168.128.0/18"
          },
          {
            range_name    = "ip-range-svc-db2"
            ip_cidr_range = "192.168.192.0/18"
          },
        ]
      }
    }
    
    output "network_name" {
      value = module.gcp-network.network_name
    }
    
    output "primary_subnet_name" {
      value = module.gcp-network.subnets_names[0]
    }
    
    output "secondary_subnet_name" {
      value = module.gcp-network.subnets_names[1]
    }
  • プライマリ GKE クラスタを作成します。

    Terraform は us-central1 リージョンに限定公開クラスタを作成し、Backup for GKE で障害復旧を、Managed Service for Prometheus でクラスタのモニタリングを有効にします。

    module "gke-db1" {
      source                   = "../modules/beta-private-cluster"
      project_id               = var.project_id
      name                     = "cluster-db1"
      regional                 = true
      region                   = "us-central1"
      network                  = module.network.network_name
      subnetwork               = module.network.primary_subnet_name
      ip_range_pods            = "ip-range-pods-db1"
      ip_range_services        = "ip-range-svc-db1"
      create_service_account   = true
      enable_private_endpoint  = false
      enable_private_nodes     = true
      master_ipv4_cidr_block   = "172.16.0.0/28"
      network_policy           = true
      cluster_autoscaling = {
        "autoscaling_profile": "OPTIMIZE_UTILIZATION",
        "enabled" : true,
        "gpu_resources" : [],
        "min_cpu_cores" : 36,
        "min_memory_gb" : 144,
        "max_cpu_cores" : 48,
        "max_memory_gb" : 192,
      }
      monitoring_enable_managed_prometheus = true
      gke_backup_agent_config = true
    
      node_pools = [
        {
          name            = "pool-sys"
          autoscaling     = true
          min_count       = 1
          max_count       = 3
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-4"
          node_locations  = "us-central1-a,us-central1-b,us-central1-c"
          auto_repair     = true
        },
        {
          name            = "pool-db"
          autoscaling     = true
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-8"
          node_locations  = "us-central1-a,us-central1-b,us-central1-c"
          auto_repair     = true
        },
      ]
      node_pools_labels = {
        all = {}
        pool-db = {
          "app.stateful/component" = "postgresql"
        }
        pool-sys = {
          "app.stateful/component" = "postgresql-pgpool"
        }
      }
      node_pools_taints = {
        all = []
        pool-db = [
          {
            key    = "app.stateful/component"
            value  = "postgresql"
            effect = "NO_SCHEDULE"
          },
        ],
        pool-sys = [
          {
            key    = "app.stateful/component"
            value  = "postgresql-pgpool"
            effect = "NO_SCHEDULE"
          },
        ],
      }
      gce_pd_csi_driver = true
    }

  • 障害復旧のために us-west1 リージョンにバックアップ クラスタを作成します。

    module "gke-db2" {
      source                   = "../modules/beta-private-cluster"
      project_id               = var.project_id
      name                     = "cluster-db2"
      regional                 = true
      region                   = "us-west1"
      network                  = module.network.network_name
      subnetwork               = module.network.secondary_subnet_name
      ip_range_pods            = "ip-range-pods-db2"
      ip_range_services        = "ip-range-svc-db2"
      create_service_account   = false
      service_account          = module.gke-db1.service_account
      enable_private_endpoint  = false
      enable_private_nodes     = true
      master_ipv4_cidr_block   = "172.16.0.16/28"
      network_policy           = true
      cluster_autoscaling = {
        "autoscaling_profile": "OPTIMIZE_UTILIZATION",
        "enabled" : true,
        "gpu_resources" : [],
        "min_cpu_cores" : 10,
        "min_memory_gb" : 144,
        "max_cpu_cores" : 48,
        "max_memory_gb" : 192,
      }
      monitoring_enable_managed_prometheus = true
      gke_backup_agent_config = true
      node_pools = [
        {
          name            = "pool-sys"
          autoscaling     = true
          min_count       = 1
          max_count       = 3
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-4"
          node_locations  = "us-west1-a,us-west1-b,us-west1-c"
          auto_repair     = true
        },
        {
          name            = "pool-db"
          autoscaling     = true
          max_surge       = 1
          max_unavailable = 0
          machine_type    = "e2-standard-8"
          node_locations  = "us-west1-a,us-west1-b,us-west1-c"
          auto_repair     = true
        },
      ]
      node_pools_labels = {
        all = {}
        pool-db = {
          "app.stateful/component" = "postgresql"
        }
        pool-sys = {
          "app.stateful/component" = "postgresql-pgpool"
        }
      }
      node_pools_taints = {
        all = []
        pool-db = [
          {
            key    = "app.stateful/component"
            value  = "postgresql"
            effect = "NO_SCHEDULE"
          },
        ],
        pool-sys = [
          {
            key    = "app.stateful/component"
            value  = "postgresql-pgpool"
            effect = "NO_SCHEDULE"
          },
        ],
      }
      gce_pd_csi_driver = true
    }

PostgreSQL をクラスタにデプロイする

このセクションでは、Helm チャートを使用して、PostgreSQL データベース インスタンスをデプロイして、GKE で実行します。

PostgreSQL をインストールする

クラスタに PostgreSQL をインストールするには、次の手順で操作します。

  1. Docker アクセスを構成します。

    gcloud auth configure-docker us-docker.pkg.dev
    
  2. 必要な PostgreSQL Docker イメージを Artifact Registry に入力します。

    ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r0
    ./scripts/gcr.sh bitnami/postgres-exporter 0.11.1-debian-11-r27
    ./scripts/gcr.sh bitnami/pgpool 4.3.3-debian-11-r28
    

    スクリプトにより、次の Bitnami イメージが Helm 用の Artifact Registry に push され、インストールされます。

    • postgresql-repmgr: この PostgreSQL クラスタ ソリューションには、PostgreSQL クラスタでのレプリケーションとフェイルオーバーを管理するためのオープンソース ツールである PostgreSQL レプリケーション マネージャー(repmgr)が含まれています。
    • postgres-exporter: PostgreSQL Exporter は、Prometheus の使用に必要な PostgreSQL 指標を収集します。
    • pgpool: Pgpool-II は PostgreSQL プロキシです。接続プーリングとロード バランシングを提供します。
  3. 正しいイメージがリポジトリに保存されていることを確認します。

    gcloud artifacts docker images list us-docker.pkg.dev/$PROJECT_ID/main \
        --format="flattened(package)"
    

    出力は次のようになります。

    ---
    image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/pgpool
    ---
    image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/postgres-exporter
    ---
    image: us-docker.pkg.dev/h[PROJECT_ID]/main/bitnami/postgresql-repmgr
    
  4. プライマリ クラスタへの kubectl コマンドライン アクセスを構成します。

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --region=$REGION --project=$PROJECT_ID
    
  5. Namespace を作成します。

    export NAMESPACE=postgresql
    kubectl create namespace $NAMESPACE
    
  6. Autopilot クラスタにデプロイする場合は、3 つのゾーンにわたるノード プロビジョニングを構成します。Standard クラスタにデプロイする場合は、この手順をスキップしてください。

    デフォルトでは、Autopilot は 2 つのゾーンにのみリソースをプロビジョニングします。prepareforha.yaml で定義された Deployment により、Autopilot は次の値を設定して、クラスタ内の 3 つのゾーンにノードをプロビジョニングします。

    • replicas:3
    • requiredDuringSchedulingIgnoredDuringExecutiontopologyKey: "topology.kubernetes.io/zone" を指定した podAntiAffinity
    kubectl -n $NAMESPACE apply -f scripts/prepareforha.yaml
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prepare-three-zone-ha
      labels:
        app: prepare-three-zone-ha
        app.kubernetes.io/name: postgresql-ha
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: prepare-three-zone-ha
          app.kubernetes.io/name: postgresql-ha
      template:
        metadata:
          labels:
            app: prepare-three-zone-ha
            app.kubernetes.io/name: postgresql-ha
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - prepare-three-zone-ha
                topologyKey: "topology.kubernetes.io/zone"
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - preference:
                  matchExpressions:
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Scale-Out"
                weight: 1
          nodeSelector:
            app.stateful/component: postgresql
          tolerations:
          - effect: NoSchedule
            key: app.stateful/component
            operator: Equal
            value: postgresql
          containers:
          - name: prepare-three-zone-ha
            image: busybox:latest
            command:
                - "/bin/sh"
                - "-c"
                - "while true; do sleep 3600; done"
            resources:
              limits:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
              requests:
                cpu: "500m"
                ephemeral-storage: "10Mi"
                memory: "0.5Gi"
    
  7. Helm の依存関係を更新します。

    cd helm/postgresql-bootstrap
    helm dependency update
    
  8. Helm によってインストールされるチャートを調べて確認します。

    helm -n postgresql template postgresql . \
      --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
    
  9. Helm チャートをインストールします。

    helm -n postgresql upgrade --install postgresql . \
        --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
    

    出力は次のようになります。

    NAMESPACE: postgresql
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    
  10. PostgreSQL のレプリカが動作していることを確認します。

    kubectl get all -n $NAMESPACE
    

    出力は次のようになります。

    NAME                                                          READY   STATUS    RESTARTS   AGE
    pod/postgresql-postgresql-bootstrap-pgpool-75664444cb-dkl24   1/1     Running   0          8m39s
    pod/postgresql-postgresql-ha-pgpool-6d86bf9b58-ff2bg          1/1     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-0                     2/2     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-1                     2/2     Running   0          8m39s
    pod/postgresql-postgresql-ha-postgresql-2                     2/2     Running   0          8m38s
    
    NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
    service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.99.236    <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.90.20     <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   8m39s
    service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.127.198   <none>        9187/TCP   8m39s
    
    NAME                                                     READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/postgresql-postgresql-bootstrap-pgpool   1/1     1            1           8m39s
    deployment.apps/postgresql-postgresql-ha-pgpool          1/1     1            1           8m39s
    
    NAME                                                                DESIRED   CURRENT   READY   AGE
    replicaset.apps/postgresql-postgresql-bootstrap-pgpool-75664444cb   1         1         1       8m39s
    replicaset.apps/postgresql-postgresql-ha-pgpool-6d86bf9b58          1         1         1       8m39s
    
    NAME                                                   READY   AGE
    statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     8m39s
    

テスト データセットを作成する

このセクションでは、データベースとサンプル値を含むテーブルを作成します。データベースは、このチュートリアルの後半でテストするフェイルオーバー プロセスのテスト データセットとして機能します。

  1. PostgreSQL インスタンスに接続します。

    cd ../../
    ./scripts/launch-client.sh
    

    出力は次のようになります。

    Launching Pod pg-client in the namespace postgresql ...
    pod/pg-client created
    waiting for the Pod to be ready
    Copying script files to the target Pod pg-client ...
    Pod: pg-client is healthy
    
  2. シェル セッションを開始します。

    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  3. データベースとテーブルを作成し、いくつかのテスト行を挿入します。

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
    
  4. 各テーブルの行数を確認します。

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
    

    出力は次のようになります。

    select COUNT(*) from tb01;
     count
    --------
     300000
    (1 row)
    
    select COUNT(*) from tb02;
     count
    --------
     300000
    (1 row)
    
  5. テストデータを生成します。

    export DB=postgres
    pgbench -i -h $HOST_PGPOOL -U postgres $DB -s 50
    

    出力は次のようになります。

    dropping old tables...
    creating tables...
    generating data (client-side)...
    5000000 of 5000000 tuples (100%) done (elapsed 29.85 s, remaining 0.00 s)
    vacuuming...
    creating primary keys...
    done in 36.86 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 31.10 s, vacuum 1.88 s, primary keys 3.86 s).
    
  6. postgres クライアント Pod を終了します。

    exit
    

PostgreSQL をモニタリングする

このセクションでは、PostgreSQL インスタンス用の指標を表示して、アラートを設定します。Google Cloud Managed Service for Prometheus を使用して、モニタリングとアラートを実行します。

指標を表示する

PostgreSQL の Deployment には、postgresql-exporter サイドカー コンテナが含まれています。このコンテナは /metrics エンドポイントを公開します。Google Cloud Managed Service for Prometheus は、このエンドポイントで PostgreSQL Pod をモニタリングするように構成されています。これらの指標は、Google Cloud コンソールのダッシュボードで確認できます。

Google Cloud コンソールには、ダッシュボードの構成を作成して保存する方法がいくつか用意されています。

  • 作成とエクスポート: Google Cloud コンソールでダッシュボードを直接作成してから、コード リポジトリにそれらをエクスポートして保存できます。それには、ダッシュボードのツールバーで JSON エディタを開き、ダッシュボードの JSON ファイルをダウンロードします。
  • ストレージとインポート: JSON ファイルからダッシュボードをインポートできます。それには、[+ ダッシュボードの作成] をクリックし、JSON エディタのメニューを使用して、ダッシュボードの JSON コンテンツをアップロードします。

PostgreSQL アプリケーションと GKE クラスタからのデータを可視化する手順は次のとおりです。

  1. 次のダッシュボードを作成します。

    cd monitoring
    gcloud monitoring dashboards create \
            --config-from-file=dashboard/postgresql-overview.json \
            --project=$PROJECT_ID
    gcloud monitoring dashboards create \
            --config-from-file dashboard/gke-postgresql.json \
            --project $PROJECT_ID
    
  2. Google Cloud コンソールで、Cloud Monitoring ダッシュボードに移動します。Cloud Monitoring ダッシュボードに移動

  3. ダッシュボードのリストから [カスタム] を選択します。次のダッシュボードが表示されます。

    • PostgreSQL の概要: PostgreSQL アプリケーションの指標(データベースの稼働時間、データベースのサイズ、トランザクションのレイテンシなど)を表示します。
    • GKE PostgreSQL クラスタ: PostgreSQL が実行されている GKE クラスタの指標(CPU 使用率、メモリ使用量、ボリューム使用率など)を表示します。
  4. 各リンクをクリックして、生成されたダッシュボードを調べます。

アラートを設定する

アラートを使用すると、アプリケーションの問題をタイムリーに認識できるため、問題をすばやく解決できます。アラート ポリシーを作成して、アラートを受け取る状況と通知方法を指定できます。通知チャンネルを作成して、アラートの送信先を選択することもできます。

このセクションでは、Terraform を使用して次の例のアラートを構成します。

  • db_max_transaction: トランザクションの最大ラグを秒単位でモニタリングします。値が 10 より大きい場合は、アラートがトリガーされます。
  • db_node_up: データベース Pod のステータスをモニタリングします。0 は、Pod がダウンしていることを意味し、アラートがトリガーされます。

アラートを設定する手順は次のとおりです。

  1. Terraform を使用してアラートを構成します。

    EMAIL=YOUR_EMAIL
    cd alerting/terraform
    terraform init
    terraform plan -var project_id=$PROJECT_ID -var email_address=$EMAIL
    terraform apply -var project_id=$PROJECT_ID -var email_address=$EMAIL
    

    次の値を置き換えます。

    • YOUR_EMAIL: メールアドレス。

    出力は次のようになります。

    Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
    
  2. クライアント Pod に接続します。

    cd ../../../
    kubectl exec -it --namespace postgresql pg-client -- /bin/bash
    
  3. 負荷テストを生成して、db_max_transaction アラートをテストします。

    pgbench -i -h $HOST_PGPOOL -U postgres -s 200 postgres
    

    出力は次のようになります。

    dropping old tables...
    creating tables...
    generating data (client-side)...
    20000000 of 20000000 tuples (100%) done (elapsed 163.22 s, remaining 0.00 s)
    vacuuming...
    creating primary keys...
    done in 191.30 s (drop tables 0.14 s, create tables 0.01 s, client-side generate 165.62 s, vacuum 4.52 s, primary keys 21.00 s).
    

    アラートがトリガーされると、件名が「[ALERT] Max Lag of transaction」で始まるメールが YOUR_EMAIL に送信されます。

  4. Google Cloud コンソールで、[アラート ポリシー] ページに移動します。

    [アラート ポリシー] に移動

  5. リスト内のポリシーから db_max_transaction を選択します。チャートから、Prometheus 指標 pg_stat_activity_max_tx_duration/gauge のしきい値の 10 を超える負荷テストの急増が確認できます。

  6. postgres クライアント Pod を終了します。

    exit
    

PostgreSQL と GKE のアップグレードを管理する

PostgreSQL と Kubernetes の両方のバージョンの更新は定期的なスケジュールでリリースされます。運用に関するベスト プラクティスに沿って、ソフトウェア環境を定期的に更新します。デフォルトでは、GKE ではクラスタとノードプールのアップグレードが自動的に管理されます。

PostgreSQL をアップグレードする

このセクションでは、PostgreSQL のバージョン アップグレードを行う方法について説明します。このチュートリアルでは、どの時点でもすべての Pod がダウンすることがないように、Pod のアップグレードにローリング アップデート戦略を使用します。

バージョン アップグレードの手順は次のとおりです。

  1. 更新されたバージョンの postgresql-repmgr イメージを Artifact Registry に push します。新しいバージョンを定義します(例: postgresql-repmgr 15.1.0-debian-11-r1)。

    NEW_IMAGE=us-docker.pkg.dev/$PROJECT_ID/main/bitnami/postgresql-repmgr:15.1.0-debian-11-r1
    ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r1
    
  2. kubectl を使用してローリング アップデートをトリガーします。

    kubectl set image statefulset -n postgresql postgresql-postgresql-ha-postgresql postgresql=$NEW_IMAGE
    kubectl rollout restart statefulsets -n postgresql postgresql-postgresql-ha-postgresql
    kubectl rollout status statefulset -n postgresql postgresql-postgresql-ha-postgresql
    

    StatefulSet により、ローリング アップデートの完了が確認できます(序数の大きいレプリカから小さいものの順)。

    出力は次のようになります。

    Waiting for 1 pods to be ready...
    waiting for statefulset rolling update to complete 1 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    Waiting for 1 pods to be ready...
    Waiting for 1 pods to be ready...
    waiting for statefulset rolling update to complete 2 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    Waiting for 1 pods to be ready...
    Waiting for 1 pods to be ready...
    statefulset rolling update complete 3 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
    

Standard クラスタで GKE のアップグレードを計画する

このセクションは、Standard クラスタを実行している場合に適用されます。ステートフル サービスの実行時に、次のように予防的措置を講じて、リスクを軽減してクラスタのアップグレードをよりスムーズに行うための構成を設定することができます。

Standard クラスタのアップグレード中にデータベースの可用性を確認する

このセクションは、Standard クラスタを実行している場合に適用されます。アップグレード中に PostgreSQL の可用性を検証するには、アップグレード処理中に PostgreSQL データベースに対してトラフィックを生成することが一般的な処理です。その後、pgbench を使用して、データベースが完全に使用可能になったときに比べて、アップグレード中にデータベースがトラフィックのベースライン レベルを処理できることを確認します。

  1. PostgreSQL インスタンスに接続します。

    ./scripts/launch-client.sh
    

    出力は次のようになります。

    Launching Pod pg-client in the namespace postgresql ...
    pod/pg-client created
    waiting for the Pod to be ready
    Copying script files to the target Pod pg-client ...
    Pod: pg-client is healthy
    
  2. Cloud Shell で、クライアント Pod にシェルを追加します。

    kubectl exec -it -n postgresql pg-client -- /bin/bash
    
  3. pgbench を初期化します。

    pgbench -i -h $HOST_PGPOOL -U postgres postgres
    
  4. 次のコマンドを使用して、アップグレードの時間枠内に PostgreSQL アプリケーションの高可用性が維持されていることを確認するベースラインの結果を取得します。ベースラインの結果を取得するには、30 秒間、マルチジョブ(スレッド)を介したマルチ接続でテストします。

    pgbench -h $HOST_PGPOOL -U postgres postgres -c10 -j4 -T 30 -R 200
    

    出力は次のようになります。

    pgbench (14.5)
    starting vacuum...end.
    transaction type: <builtin: TPC-B (sort of)>
    scaling factor: 1
    query mode: simple
    number of clients: 10
    number of threads: 4
    duration: 30 s
    number of transactions actually processed: 5980
    latency average = 7.613 ms
    latency stddev = 2.898 ms
    rate limit schedule lag: avg 0.256 (max 36.613) ms
    initial connection time = 397.804 ms
    tps = 201.955497 (without initial connection time)
    
  5. アップグレード中の可用性を確保するには、データベースに対してある程度の負荷を生成し、PostgreSQL アプリケーションがアップグレード中も一貫した応答率を確実に示すようにします。このテストを行うには、pgbench コマンドを使用して、データベースに対するある程度のトラフィックを生成します。次のコマンドは、200 TPS(1 秒あたりのトランザクション数)を目標に、2 秒ごとにリクエスト率を一覧表示しながら、1 時間 pgbench を実行します。

    pgbench -h $HOST_PGPOOL -U postgres postgres --client=10 --jobs=4 --rate=200 --time=3600 --progress=2 --select-only
    

    各要素の意味は次のとおりです。

    • --client: シミュレートされたクライアントの数、つまりデータベース セッションの同時実行数。
    • --jobs: pgbench 内のワーカー スレッド数。マルチ CPU マシンでは、複数のスレッドの使用が便利です。クライアントは、使用可能なスレッド間でできるだけ均等に分散されます。デフォルトは 1 です。
    • --rate: レートは 1 秒あたりのトランザクション数で指定します。
    • --progress: 進行状況レポートを 1 秒ごとに表示します。

    出力は次のようになります。

    pgbench (14.5)
    starting vacuum...end.
    progress: 5.0 s, 354.8 tps, lat 25.222 ms stddev 15.038
    progress: 10.0 s, 393.8 tps, lat 25.396 ms stddev 16.459
    progress: 15.0 s, 412.8 tps, lat 24.216 ms stddev 14.548
    progress: 20.0 s, 405.0 tps, lat 24.656 ms stddev 14.066
    
  6. Google Cloud コンソールで、Cloud Monitoring の PostgreSQL の概要ダッシュボードに戻ります。DB あたりの接続のグラフと Pod あたりの接続のグラフの急増に注意してください。

  7. クライアント Pod を終了します。

    exit
    
  8. クライアント Pod を削除します。

    kubectl delete pod -n postgresql pg-client
    

PostgreSQL サービスの中断をシミュレートする

このセクションでは、レプリケーション マネージャー サービスを停止して、PostgreSQL レプリカの 1 つでのサービスの中断をシミュレートします。これにより、Pod がピアレプリカにトラフィックを送信できなくなり、liveness プローブも失敗します。

  1. 新しい Cloud Shell セッションを開き、プライマリ クラスタへの kubectl コマンドライン アクセスを構成します。

    gcloud container clusters get-credentials $SOURCE_CLUSTER \
    --region=$REGION --project=$PROJECT_ID
    
  2. Kubernetes で出力された PostgreSQL イベントを表示します。

    kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
    
  3. 以前の Cloud Shell セッションで、PostgreSQL repmgr を停止してサービス障害をシミュレートします。

    1. セッションをデータベース コンテナにアタッチします。

      kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
      
    2. repmgr を使用してサービスを停止し、チェックポイントと dry-run 引数を削除します。

      export ENTRY='/opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh'
      export RCONF='/opt/bitnami/repmgr/conf/repmgr.conf'
      $ENTRY repmgr -f $RCONF node service --action=stop --checkpoint
      

PostgreSQL コンテナ用に構成された liveness プローブが開始して 5 秒以内に失敗します。失敗回数がしきい値の 6 回に達するまで、10 秒ごとにこれが繰り返されます。failureThreshold の値に達すると、コンテナが再起動されます。これらのパラメータを構成して、liveness プローブの許容範囲を下げて、Deployment の SLO 要件を調整できます。

イベント ストリームから、Pod の liveness プローブと readiness プローブが失敗し、コンテナを再起動する必要があるというメッセージが確認できます。出力は次のようになります。

0s          Normal    Killing                pod/postgresql-postgresql-ha-postgresql-0   Container postgresql failed liveness probe, will be restarted
0s          Warning   Unhealthy              pod/postgresql-postgresql-ha-postgresql-0   Readiness probe failed: psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused...
0s          Normal    Pulled                 pod/postgresql-postgresql-ha-postgresql-0   Container image "us-docker.pkg.dev/psch-gke-dev/main/bitnami/postgresql-repmgr:14.5.0-debian-11-r10" already present on machine
0s          Normal    Created                pod/postgresql-postgresql-ha-postgresql-0   Created container postgresql
0s          Normal    Started                pod/postgresql-postgresql-ha-postgresql-0   Started container postgresql

障害復旧に備える

サービス中断イベントの発生時に本番環境のワークロードの可用性を確保するには、障害復旧(DR)計画を準備する必要があります。DR 計画の詳細については、障害復旧計画ガイドをご覧ください。

Kubernetes の障害復旧は、次の 2 つのフェーズで実装できます。

  • バックアップ。サービス中断イベントの発生前に、状態またはデータの特定の時点のスナップショットを作成します。
  • 復旧。障害の発生後に、バックアップ コピーから状態またはデータを復元します。

GKE クラスタでワークロードをバックアップして復元するには、Backup for GKE を使用します。このサービスは、新規および既存のクラスタで有効にできます。これにより、クラスタで実行される Backup for GKE エージェントがデプロイされます。エージェントは、構成とボリュームのバックアップ データの取得と、復旧のオーケストレートを担当します。

バックアップと復元のスコープは、クラスタ全体、Namespace、アプリケーション(matchLabels などのセレクタで定義)に設定できます。

PostgreSQL のバックアップと復元のシナリオの例

このセクションの例では、ProtectedApplication カスタム リソースを使用して、アプリケーション スコープでバックアップと復元の操作を行う方法を紹介しています。

次の図は、ProtectedApplication のコンポーネント リソースを示しています。つまり、postgresql-ha アプリケーションを表す StatefulSet と、同じラベル(app.kubernetes.io/name: postgresql-ha)を使用する pgpool の Deployment を示しています。

高可用性 PostgreSQL クラスタ用のバックアップと復元のソリューションの例を示す図。
図 2: 高可用性 PostgreSQL クラスタのバックアップと復元のソリューションの例

PostgreSQL ワークロードのバックアップと復元を準備する手順は次のとおりです。

  1. 環境変数を設定します。この例では、ProtectedApplication を使用して、PostgreSQL ワークロードとそのボリュームを移行元の GKE クラスタ(us-central1)から復元してから、異なるリージョン(us-west1)の別の GKE クラスタに復元します。

    export SOURCE_CLUSTER=cluster-db1
    export TARGET_CLUSTER=cluster-db2
    export REGION=us-central1
    export DR_REGION=us-west1
    export NAME_PREFIX=g-db-protected-app
    export BACKUP_PLAN_NAME=$NAME_PREFIX-bkp-plan-01
    export BACKUP_NAME=bkp-$BACKUP_PLAN_NAME
    export RESTORE_PLAN_NAME=$NAME_PREFIX-rest-plan-01
    export RESTORE_NAME=rest-$RESTORE_PLAN_NAME
    
  2. クラスタで Backup for GKE が有効になっていることを確認します。以前に行った Terraform 設定の一部として、すでに有効になっているはずです。

    gcloud container clusters describe $SOURCE_CLUSTER \
        --project=$PROJECT_ID  \
        --region=$REGION \
        --format='value(addonsConfig.gkeBackupAgentConfig)'
    

    Backup for GKE が有効になっている場合、コマンドの出力に enabled=True と表示されます。

バックアップ プランを設定して復元を実行する

Backup for GKE を使用すると、cron ジョブとしてバックアップ プランを作成できます。バックアップ プランには、ソースクラスタ、バックアップするワークロードの選択、このプランで生成したバックアップ アーティファクトが保存されているリージョンなどのバックアップ構成が含まれます。

バックアップと復元を行う手順は次のとおりです。

  1. cluster-db1 で ProtectedApplication のステータスを確認します。

    kubectl get ProtectedApplication -A
    

    出力は次のようになります。

    NAMESPACE    NAME            READY TO BACKUP
    postgresql   postgresql-ha   true
    
  2. ProtectedApplication のバックアップ プランを作成します。

    export NAMESPACE=postgresql
    export PROTECTED_APP=$(kubectl get ProtectedApplication -n $NAMESPACE | grep -v 'NAME' | awk '{ print $1 }')
    
    gcloud beta container backup-restore backup-plans create $BACKUP_PLAN_NAME \
    --project=$PROJECT_ID \
    --location=$DR_REGION \
    --cluster=projects/$PROJECT_ID/locations/$REGION/clusters/$SOURCE_CLUSTER \
    --selected-applications=$NAMESPACE/$PROTECTED_APP \
    --include-secrets \
    --include-volume-data \
    --cron-schedule="0 3 * * *" \
    --backup-retain-days=7 \
    --backup-delete-lock-days=0
    
  3. バックアップを手動で作成します。

    gcloud beta container backup-restore backups create $BACKUP_NAME \
    --project=$PROJECT_ID \
    --location=$DR_REGION \
    --backup-plan=$BACKUP_PLAN_NAME \
    --wait-for-completion
    
  4. 復元プランを設定します。

    gcloud beta container backup-restore restore-plans create $RESTORE_PLAN_NAME \
      --project=$PROJECT_ID \
      --location=$DR_REGION \
      --backup-plan=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME \
      --cluster=projects/$PROJECT_ID/locations/$DR_REGION/clusters/$TARGET_CLUSTER \
      --cluster-resource-conflict-policy=use-existing-version \
      --namespaced-resource-restore-mode=delete-and-restore \
      --volume-data-restore-policy=restore-volume-data-from-backup \
      --selected-applications=$NAMESPACE/$PROTECTED_APP \
      --cluster-resource-scope-selected-group-kinds="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
    
  5. バックアップから復元します。

    gcloud beta container backup-restore restores create $RESTORE_NAME \
      --project=$PROJECT_ID \
      --location=$DR_REGION \
      --restore-plan=$RESTORE_PLAN_NAME \
      --backup=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME/backups/$BACKUP_NAME \
      --wait-for-completion
    

クラスタが復元されていることを確認する

復元されたクラスタに、想定どおりのすべての Pod、PersistentVolume、StorageClass リソースが含まれていることを確認する手順は次のとおりです。

  1. バックアップ クラスタ cluster-db2 への kubectl コマンドライン アクセスを構成します。

    gcloud container clusters get-credentials $TARGET_CLUSTER --region $DR_REGION --project $PROJECT_ID
    
  2. 3/3 Pod で StatefulSet の準備ができていることを確認します。

    kubectl get all -n $NAMESPACE
    

    出力は次のようになります。

    NAME                                                   READY   STATUS    RESTARTS        AGE
    pod/postgresql-postgresql-ha-pgpool-778798b5bd-k2q4b   1/1     Running   0               4m49s
    pod/postgresql-postgresql-ha-postgresql-0              2/2     Running   2 (4m13s ago)   4m49s
    pod/postgresql-postgresql-ha-postgresql-1              2/2     Running   0               4m49s
    pod/postgresql-postgresql-ha-postgresql-2              2/2     Running   0               4m49s
    
    NAME                                                   TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE
    service/postgresql-postgresql-ha-pgpool                ClusterIP   192.168.241.46    <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql            ClusterIP   192.168.220.20    <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql-headless   ClusterIP   None              <none>        5432/TCP   4m49s
    service/postgresql-postgresql-ha-postgresql-metrics    ClusterIP   192.168.226.235   <none>        9187/TCP   4m49s
    
    NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/postgresql-postgresql-ha-pgpool   1/1     1            1           4m49s
    
    NAME                                                         DESIRED   CURRENT   READY   AGE
    replicaset.apps/postgresql-postgresql-ha-pgpool-778798b5bd   1         1         1       4m49s
    
    NAME                                                   READY   AGE
    statefulset.apps/postgresql-postgresql-ha-postgresql   3/3     4m49s
    
  3. postgres Namespace 内のすべての Pod が動作していることを確認します。

    kubectl get pods -n $NAMESPACE
    

    出力は次のようになります。

    postgresql-postgresql-ha-pgpool-569d7b8dfc-2f9zx   1/1     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-0              2/2     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-1              2/2     Running   0          7m56s
    postgresql-postgresql-ha-postgresql-2              2/2     Running   0          7m56s
    
  4. PersistentVolume と StorageClass を確認します。復元処理中に、Backup for GKE は、ターゲット ワークロードにプロキシクラスを作成して、ソース ワークロード(サンプル出力の gce-pd-gkebackup-dn)でプロビジョニングされた StorageClass を置き換えます。

    kubectl get pvc -n $NAMESPACE
    

    出力は次のようになります。

    NAME                                         STATUS   VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS          AGE
    data-postgresql-postgresql-ha-postgresql-0   Bound    pvc-be91c361e9303f96   8Gi        RWO            gce-pd-gkebackup-dn   10m
    data-postgresql-postgresql-ha-postgresql-1   Bound    pvc-6523044f8ce927d3   8Gi        RWO            gce-pd-gkebackup-dn   10m
    data-postgresql-postgresql-ha-postgresql-2   Bound    pvc-c9e71a99ccb99a4c   8Gi        RWO            gce-pd-gkebackup-dn   10m
    

想定どおりのデータが復元されていることを確認する

想定どおりのデータが復元されていることを確認する手順は次のとおりです。

  1. PostgreSQL インスタンスに接続します。

    ./scripts/launch-client.sh
    kubectl exec -it pg-client -n postgresql -- /bin/bash
    
  2. 各テーブルの行数を確認します。

    psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
    select COUNT(*) from tb01;
    

    前述のテスト データセットを作成するで書き込んだデータと同様の結果を確認できます。出力は次のようになります。

    300000
    (1 row)
    
  3. クライアント Pod を終了します。

    exit
    

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトを削除する

課金を停止する最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

Delete a Google Cloud project:

gcloud projects delete PROJECT_ID

次のステップ