使用 PGAdapter 連線

本文說明如何使用 PGAdapter 連線至 Spanner Omni。設定 PGAdapter 以建立安全連線。 PGAdapter 支援純文字、傳輸層安全標準 (TLS)相互 TLS (mTLS) 安全模式。這些模式提供不同程度的加密和驗證,可在傳輸期間保護資料。每種安全模式都需要特定的用戶端設定,才能確保資料完整性和機密性。

您可以將 PGAdapter 當做獨立程序執行,也可以直接整合到應用程式中。如要進行互動式管理及手動執行查詢,請使用標準 PostgreSQL 工具 (例如 psql) 連線至資料庫。如要建構自動化應用程式,請使用與 PostgreSQL 相容的驅動程式,例如:

如需使用部分驅動程式的程式碼範例,請參閱本文中的程式碼範例

安全模式

Spanner Omni PGAdapter 支援三種安全模式,可定義 PGAdapter 與資料庫之間的通訊加密和驗證方式。如要使用這些模式,請按照下表說明設定用戶端選項:

安全模式 說明
純文字 通訊內容未加密。
TLS 通訊內容會使用傳輸層安全標準 (TLS) 加密。這個模式需要將 Spanner Omni CA 憑證新增至預設的 Java 信任存放區。
mTLS 通訊會使用相互傳輸層安全標準 (mTLS) 加密。這個模式需要您提供用戶端憑證和用戶端私鑰。

以獨立程序執行

如要手動與資料庫互動,請為非 Java 應用程式和標準 PostgreSQL 工具 (例如 psql) 執行 PGAdapter 做為獨立程序。這種做法可將 Proxy 與應用程式生命週期分離,讓您獨立管理及更新 Proxy。如要以獨立程序啟動 PGAdapter,請根據所選安全模式使用下列設定方法。

使用純文字模式

如要在純文字通訊模式下啟動 PGAdapter,請執行下列指令:

java -jar pgadapter.jar \
     -d DATABASE_ID \
     -e ENDPOINT \
     -r "isExperimentalHost=true;usePlainText=true"

更改下列內容:

  • DATABASE_ID:Spanner Omni 資料庫的 ID,例如 test-db

  • ENDPOINT:Spanner Omni 執行個體的端點,例如 localhost:15000

使用 TLS 模式

如要透過 Java 應用程式以傳輸層安全標準:TLS 模式啟動程序內 PGAdapter,必須先將 Spanner Omni CA 憑證新增至預設 Java 信任儲存庫。如要將現有 CA 憑證新增至 Java 信任儲存區,請執行下列指令:

sudo keytool -import -trustcacerts -file ~/.spanner/certs/ca.crt -alias spanner-ca -keystore $JAVA_HOME/lib/security/cacerts

如要在 TLS 模式下啟動 PGAdapter,請執行下列指令:

java -Djavax.net.ssl.trustStore=$JAVA_HOME/lib/security/cacerts \
     -Djavax.net.ssl.trustStoreType=JKS \
     -jar pgadapter.jar \
     -d DATABASE_ID \
     -e ENDPOINT \
     -r "isExperimentalHost=true"

使用 mTLS 模式

如要在 mTLS 模式下啟動 PGAdapter,請務必確認用戶端金鑰採用 PKCS#8 格式。如要將金鑰儲存區中的現有金鑰轉換為 PKCS#8 格式,請執行下列指令:

openssl pkcs8 -topk8 -in ~/.spanner/certs/client.key -out ~/.spanner/certs/java-client.key -nocrypt

或者,使用 Spanner Omni CLI 建立用戶端憑證和金鑰時,請提供 --generate-pkcs8-key 參數,以 PKCS#8 格式產生金鑰。

如要在 mTLS 模式下啟動 PGAdapter,請執行下列指令:

java -Djavax.net.ssl.trustStore=$JAVA_HOME/lib/security/cacerts \
    -Djavax.net.ssl.trustStoreType=JKS \
    -jar pgadapter.jar \
    -d DATABASE_ID \
    -e ENDPOINT \
    -r "isExperimentalHost=true;clientCertificate=PATH_TO_CLIENT_CERT;clientKey=PATH_TO_CLIENT_KEY"

更改下列內容:

  • PATH_TO_CLIENT_CERT:用戶端憑證檔案的路徑。

  • PATH_TO_CLIENT_KEY:用戶端金鑰檔案的路徑。

與「psql」聯絡

使用上述任一方法建立連線後,請執行 psql 管理資料庫及執行查詢。如要連線至 psql,請使用下列指令:

psql -h PG_HOST -p PG_PORT -U USERNAME -d DATABASE_ID

更改下列內容:

  • PG_HOST:執行 PGAdapter 的電腦主機名稱或 IP 位址。如要在本機執行,請使用 localhost

  • PG_PORT:PGAdapter 執行的通訊埠編號。如果您未指定自訂通訊埠,PGAdapter 預設會使用通訊埠 5432

  • USERNAME:您的 PostgreSQL 使用者名稱。

在應用程式中以程序內執行

