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)

pgx を使用して、PostgreSQL データベースに接続するのと同じように 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();