במאמר הזה מוסבר איך להתחבר ל-Spanner Omni באמצעות PGAdapter. מגדירים את PGAdapter ליצירת חיבורים מאובטחים. PGAdapter תומך במצבי אבטחה של טקסט רגיל, Transport Layer Security (TLS) וTLS הדדי (mTLS). ההגנה על הנתונים במצבים האלה מתבצעת בזמן ההעברה באמצעות רמות שונות של הצפנה ואימות. כל מצב אבטחה דורש הגדרות ספציפיות של הלקוח כדי להבטיח את תקינות הנתונים ואת הסודיות שלהם.
אפשר להריץ את PGAdapter כתהליך עצמאי או לשלב אותו ישירות באפליקציה. לניהול אינטראקטיבי ולהרצת שאילתות ידנית, מתחברים למסד הנתונים באמצעות כלים סטנדרטיים של PostgreSQL כמו psql. כדי ליצור אפליקציות אוטומטיות, אפשר להשתמש במנהלי התקנים שתואמים ל-PostgreSQL, כמו:
pgxל-Go
psycopg3ל-Python
node-postgresל-Node.js
דוגמאות קוד לשימוש בחלק מהדרייברים האלה מופיעות בקטע קוד לדוגמה במסמך הזה.
מצבי אבטחה
PGAdapter ב-Spanner Omni תומך בשלושה מצבי אבטחה, שמגדירים איך התקשורת מוצפנת ומאומתת בין PGAdapter לבין מסד הנתונים. כדי להשתמש במצבים האלה, צריך להגדיר את אפשרויות הלקוח כמו שמתואר בטבלה הבאה:
| מצב אבטחה | תיאור |
|---|---|
| טקסט פשוט | התקשורת לא מוצפנת. |
| TLS | התקשורת מוצפנת באמצעות פרוטוקול ההצפנה Transport Layer Security (TLS). כדי להשתמש במצב הזה, צריך להוסיף את אישור ה-CA של Spanner Omni למאגר האישורים המהימן של Java. |
| mTLS | התקשורת מוצפנת באמצעות פרוטוקול TLS הדדי (mTLS). במצב הזה צריך לספק גם אישור לקוח וגם מפתח פרטי של הלקוח. |
הפעלה כתהליך עצמאי
מריצים את PGAdapter כתהליך עצמאי לאפליקציות שאינן Java ולכלים סטנדרטיים של PostgreSQL, לדוגמה, psql, כשצריך אינטראקציה ידנית עם מסד הנתונים. הגישה הזו מפרידה את שרת ה-proxy ממחזור החיים של האפליקציה, ומאפשרת לכם לנהל ולעדכן אותו באופן עצמאי. כדי להפעיל את PGAdapter כתהליך עצמאי, משתמשים בשיטות ההגדרה הבאות בהתאם למצב האבטחה שנבחר.
שימוש במצב טקסט פשוט
כדי להפעיל את PGAdapter במצב תקשורת של טקסט פשוט, מריצים את הפקודה הבאה:
java -jar pgadapter.jar \
-d DATABASE_ID \
-e ENDPOINT \
-r "isExperimentalHost=true;usePlainText=true"
מחליפים את מה שכתוב בשדות הבאים:
DATABASE_ID: המזהה של מסד הנתונים של Spanner Omni, לדוגמה,test-db.
ENDPOINT: נקודת הקצה של מופע Spanner Omni, לדוגמה,localhost:15000.
שימוש במצב TLS
כדי להפעיל את PGAdapter בתוך התהליך במצב TLS באפליקציית Java, צריך להוסיף את אישור ה-CA של Spanner Omni אל מאגר האישורים המהימנים של Java. כדי להוסיף אישור CA קיים למאגר האישורים המהימנים של Java, מריצים את הפקודה הבאה:
sudo keytool -import -trustcacerts -file ~/.spanner/certs/ca.crt -alias spanner-ca -keystore $JAVA_HOME/lib/security/cacerts
כדי להפעיל את PGAdapter במצב TLS, מריצים את הפקודה הבאה:
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
לפני שמתחילים את PGAdapter במצב mTLS, צריך לוודא שמפתח הלקוח הוא בפורמט 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.
כדי להפעיל את PGAdapter במצב mTLS, מריצים את הפקודה הבאה:
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: שם המארח או כתובת ה-IP של המכונה שבה PGAdapter פועל. אם מריצים באופן מקומי, משתמשים ב-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
כדי להפעיל את PGAdapter במצב in-process עם אפליקציית Java, צריך לוודא שמפתח הלקוח הוא בפורמט 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();
קוד לדוגמה
בקטע הזה מוצג קוד לדוגמה לחיבור למסד נתונים של Spanner Omni באמצעות מנהלי ההתקנים הבאים שתואמים ל-PostgreSQL:
מחליפים את הערך הזמני לשמירת מקום במחרוזות החיבור:
- PASSWORD: הסיסמה של משתמש PostgreSQL.
JDBC
אפשר להתחבר ל-PGAdapter באמצעות מנהל ההתקן JDBC של PostgreSQL, כאילו מתחברים למסד נתונים של 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)
אפשר להתחבר ל-PGAdapter באמצעות pgx כאילו מתחברים למסד נתונים של 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)
אפשר להתחבר ל-PGAdapter באמצעות psycopg2 או psycopg3 כאילו מתחברים למסד נתונים של 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)
אפשר להתחבר ל-PGAdapter באמצעות node-postgres כאילו מתחברים למסד נתונים של 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();