יצירת פריסה עם הצפנת TLS ב-Kubernetes

‫Spanner Omni משתמש ב-TLS 1.3 כדי להצפין את הנתונים שעוברים בין הלקוח לשרת, ובין שרתי Spanner Omni. ‫Spanner Omni מספק mTLS לאבטחה משופרת, שבה שני הצדדים מאמתים את האותנטיות אחד של השני לפני שהם מחליפים נתונים. אם אתם משתמשים בהצפנה, השרתים שלכם צריכים לתקשר באמצעות mTLS. אתם יכולים לבחור אם הלקוח והשרת ישתמשו גם ב-mTLS.

לפני שמתחילים

צריך לוודא שאתם עומדים בדרישות הבאות:

  • יוצרים אשכול Kubernetes. ההגדרה תומכת ב-Google Kubernetes Engine (GKE) וב-Amazon Elastic Kubernetes Service (Amazon EKS). יכול להיות שתצטרכו להתאים אישית את ההגדרות כדי לעבוד בסביבות אחרות.

  • מוודאים שלאשכול Kubernetes יש גישה לארטיפקט של Artifact Registry שמארח את הקונטיינר של Spanner Omni.

  • מתקינים ומגדירים את כלי שורת הפקודה kubectl ואת Helm.

  • אם הגדרתם את סביבת Kubernetes במכונות של פלטפורמת הווירטואליזציה vSphere, השביתו את הווירטואליזציה של מונה חותמות הזמן (TSC) על ידי הוספת monitor_control.virtual_rdtsc = FALSE לקובץ התצורה .vmx של המכונה הווירטואלית. כך אפשר לוודא ש-TrueTime פועל בצורה תקינה.

  • מוודאים שהסביבה עומדת בדרישות המערכת של Spanner Omni.

שלב 1: יוצרים את האישורים

צריך ליצור שלוש קבוצות של אישורים:

  • אישורי API: עוזרים להגן על שרת ה-API של Spanner Omni.

  • אישורי שרת: עוזרים להגן על התקשורת בין שרתים.

  • אישורי לקוח: משתמשי קצה או אפליקציות משתמשים בהם כדי לאמת את הזהות שלהם וליצור אמון עם שרתי Spanner Omni.

רשות אישורים (CA) מנפיקה את האישורים האלה. ב-Spanner Omni יש כלים ליצירת רשות אישורים בחתימה עצמית וכל שלושת סוגי האישורים.

מבצעים את השלבים הבאים באחד מהמחשבים. השלבים מבוססים על ההנחה שמרחב השמות הוא spanner-ns. צריך לשנות את זה למרחב השמות שבו אתם מתכוונים להשתמש בפריסה.

אתם יכולים ליצור את האישורים האלה בתחנת העבודה שלכם באמצעות ה-CLI של Spanner Omni.

1. יצירת רשות אישורים (CA)

רשות אישורים (CA) מנפיקה את כל האישורים. יכול להיות שבארגון שלכם יש רשות אישורים מרכזית, או שאתם יכולים להשתמש ברשות אישורים ציבורית. אפשר להשתמש באותה רשות אישורים לכל האישורים, אבל אישורי ה-API ואישורי הלקוח חייבים להשתמש באותה רשות אישורים.

ב-Spanner Omni אתם יכולים ליצור רשות אישורים פרטית.

./google/spanner/bin/spanner certificates create-ca --ca-certificate-directory=certs

הפקודה create-ca יוצרת את אישור ה-CA בספרייה certs. אתם יכולים להעתיק את האישור הזה כדי להשתמש בו כרשות האישורים לאישורי API, או ליצור רשות אישורים אחרת. חשוב לוודא שאתם משתמשים ברשות האישורים הנכונה כשאתם יוצרים אישורים.

cp certs/ca.crt certs/ca-api.crt

הספרייה $HOME/.spanner/private-keys מכילה את המפתח הפרטי של רשות האישורים. חשוב מאוד לגבות ולאבטח את הספרייה הזו. משתמשים שיש להם גישה למפתח הפרטי יכולים לחתום על אישורים שרירותיים, שלקוחות שסומכים על רשות האישורים (CA) עם החתימה העצמית סומכים עליהם. אפשר גם ליצור רשות אישורים נוספת (או להשתמש ברשות אישורים חיצונית מהימנה) לאישורי ה-API. במסמך הזה אנחנו משתמשים באותה רשות אישורים לכל סוגי האישורים.