您也可以在應用程式中啟動 PGAdapter。如要建立安全性,請設定 OptionsMetadata 物件。

使用純文字模式

如要進行純文字通訊,例如在本機開發或在安全環境中測試,且不需要加密額外負荷,請使用下列設定:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
    .setEndpoint("ENDPOINT")
    .setUsePlainText();

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

使用 TLS 模式

如要在本機開發或測試等環境中使用純文字通訊,請使用下列設定:

sudo keytool -import -trustcacerts -file /.spanner/certs/ca.crt -alias spanner-ca -keystore $JAVA_HOME/lib/security/cacerts

如要在程序中建立 TLS 連線,請使用下列設定:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
    .setEndpoint("ENDPOINT");

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

使用 mTLS 模式

如要使用 Java 應用程式以程序內模式啟動 PGAdapter,請務必確認用戶端金鑰為 PKCS#8 格式。如要將金鑰儲存區中的現有金鑰轉換為 PKCS#8 格式,請執行下列指令:

openssl pkcs8 -topk8 -in ~/.spanner/certs/client.key -out ~/.spanner/certs/java-client.key -nocrypt

或者,使用 Spanner Omni CLI 建立用戶端憑證和金鑰時,請提供 --generate-pkcs8-key 參數,以 PKCS#8 格式產生金鑰。

如要在程序中建立 mTLS 連線,請使用下列設定:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
    .setEndpoint("ENDPOINT")
    .useClientCert("PATH_TO_CLIENT_CERT", "PATH_TO_CLIENT_KEY");

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

程式碼範例

本節提供程式碼範例,說明如何使用下列與 PostgreSQL 相容的驅動程式,連線至 Spanner Omni 資料庫:

在連線字串中替換下列預留位置:

  • PASSWORD:PostgreSQL 使用者的密碼。

JDBC

您可以使用 PostgreSQL JDBC 驅動程式連線至 PGAdapter,就像連線至 PostgreSQL 資料庫一樣。如要連線及查詢 Spanner Omni 資料庫中的資料表,請使用下列程式碼範例:

String jdbcUrl =
    "jdbc:postgresql://PG_HOST:PG_PORT/DATABASE_ID";

try (Connection connection = DriverManager.getConnection(jdbcUrl)) {
  // Example: Query data
  try (Statement statement = connection.createStatement();
      ResultSet resultSet = statement.executeQuery("SELECT * FROM Singers")) {

    System.out.println("Query Results:");
    while (resultSet.next()) {
      long id = resultSet.getLong("id");
      String name = resultSet.getString("name");
      System.out.printf("ID: %d, Name: %s\n", id, name);
    }
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}

Go (pgx)

您可以透過 pgx 連線至 PGAdapter,就像連線至 PostgreSQL 資料庫一樣。請使用下列程式碼範例:

// Database connection string
connString := "postgres://USERNAME:PASSWORD@PG_HOST:PG_PORT/DATABASE_ID?sslmode=disable"
ctx := context.Background()

// Connect to PGAdapter
conn, err := pgx.Connect(ctx, connString)
if err != nil {
  log.Fatalf("Connection error: %s", err.Error())
}
defer conn.Close(ctx)

// Query all rows from the Singers table
rows, err := conn.Query(ctx, "SELECT id, name FROM Singers")
if err != nil {
  log.Fatalf("Query error: %s", err.Error())
}
defer rows.Close()

// Iterate over the result set
fmt.Println("Singers Table Data:")
for rows.Next() {
  var id int
  var name string
  if err := rows.Scan(&id, &name); err != nil {
    log.Fatalf("Scan error: %s", err.Error())
  }
  fmt.Printf("ID: %d, Name: %s\n", id, name)
}

Python (psycopg2 或 psycopg3)

您可以透過 psycopg2psycopg3 連線至 PGAdapter,就像連線至 PostgreSQL 資料庫一樣。如要連線及查詢 Spanner Omni 資料庫中的資料表,請使用下列程式碼範例:

# psycopg2
import psycopg2

connection = psycopg2.connect(database="DATABASE_ID",
                              host="PG_HOST",
                              port=PG_PORT)

cursor = connection.cursor()
cursor.execute('SELECT * FROM Singers')
for row in cursor:
  print(row)

cursor.close()
connection.close()


# psycopg3
import psycopg

with psycopg.connect("host=PG_HOST port=PG_PORT dbname=DATABASE_ID sslmode=disable") as conn:
  conn.autocommit = True
  with conn.cursor() as cur:
    cur.execute("SELECT * FROM Singers")
    for row in cur:
      print(row)

Node.js (node-postgres)

您可以透過 node-postgres 連線至 PGAdapter,就像連線至 PostgreSQL 資料庫一樣。如要連線及查詢 Spanner Omni 資料庫中的資料表,請使用下列程式碼範例:

const { Client } = require('pg');
const client = new Client({
  host: 'PG_HOST',
  port: PG_PORT,
  database: 'DATABASE_ID',
});
await client.connect();
const res = await client.query("SELECT * FROM Singers");
console.log(res.rows);
await client.end();