啟動 PGAdapter

本頁面說明如何在 Spanner 中啟動 PGAdapter。如要瞭解 PGAdapter,請參閱「 關於 PGAdapter」一文。如要取得 PGAdapter 二進位檔,請參閱「取得 PGAdapter」一文。

您可以透過下列方式啟動 PGAdapter:

  • 做為獨立程序
  • 在 Docker 容器中
  • 在 Cloud Run 上
  • 使用 PGAdapter 做為補充 Proxy (例如在 Kubernetes 叢集中)
  • 與 Java 應用程式一同處理

事前準備

在啟動 PGAdapter 前,請確認您已在 PGAdapter 執行的電腦上,使用使用者帳戶或服務帳戶進行驗證。如果您使用服務帳戶,必須知道 JSON 金鑰檔案 (憑證檔案) 的位置。接著,您可以使用 PGAdapter -c 選項指定憑證路徑,或是設定 GOOGLE_APPLICATION_CREDENTIALS 環境變數。

如需詳細資訊,請參閱:

選擇執行 PGAdapter 的方法

您可以將 PGAdapter 做為獨立程序啟動,在 Docker 容器內、Cloud Run 上,或在 Java 應用程式中啟動。啟動 PGAdapter 時,您會指定要連線的專案、Spanner 執行個體和資料庫。您也可以指定 JSON 格式憑證檔案 (金鑰檔案) 的路徑。

獨立式

使用以下指令下載 PGAdapter。

    wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
    && tar -xzvf pgadapter.tar.gz
    

使用下列指令啟動 PGAdapter。

    java -jar pgadapter.jar -p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME \
    -c CREDENTIALS_FILE_PATH \
    ADDITIONAL_OPTIONS
    

以下選項為必填:

-p project_name
Spanner 資料庫執行所在的專案名稱。
-i instance_name
Spanner 執行個體名稱。
-d database_name
要連線的資料庫名稱。

以下選項為選用:

-r databaseRole=database_role
要用於工作階段的資料庫角色。詳情請參閱「使用 PGAdapter 進行授權」。
-c credentials_file_path
含有服務帳戶憑證 JSON 格式的金鑰檔案完整路徑。如果未設定這個選項,系統會從 GOOGLE_APPLICATION_CREDENTIALS 環境變數指定的路徑讀取憑證。

如要瞭解如何建立服務帳戶及下載 JSON 格式的金鑰檔案,請參閱「 建立服務帳戶」一文。

請務必為服務帳戶授予足夠的憑證,以便存取資料庫。

如果您先使用下列指令驗證 Google Cloud CLI,可以省略這個選項:

gcloud auth application-default login

詳情請參閱「 設定驗證和授權」。

-s port
PGAdapter 監聽的通訊埠。預設為 5432 (預設的 PostgreSQL 通訊埠)。
-v version_number

在連線期間,要向用戶端公開的 PostgreSQL 版本號碼。預設值為 14.1

部分 PostgreSQL 應用程式和驅動程式會根據這個版本號碼啟用其他功能。Spanner 可能不支援這些功能。如需支援用戶端的完整清單,請參閱「 驅動程式和用戶端」。

-x

啟用來自 localhost 以外主機的連線。請勿在獨立模式下啟動 PGAdapter。僅在 Docker 容器內啟動時使用

根據預設,PGAdapter 會採取安全措施,僅接受來自本機主機的連線。

以下範例會使用預設應用程式憑證,在 5432 通訊埠上以獨立模式啟動 PGAdapter。

java -jar pgadapter.jar \
-p my-project \
-i my-instance \
-d my-database \
-s 5432

Docker

使用下列指令啟動 PGAdapter。

docker run -d -p HOST-PORT:DOCKER-PORT \
-v CREDENTIALS_FILE_PATH:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME  \
-c /acct_credentials.json -x OTHER_PGAdapter_OPTIONS

除了用來指定專案、執行個體、資料庫和憑證的 PGAdapter 選項之外,您還必須使用下列選項:

-p 127.0.0.1:HOST-PORT:DOCKER-PORT

此 Docker 選項會將 Docker 容器內的通訊埠 DOCKER-PORT 對應至容器外部的通訊埠 HOST-PORTDOCKER-PORT 必須與 PGAdapter 在容器內的設定方式相符。預設值為 5432。HOST-PORT 是 Docker 應在容器外監聽連線要求的通訊埠。必須是 localhost 上可用的通訊埠。

詳情請參閱 Docker 說明文件中的「 發布或公開通訊埠 (-p, --expose)」一節。

-v CREDENTIALS_FILE_PATH:in_container_mount_point

這個 Docker 選項會綁定掛接共用磁碟區。它會將容器外的主機路徑對應至容器內的磁碟區 (掛接點)。主機和容器路徑以半形冒號 (:) 分隔。

這個選項可讓 PGAdapter 存取位於容器外的 JSON 憑證檔案。在上述範例中,-c 選項會參照容器內的掛接點。這個範例會命名容器內掛接點 /acct_credentials.json。您可以隨意命名這個檔案。

詳情請參閱 Docker 說明文件中的「VOLUME (共用檔案系統)」。

-x

啟用來自 localhost 以外主機的連線。這是因為容器內部對應至主機通訊埠的通訊埠,不會向 PGAdapter 顯示為 localhost。

以下選項為選用選項:

-r databaseRole=database_role
要用於工作階段的資料庫角色。詳情請參閱「使用 PGAdapter 進行授權」。

在以下範例中,Docker 通訊埠和主機通訊埠都設為 PostgreSQL 資料庫服務的預設通訊埠 5432。