2. יצירת אישורי שרת

צריך ליצור שני סוגים של אישורי שרת:

  • אישור API: משתמשים באישור הזה כדי להצפין את התקשורת ממערכות שיוצרות אינטראקציה עם הפריסה.

  • אישור שרת Spanner: שרתי Spanner Omni משתמשים באישור הזה כדי להצפין את התקשורת ביניהם.

ההגדרה הזו מאפשרת לנהל את האישורים האלה בצורה גמישה. לדוגמה, אפשר להשתמש ברוטציית אישורים.

יצירת אישור השרת של Spanner

כדי ליצור את אישור השרת, מריצים את הפקודה הבאה:

# Comma-separate names of the Spanner servers; wildcards are supported.
SERVER_NAMES=*.pod.NAMESPACE
./google/spanner/bin/spanner certificates create-server --hostnames=${SERVER_NAMES} --ca-certificate-directory certs --output-directory certs

הפקודה הזו יוצרת את server.crt ואת server.key בספרייה certs.

יצירת אישור ה-API

כדי ליצור את אישור ה-API, מריצים את הפקודה הבאה:

OMNI_ENDPOINT=spanner.NAMESPACE
./google/spanner/bin/spanner certificates create-server --filename-prefix=api --hostnames=${OMNI_ENDPOINT} --ca-certificate-directory certs --output-directory certs

הפקודה הזו יוצרת את api.crt ואת api.key בספרייה certs. במקרה הצורך, השתמשו ברשות אישורים חיצונית מהימנה לאישורי ה-API.

3. יצירת אישורי לקוח

אתם יכולים להשתמש באישורי לקוח כדי לאמת משתמשים ואפליקציות. אישורי לקוח מאפשרים mTLS בין הלקוח לשרת. אם אתם לא מתכוונים להשתמש ב-mTLS, אתם יכולים לדלג על השלב הזה.

אותה רשות אישורים (CA) שחותמת על אישור ה-API צריכה לחתום על אישורי הלקוח, שצריכים להכיל גם שם משתמש לצורך הרשאה. בדוגמה הזו, נשתמש במשתמש admin, שהוא המשתמש שמוגדר כברירת מחדל לכל מסד נתונים חדש. מידע נוסף זמין במאמר אימות והרשאה ב-Spanner Omni.

USERNAME=admin
./google/spanner/bin/spanner certificates create-client $USERNAME --output-directory clientcerts --ca-certificate-directory certs

הפקודה הזו יוצרת את client.crt ואת client.key בספרייה clientcerts. שולחים את הקבצים האלה לכל מכונה שמתחברת לפריסה.

אם אתם מתכננים להשתמש באישורי לקוח עם ספריית הלקוח של Java, אתם צריכים ליצור את מפתח האישור בפורמט PKCS#8. משתמשים בפקודה הבאה:

USERNAME=admin
./google/spanner/bin/spanner certificates create-client $USERNAME --output-directory clientcerts --ca-certificate-directory certs --generate-pkcs8-key

4. יצירת קבוצת המפתחות של ה-wrapper

כדי להצפין מפתחות פנימיים, כמו מפתחות להצפנה ולחתימה של טוקנים, Spanner Omni משתמש בערכת מפתחות עוטפת של מפתח להצפנת מפתחות הצפנה (KEK) שמותקנת ב-/spanner/kms/wrapper_key בכל פוד של שרת.

כדי ליצור קובץ חדש של קבוצת מפתחות wrapper באמצעות spanner keys create-keyset, מריצים את הפקודה הבאה:

./google/spanner/bin/spanner keys create-keyset --output-file=kms/wrapper_key

כברירת מחדל, spanner keys create-keyset יוצר מפתח AES256_GCM. כדי ליצור סוג אחר של מפתח, משתמשים בדגל --key-template עם אחד מהערכים הבאים של סוג המפתח: AES256_GCM,‏ AES128_GCM,‏ AES256_GCM_RAW,‏ CHACHA20_POLY1305 או XCHACHA20_POLY1305.

