Verbindung über PGAdapter herstellen

In diesem Dokument wird beschrieben, wie Sie mit PGAdapter eine Verbindung zu Spanner Omni herstellen. Sie konfigurieren PGAdapter so, dass sichere Verbindungen hergestellt werden. PGAdapter unterstützt die Sicherheitsmodi „Klartext“, Transport Layer Security (TLS) und gegenseitiges TLS (mTLS). Diese Modi schützen Ihre Daten bei der Übertragung durch unterschiedliche Verschlüsselungs- und Authentifizierungsstufen. Für jeden Sicherheitsmodus sind bestimmte Clientkonfigurationen erforderlich, um die Datenintegrität und ‑vertraulichkeit zu gewährleisten.

Sie können PGAdapter als eigenständigen Prozess ausführen oder direkt in Ihre Anwendung einbinden. Für die interaktive Verwaltung und die manuelle Ausführung von Abfragen stellen Sie mit Standard-PostgreSQL-Tools wie psql eine Verbindung zu Ihrer Datenbank her. Verwenden Sie zum Erstellen automatisierter Anwendungen PostgreSQL-kompatible Treiber wie die folgenden:

Beispielcode in diesem Dokument enthält Codebeispiele für einige dieser Treiber.

Sicherheitsmodi

Spanner Omni PGAdapter unterstützt drei Sicherheitsmodi, die definieren, wie die Kommunikation zwischen PGAdapter und der Datenbank verschlüsselt und authentifiziert wird. Wenn Sie diese Modi verwenden möchten, konfigurieren Sie die Clientoptionen wie in der folgenden Tabelle beschrieben:

Sicherheitsmodus Beschreibung
Nur Text Die Kommunikation ist nicht verschlüsselt.
TLS Die Kommunikation wird mit Transport Layer Security (TLS) verschlüsselt. In diesem Modus müssen Sie das Spanner Omni-CA-Zertifikat dem standardmäßigen Java-Truststore hinzufügen.
mTLS Die Kommunikation wird mit gegenseitigem TLS (mTLS) verschlüsselt. In diesem Modus müssen Sie sowohl ein Clientzertifikat als auch einen privaten Clientschlüssel angeben.

Als eigenständigen Prozess ausführen

Führen Sie PGAdapter als eigenständigen Prozess für Nicht-Java-Anwendungen und für Standard-PostgreSQL-Tools wie psql aus, wenn Sie eine manuelle Datenbankinteraktion benötigen. Bei diesem Ansatz wird der Proxy vom Lebenszyklus Ihrer Anwendung entkoppelt, sodass Sie ihn unabhängig verwalten und aktualisieren können. Wenn Sie PGAdapter als eigenständigen Prozess starten möchten, verwenden Sie die folgenden Konfigurationsmethoden, die von Ihrem ausgewählten Sicherheitsmodus abhängen.

Reinen Textmodus verwenden

Führen Sie den folgenden Befehl aus, um PGAdapter im Nur-Text-Kommunikationsmodus zu starten:

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

Ersetzen Sie Folgendes:

  • DATABASE_ID: die ID Ihrer Spanner Omni-Datenbank, z. B. test-db.

  • ENDPOINT: Der Endpunkt Ihrer Spanner Omni-Instanz, z. B. localhost:15000.

TLS-Modus verwenden

Bevor Sie PGAdapter im TLS-Modus in Ihrer Java-Anwendung starten können, müssen Sie das Spanner Omni-CA-Zertifikat dem standardmäßigen Java-Truststore hinzufügen. Führen Sie den folgenden Befehl aus, um dem Java-Truststore ein vorhandenes CA-Zertifikat hinzuzufügen:

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

Führen Sie den folgenden Befehl aus, um PGAdapter im TLS-Modus zu starten:

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-Modus verwenden

Bevor Sie PGAdapter im mTLS-Modus starten können, muss Ihr Clientschlüssel im PKCS#8-Format vorliegen. Führen Sie den folgenden Befehl aus, um einen vorhandenen Schlüssel in Ihrem Keystore in das PKCS#8-Format zu konvertieren:

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

Alternativ können Sie beim Erstellen des Clientzertifikats und des Schlüssels mit der Spanner Omni-CLI den Parameter --generate-pkcs8-key angeben, um den Schlüssel im PKCS#8-Format zu generieren.

Führen Sie den folgenden Befehl aus, um PGAdapter im mTLS-Modus zu starten:

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"