docker run -d -p 127.0.0.1:5432:5432 \
-v /tmp/credentials.json:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p my_project -i my_instance -d my_database \
-c /acct_credentials.json -x

Cloud Run

您無法在 Cloud Run 上將 PGAdapter 部署為獨立服務,但可以將其部署為附屬 Proxy。

建議您以補充資訊模式執行 PGAdapter,而非以個別服務模式執行,原因如下:
  • 避免單點故障。每個應用程式對資料庫的存取權都與其他應用程式無關,因此更為穩健。
  • PGAdapter 執行個體的數量會自動以線性方式,隨著應用程式執行個體的數量而調整。

PGAdapter GitHub 存放區包含多個 使用 Cloud Run 和 PGAdapter 做為附屬 Proxy 的實際範例應用程式,適用於各種程式設計語言。

下列設定檔顯示如何將 PGAdapter 新增為 Cloud Run 的附加 Proxy:

  apiVersion: serving.knative.dev/v1
  kind: Service
  metadata:
  annotations:
    # This example uses an in-memory volume for Unix domain sockets.
    # This is a Cloud Run beta feature.
    run.googleapis.com/launch-stage: BETA
  name: pgadapter-sidecar-example
  spec:
  template:
    metadata:
      annotations:
        run.googleapis.com/execution-environment: gen1
        # This registers 'pgadapter' as a dependency of 'app' and ensures that pgadapter starts
        # before the app container.
        run.googleapis.com/container-dependencies: '{"app":["pgadapter"]}'
    spec:
      # Create an in-memory volume that can be used for Unix domain sockets.
      volumes:
        - name: sockets-dir
          emptyDir:
            # This directory contains the virtual socket files that are used to
            # communicate between your application and PGAdapter.
            sizeLimit: 50Mi
            medium: Memory
      containers:
        # This is the main application container.
        - name: app
          # Example: europe-north1-docker.pkg.dev/my-test-project/cloud-run-source-deploy/pgadapter-sidecar-example
          image: MY-REGION.pkg.dev/MY-PROJECT/cloud-run-source-deploy/pgadapter-sidecar-example
          # The PGADAPTER_HOST variable is set to point to /sockets, which is the shared in-memory
          # volume that is used for Unix domain sockets.
          env:
            - name: SPANNER_PROJECT
              value: my-project
            - name: SPANNER_INSTANCE
              value: my-instance
            - name: SPANNER_DATABASE
              value: my-database
            - name: PGADAPTER_HOST
              value: /sockets
            - name: PGADAPTER_PORT
              value: "5432"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
        # This is the PGAdapter sidecar container.
        - name: pgadapter
          image: gcr.io/cloud-spanner-pg-adapter/pgadapter
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
          args:
            - -dir /sockets
            - -x
          # Add a startup probe that checks that PGAdapter is listening on port 5432.
          startupProbe:
            initialDelaySeconds: 10
            timeoutSeconds: 10
            periodSeconds: 10
            failureThreshold: 3
            tcpSocket:
              port: 5432
  

補充 Proxy

您可以將 PGAdapter 用於 Kubernetes 叢集等 sidecar 代理程式。Kubernetes 附加元件容器會與 Pod 中的主容器並行執行。

建議您以補充資訊模式執行 PGAdapter,而非以獨立服務模式執行,原因如下:

  • 避免單點故障。每個應用程式對資料庫的存取權皆獨立於其他應用程式,因此更具彈性。
  • 由於 PGAdapter 會以與用量成正比的方式耗用資源,因此您可以透過這個模式,更準確地設定範圍和要求資源,以便在應用程式擴充時與其相符。

下列設定檔顯示如何將 PGAdapter 新增為 Kubernetes 叢集的附屬 Proxy:

containers:
- name: pgadapter
image: gcr.io/cloud-spanner-pg-adapter/pgadapter
ports:
  - containerPort: 5432
args:
  - "-p my-project"
  - "-i my-instance"
  - "-d my-database"
  - "-x"
resources:
  requests:
    # PGAdapter'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: "512Mi"
    # PGAdapter'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"

PGAdapter GitHub 存放區包含逐步指南和應用程式範例。這個範例包含使用 Workload Identity Federation for GKE 搭配 PGAdapter 的操作說明。

Java 內部程序

使用 Java 程式碼建立及啟動 PGAdapter 例項。這是 Java 應用程式的建議設定。

如果您使用服務帳戶進行驗證,請務必將 GOOGLE_APPLICATION_CREDENTIALS 環境變數設為憑證檔案的路徑。

  1. google-cloud-spanner-pgadapter 新增為專案的依附元件。詳情請參閱「取得 PGAdapter」。
  2. 使用 com.google.cloud.spanner.pgadapter.ProxyServer 類別建構伺服器。
  3. /**
    * Starts PGAdapter in-process and returns a reference to the server. Use this reference to
    * gracefully shut down the server when your application shuts down.
    *
    * @param project the Google Cloud project that PGAdapter should connect to
    * @param instance the Spanner instance that PGAdapter should connect to
    * @param credentialsFile the full path of a credentials file that PGAdapter should use, or 
    *     null if PGAdapter should use the application default credentials
    */
    static Server startPGAdapter(String project, String instance, String credentialsFile) {
    OptionsMetadata.Builder builder =
        OptionsMetadata.newBuilder()
            .setProject(project)
            .setInstance(instance)
            // Start PGAdapter on any available port.
            .setPort(0);
    if (credentialsFile != null) {
      builder.setCredentialsFile(credentialsFile);
    }
    ProxyServer server = new ProxyServer(builder.build());
    server.startServer();
    server.awaitRunning();
    
    return new PGAdapter(server);
    }

PGAdapter GitHub 存放區包含完整的範例應用程式

後續步驟