שלב 2: דוחפים את האישורים, את קבוצת מפתחות ה-wrapper ואת סיסמת האדמין לאשכול Kubernetes

מריצים את הפקודות הבאות כדי ליצור את מרחב השמות ולהעביר את האישורים, את קבוצת מפתחות ה-wrapper ואת סיסמת האדמין לאשכול Kubernetes:

  1. יוצרים את מרחב השמות:

    kubectl create namespace NAMESPACE
    
  2. מעבירים את אישורי ה-TLS לסוד:

    kubectl create secret generic tls-certs \
      --from-file=ca.crt="certs/ca.crt" \
      --from-file=ca-api.crt="certs/ca-api.crt" \
      --from-file=server.crt="certs/server.crt" \
      --from-file=server.key="certs/server.key" \
      --from-file=api.crt="certs/api.crt" \
      --from-file=api.key="certs/api.key" \
      -n NAMESPACE
    
  3. מעבירים את קבוצת מפתחות ה-wrapper לסוד (wrapper-key), שמוטמע ב-/spanner/kms בכל pod של שרת:

    kubectl create secret generic wrapper-key \
      --from-file=wrapper_key="kms/wrapper_key" \
      -n NAMESPACE
    
  4. יוצרים קובץ סיסמה שמכיל את הסיסמה של משתמש ברירת המחדל של admin, עם הרשאות מוגבלות (ניתן לקריאה רק על ידי הבעלים, הרשאות 600):

    printf '%s' 'PASSWORD' > admin_password.txt
    chmod 600 admin_password.txt
    

    הסיסמה צריכה לעמוד בדרישות הבאות:

    • באורך של בין 8 ל-32 תווים.
    • לפחות אות גדולה אחת.
    • לפחות אות קטנה אחת.
    • לפחות מספר אחד.
    • לפחות תו מיוחד אחד.
  5. יוצרים סוד לסיסמת האדמין:

    kubectl create secret generic spanner-admin-password \
      --from-file=password=admin_password.txt \
      -n NAMESPACE
    

שלב 3: יצירת הפריסה עם הצפנת TLS

כדי ליצור את הפריסה עם הצפנת TLS, פועלים לפי השלבים הבאים.

1. הכנת ההגדרות של Helm

במאמר יצירת הגדרה של תרשים Helm מוסבר איך ליצור את הגדרת הפריסה לסביבה שלכם.

כדי להפעיל את TLS ולהגדיר את סיסמת האדמין, מגדירים את הערכים הבאים בתצורה של תרשים Helm:

# Enables TLS
global:
  insecureMode: false

# Enables client certificate authentication (mTLS)
deployment:
  enableClientCertificateAuthentication: true
  # Name of the secret containing the administrator password
  adminPasswordSecret: spanner-admin-password

2. יצירת הפריסה

מריצים את הפקודה הבאה כדי ליצור את הפריסה:

kubectl create ns monitoring

helm upgrade --install spanner-omni oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni \
  --version VERSION \
  --set global.platform=gke \
  --set global.insecureMode=false \
  --set deployment.enableClientCertificateAuthentication=true \
  --set deployment.adminPasswordSecret=spanner-admin-password \
  --namespace NAMESPACE \
  --set monitoring.enabled=true

הפקודה מפעילה משימת אתחול. אפשר לעקוב אחרי ההתקדמות באמצעות היומנים של המשימה הזו:

kubectl logs -n NAMESPACE -l app.kubernetes.io/component=bootstrap -f

הפלט מציין את ההתקדמות. בסיום, תופיע ההודעה "Deployment created successfully".

3. בדיקת הסטטוס של ה-pods

מריצים את הפקודה הבאה כדי לאמת את סטטוס ה-Pod:

kubectl get pods --watch --namespace NAMESPACE

כל הפודים נמצאים במצב READY.

4. עדכון האישור והפריסה עם פרטי מאזן העומסים

השלב הזה נדרש אם רוצים שלקוחות יתחברו מחוץ לאשכול Kubernetes.

# Get the service details
kubectl get service spanner -n NAMESPACE