Ersetzen Sie Folgendes:

  • PATH_TO_CLIENT_CERT: der Pfad zu Ihrer Clientzertifikatsdatei.

  • PATH_TO_CLIENT_KEY: der Pfad zu Ihrer Client-Schlüsseldatei.

Mit psql verbinden

Nachdem Sie eine Verbindung mit einer der oben genannten Methoden hergestellt haben, führen Sie psql aus, um Ihre Datenbank zu verwalten und Abfragen auszuführen. Verwenden Sie zum Herstellen einer Verbindung zu psql den folgenden Befehl:

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

Ersetzen Sie Folgendes:

  • PG_HOST: der Hostname oder die IP-Adresse des Computers, auf dem PGAdapter ausgeführt wird. Bei einer lokalen Ausführung verwenden Sie localhost.

  • PG_PORT: Die Portnummer, unter der PGAdapter ausgeführt wird. Wenn Sie keinen benutzerdefinierten Port angegeben haben, verwendet PGAdapter standardmäßig Port 5432.

  • USERNAME: Ihr PostgreSQL-Nutzername.

In-Process mit Ihrer Anwendung ausführen

Sie können PGAdapter auch als Verarbeitungsprozess mit Ihrer Anwendung starten. Konfigurieren Sie das Objekt OptionsMetadata, um die Sicherheit zu gewährleisten.

Reinen Textmodus verwenden

Für die Kommunikation im Klartext, z. B. für die lokale Entwicklung oder Tests in sicheren Umgebungen, in denen der Verschlüsselungsaufwand unnötig ist, verwenden Sie die folgende Konfiguration:

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

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

TLS-Modus verwenden

Verwenden Sie für die Nur-Text-Kommunikation in Umgebungen wie der lokalen Entwicklung oder beim Testen die folgende Konfiguration:

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

Verwenden Sie die folgende Konfiguration, um eine TLS-Verbindung im Prozess herzustellen:

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

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

mTLS-Modus verwenden

Bevor Sie PGAdapter im In-Process-Modus mit Ihrer Java-Anwendung starten können, müssen Sie dafür sorgen, dass Ihr Clientschlüssel im PKCS#8-Format vorliegt. Führen Sie den folgenden Befehl aus, um einen vorhandenen Schlüssel in Ihrem Keystore in das PKCS#8-Format zu konvertieren:

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

Alternativ können Sie beim Erstellen des Clientzertifikats und des Schlüssels mit der Spanner Omni-CLI den Parameter --generate-pkcs8-key angeben, um den Schlüssel im PKCS#8-Format zu generieren.

So stellen Sie eine mTLS-Verbindung im Prozess her:

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();

Beispielcode

In diesem Abschnitt finden Sie Beispielcode für die Verbindung zu einer Spanner Omni-Datenbank mit den folgenden PostgreSQL-kompatiblen Treibern:

Ersetzen Sie den folgenden Platzhalter in Ihren Verbindungsstrings:

  • PASSWORD: Das Passwort für Ihren PostgreSQL-Nutzer.

JDBC

Sie können mit dem PostgreSQL-Treiber JDBC eine Verbindung zu PGAdapter herstellen, als ob Sie eine Verbindung zu einer PostgreSQL-Datenbank herstellen würden. Verwenden Sie den folgenden Beispielcode, um eine Verbindung zu einer Tabelle in einer Spanner Omni-Datenbank herzustellen und sie abzufragen:

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)

Sie können mit pgx eine Verbindung zu PGAdapter herstellen, als ob Sie eine Verbindung zu einer PostgreSQL-Datenbank herstellen würden. Verwenden Sie den folgenden Beispielcode:

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

Sie können mit psycopg2 oder psycopg3 eine Verbindung zu PGAdapter herstellen, als ob Sie eine Verbindung zu einer PostgreSQL-Datenbank herstellen würden. Verwenden Sie den folgenden Beispielcode, um eine Verbindung zu einer Tabelle in einer Spanner Omni-Datenbank herzustellen und sie abzufragen:

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

Sie können eine Verbindung zu PGAdapter mit node-postgres herstellen, als ob Sie eine Verbindung zu einer PostgreSQL-Datenbank herstellen würden. Verwenden Sie den folgenden Beispielcode, um eine Verbindung zu einer Tabelle in einer Spanner Omni-Datenbank herzustellen und Abfragen auszuführen:

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();