PGAdapter を使用して接続する

このドキュメントでは、PGAdapter を使用して Spanner Omni に接続する方法について説明します。安全な接続を確立するように PGAdapter を構成します。 PGAdapter は、書式なしテキスト、 Transport Layer Security(TLS)、 および 相互 TLS(mTLS) のセキュリティ モードをサポートしています。これらのモードは、さまざまなレベルの暗号化と認証を提供することで、送信中のデータを保護します。各セキュリティ モードでは、データの完全性と機密性を確保するために、特定のクライアント構成が必要です。

PGAdapter は、スタンドアロン プロセスとして実行することも、アプリケーションに直接統合することもできます。インタラクティブな管理と手動クエリの実行には、psql などの標準の PostgreSQL ツールを使用してデータベースに接続します。自動化されたアプリケーションを構築するには、次のような PostgreSQL 互換ドライバを使用します。

これらのドライバの一部を使用したコードサンプルについては、このドキュメントの サンプルコードをご覧ください。

セキュリティ モード

Spanner Omni PGAdapter は、3 つのセキュリティ モードをサポートしています。これらのモードは、PGAdapter とデータベース間の通信を暗号化して認証する方法を定義します。これらのモードを使用するには、次の表の説明に従ってクライアント オプションを構成します。

セキュリティ モード 説明
書式なしテキスト 通信は暗号化されません。
TLS 通信は Transport Layer Security(TLS)を使用して暗号化されます。この モードでは、Spanner Omni CA 証明書を デフォルトの Java トラストストアに追加する必要があります。
mTLS 通信は相互 TLS(mTLS)を使用して暗号化されます。このモードでは、 クライアント証明書とクライアント秘密鍵の両方を指定する必要があります。

スタンドアロン プロセスとして実行する

手動でデータベースを操作する必要がある場合は、Java 以外のアプリケーションと標準の PostgreSQL ツール(psql など)で、PGAdapter をスタンドアロン プロセスとして実行します。このアプローチでは、プロキシをアプリケーションのライフサイクルから切り離すことができるため、個別に管理して更新できます。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 データベースに接続する場合と同様に、PostgreSQL JDBC ドライバを使用して PGAdapter に接続できます。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)

PostgreSQL データベースに接続する場合と同様に、pgx を使用して PGAdapter に接続できます。次のサンプルコードを使用します。

// 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)

PostgreSQL データベースに接続する場合と同様に、psycopg2 または psycopg3 を使用して PGAdapter に接続できます。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)

PostgreSQL データベースに接続する場合と同様に、 node-postgres を使用して PGAdapter に接続できます。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();