# The EXTERNAL-IP:PORT is the API or deployment endpoint for your deployment.
# Update the API certificate with these details.
OMNI_ENDPOINT=EXTERNAL_IP,spanner.NAMESPACE.svc
./google/spanner/bin/spanner certificates update \
    --certificate-file=certs/api.crt \
    --certificate-key-file=certs/api.key \
    --hostnames=${OMNI_ENDPOINT} \
    --ca-certificate-directory=certs

# Update the secrets in Kubernetes
kubectl patch secret tls-certs -n NAMESPACE -p "{\"data\":{\"api.crt\":\"$(base64 -w 0 certs/api.crt)\"}}"

שלב 4: אינטראקציה עם Spanner Omni

אתם יכולים לקיים אינטראקציה עם פריסת Spanner Omni מכל VM באמצעות ה-CLI של Spanner Omni.

אם הפעלתם mTLS ללקוחות, השתמשו בדגלים הבאים עם כל פקודה:

  • --client-certificate-directory=CLIENT_CERTIFICATE_DIRECTORY

  • --ca-certificate-file=API_CA_CERT_FILE_PATH

1. התחברות ל-Spanner Omni (אופציונלי)

מתחברים ל-Spanner Omni (השלב הזה אופציונלי אם משתמשים באישורי לקוח):

./google/spanner/bin/spanner auth login admin \
    --ca-certificate-file=certs/ca-api.crt \
    --deployment-endpoint=DEPLOYMENT_ENDPOINT

כשמופיעה בקשה, מזינים את הסיסמה שהוגדרה ב-admin_password.txt.

Successfully logged in as "admin"

2. יצירת מסד נתונים

מריצים את הפקודה הבאה כדי ליצור מסד נתונים:

./google/spanner/bin/spanner --deployment-endpoint=DEPLOYMENT_ENDPOINT databases create DATABASE_NAME --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts

3. פתיחת SQL Shell

מריצים את הפקודה הבאה כדי לפתוח את המעטפת:

./google/spanner/bin/spanner sql --database=DATABASE_NAME --deployment-endpoint=DEPLOYMENT_ENDPOINT --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts

4. יצירת טבלה והוספת נתונים

מריצים את פקודות ה-SQL הבאות:

spanner> CREATE TABLE names (nameId INT64 NOT NULL, name String(100)) PRIMARY KEY (nameId);
Query OK, 0 rows affected (4.62 sec)

spanner> INSERT names (nameId, name) VALUES (1, "Jack");
Query OK, 1 rows affected (0.18 sec)

5. אימות הפריסה

כדי להציג את רשימת מסדי הנתונים, מריצים את הפקודה הבאה:

./google/spanner/bin/spanner databases list --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts --deployment-endpoint=DEPLOYMENT_ENDPOINT

הפלט אמור להיראות כך:

שם STATE VERSION_RETENTION_PERIOD EARLIEST_VERSION_TIME ENABLE_DROP_PROTECTION
DATABASE_NAME מוכן שעה 2025-02-07T12:25:30Z FALSE

כדי לשלוח שאילתה על הנתונים, מריצים את הפקודה הבאה:

./google/spanner/bin/spanner sql --database=DATABASE_NAME --ca-certificate-file=certs/ca-api.crt --client-certificate-directory=clientcerts --deployment-endpoint=DEPLOYMENT_ENDPOINT

מריצים את פקודות ה-SQL הבאות:

SHOW TABLES;
SELECT * FROM names;

לחלופין, אתם יכולים לפעול לפי ההוראות במאמר שימוש ב-PGAdapter עם Spanner Omni כדי להגדיר את PGAdapter ולבצע פעולות באמצעות כלים כמו psql.

שלב 5: מעקב אחרי הפריסה

אם התקנתם את Spanner Omni באמצעות monitoring.enabled=true, ‏Prometheus אוסף את המדדים. אתם יכולים להשתמש ב-Grafana כדי להציג את המדדים האלה באופן חזותי.

1. קבלת פרטי השירות

מריצים את הפקודות הבאות כדי לקבל את פרטי השירות:

# Prometheus service details. Default port is 9090.
kubectl get service prometheus-service -n monitoring

# Grafana service details. Default port is 3000.
kubectl get service grafana -n monitoring

המאמרים הבאים