סנכרון סודות עם סודות של Kubernetes

במאמר הזה מתואר איך מסנכרנים סודות שמאוחסנים ב-Secret Manager עם סודות של Kubernetes באשכולות Google Kubernetes Engine ‏ (GKE).

תהליך הסנכרון מאפשר לאפליקציות שפועלות ב-GKE לגשת לסודות מ-Secret Manager באמצעות שיטות סטנדרטיות של Kubernetes, כמו משתני סביבה או טעינת נפח. האפשרות הזו שימושית לאפליקציות שכבר מתוכננות לקרוא סודות מאובייקט הסוד של Kubernetes, במקום לעדכן אותן כדי לגשת ישירות ל-Secret Manager.

המלצה: התכונה של סנכרון סודות היא חלופה לתוסף Secret Manager, שמעלה סודות כקבצים בזיכרון ישירות ל-Pods. מומלץ להשתמש בתוסף Secret Manager בכל פעם שהאפליקציה תומכת בו, כי זו שיטה מאובטחת יותר לגשת לסודות מ-Secret Manager ב-GKE.

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

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

  • מפעילים את ממשקי ה-API של Secret Manager ו-Google Kubernetes Engine.

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאה serviceusage.services.enable. איך מקצים תפקידים

    הפעלת ממשקי ה-API

  • מתקינים ואז מפעילים את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, תוכלו להריץ את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית.

  • מוודאים שאשכול GKE פועל. כדי להשתמש בתכונה הזו צריך GKE מגרסה 1.33 ואילך.

  • מוודאים שאיחוד זהויות של עומסי עבודה ל-GKE מופעל באשכול GKE. הפרטים האלה נדרשים לאימות. איחוד זהויות של עומסי עבודה ל-GKE מופעל כברירת מחדל באשכול Autopilot.

  • צריך לוודא שיש לכם את ההרשאות הנדרשות לניהול זהויות והרשאות גישה (IAM) כדי לנהל את אשכולות GKE ואת Secret Manager.

הפעלת סנכרון סודות באשכול GKE

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

הפעלת סנכרון סודות באשכול חדש

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

אשכול רגיל

כדי להשתמש ב-Secret Manager בשורת הפקודה, קודם צריך להתקין את Google Cloud CLI או לשדרג לגרסה 378.0.0 ואילך. ב-Compute Engine או ב-GKE, צריך לעבור אימות באמצעות ההיקף cloud-platform.

הפעלת סנכרון סודות ללא רוטציה אוטומטית.

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync

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

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync \
    --enable-secret-sync-rotation

הפעלת סנכרון של סודות עם מרווח סיבוב מותאם אישית. המרווח המינימלי הוא דקה אחת.

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --workload-pool=PROJECT_ID.svc.id.goog \
    --enable-secret-sync \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=60s

מחליפים את מה שכתוב בשדות הבאים:

  • CLUSTER_NAME: השם של אשכול GKE
  • CONTROL_PLANE_LOCATION: האזור של מישור הבקרה של האשכול, למשל us-central1 או us-east1-a
  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud

אשכול Autopilot

כדי להשתמש ב-Secret Manager בשורת הפקודה, קודם צריך להתקין את Google Cloud CLI או לשדרג לגרסה 378.0.0 ואילך. ב-Compute Engine או ב-GKE, צריך לעבור אימות באמצעות ההיקף cloud-platform.

הפעלת סנכרון סודות ללא רוטציה אוטומטית.

gcloud container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync

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

gcloud container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync \
    --enable-secret-sync-rotation

הפעלת סנכרון של סודות עם מרווח סיבוב מותאם אישית. המרווח המינימלי הוא דקה אחת.

gcloud container clusters create-auto CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=60s

מחליפים את מה שכתוב בשדות הבאים:

  • CLUSTER_NAME: השם של אשכול GKE
  • CONTROL_PLANE_LOCATION: האזור של מישור הבקרה של האשכול, למשל us-central1 או us-east1-a

הפעלת סנכרון סודות באשכול קיים

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

gcloud

כדי להשתמש ב-Secret Manager בשורת הפקודה, קודם צריך להתקין את Google Cloud CLI או לשדרג לגרסה 378.0.0 ואילך. ב-Compute Engine או ב-GKE, צריך לעבור אימות באמצעות ההיקף cloud-platform.

הפעלת סנכרון סודות באשכול קיים

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync

הפעלת רוטציה עם מרווח זמן מותאם אישית

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-secret-sync-rotation \
    --secret-sync-rotation-interval=300s

השבתת הסיבוב

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --no-enable-secret-sync-rotation

מחליפים את מה שכתוב בשדות הבאים:

  • CLUSTER_NAME: השם של אשכול GKE
  • CONTROL_PLANE_LOCATION: האזור של מישור הבקרה של האשכול, למשל us-central1 או us-east1-a

הגדרת סנכרון של סודות

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

  1. יוצרים Kubernetes ServiceAccount באמצעות הפקודה הבאה:

    kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
    

    מחליפים את מה שכתוב בשדות הבאים:

    • KSA_NAME: השם של חשבון השירות שלכם ב-Kubernetes
    • NAMESPACE: מרחב השמות של Kubernetes שבו רוצים ליצור את חשבון השירות
  2. יוצרים מדיניות הרשאה ב-IAM שמפנה אל Kubernetes ServiceAccount החדש, ומעניקים ל-ServiceAccount הרשאה לגשת לסוד:

    gcloud

    כדי להשתמש ב-Secret Manager בשורת הפקודה, קודם צריך להתקין את Google Cloud CLI או לשדרג לגרסה 378.0.0 ואילך. ב-Compute Engine או ב-GKE, צריך לעבור אימות באמצעות ההיקף cloud-platform.

    gcloud secrets add-iam-policy-binding SECRET_NAME \
       --role=roles/secretmanager.secretAccessor \
       --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME
    

    מחליפים את מה שכתוב בשדות הבאים:

    • SECRET_NAME: השם של הסוד ב-Secret Manager
    • PROJECT_NUMBER: מספר הפרויקט ב- Google Cloud
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud
    • NAMESPACE: מרחב השמות של Kubernetes
    • KSA_NAME: השם של חשבון השירות שלכם ב-Kubernetes
  3. יוצרים משאב מותאם אישית מסוג SecretProviderClass באמצעות מניפסט YAML. המשאב SecretProviderClass מגדיר את הסודות הספציפיים לאחזור מ-Secret Manager, כולל שמות המשאבים והנתיבים שלהם. בנוסף, התוסף Secret Manager משתמש במשאב SecretProviderClass כדי לרשום את הסודות להרכבה ואת שם הקובץ שבו הם יורכבו.

    יוצרים קובץ spc.yaml עם התוכן הבא:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: SECRET_PROVIDER_CLASS_NAME
      namespace: NAMESPACE
    spec:
      provider: gke
      parameters:
        secrets: |
          -   resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME_1/versions/SECRET_VERSION_1"
              path: "FILENAME.txt"
          -   resourceName: "projects/SECRET_PROJECT_ID/secrets/SECRET_NAME_2/versions/SECRET_VERSION_2"
              path: "FILENAME1.txt"
    

    מחליפים את מה שכתוב בשדות הבאים:

    • SECRET_PROVIDER_CLASS_NAME: השם של אובייקט SecretProviderClass.
    • NAMESPACE: מרחב השמות של Kubernetes שבו יוצרים את המשאב הזה.
    • resourceName: מזהה המשאב המלא של הסוד ב-Secret Manager. המחרוזת הזו חייבת לכלול את מזהה הפרויקט, שם הסוד והגרסה בפורמט הבא: projects/SECRET_PROJECT_ID/secrets/SECRET_NAME/versions/SECRET_VERSION.
      • SECRET_PROJECT_ID: מזהה Google Cloud הפרויקט שבו מאוחסן הסוד. הערך הזה יכול להיות זהה לערך של PROJECT_ID אם הסוד מאוחסן באותו פרויקט שבו נמצא אשכול GKE.
      • SECRET_NAME: שם הסוד.
      • SECRET_VERSION: גרסת הסוד. גרסת הסוד צריכה להיות באותו אזור כמו האשכול.
    • path: שם הקובץ המקומי או הכינוי שערך הסוד יוצג כמותו בסביבת Kubernetes. זהו המזהה הייחודי שמקשר בין גרסה ספציפית של Secret Manager לבין הייצוג המקומי שבו משתמש האשכול. כשמבצעים סנכרון של הסוד ל-Kubernetes Secret באמצעות המשאב SecretSync, הנתיב הזה מפנה לשדה sourcePath כדי לאתר את ערך הסוד לצורך הסנכרון. אפשר למפות כמה סודות (מוגדרים על ידי resourceName) לשמות נתיבים שונים באותו SecretProviderClass.
  4. כדי להחיל את קובץ המניפסט, מריצים את הפקודה הבאה:

    kubectl apply -f spc.yaml
    
  5. יוצרים משאב מותאם אישית של SecretSync באמצעות מניפסט YAML. המשאב הזה מורה לבקר הסנכרון ליצור או לעדכן סוד של Kubernetes על סמך התוכן שמוגדר ב-SecretProviderClass.

    יוצרים קובץ secret-sync.yaml עם התוכן הבא:

    apiVersion: secret-sync.gke.io/v1
    kind: SecretSync
    metadata:
      name: KUBERNETES_SECRET_NAME
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      secretProviderClassName: SECRET_PROVIDER_CLASS_NAME
      secretObject:
        type: KUBERNETES_SECRET_TYPE
        data:
          -   sourcePath: "FILENAME.txt"
              targetKey: "TARGET_KEY1"
          -   sourcePath: "FILENAME1.txt"
              targetKey: "TARGET_KEY2"
    

    מחליפים את מה שכתוב בשדות הבאים:

    • KUBERNETES_SECRET_NAME: השם שרוצים לתת ל-Kubernetes Secret החדש שייווצר על ידי משאב SecretSync.
    • NAMESPACE: מרחב השמות של Kubernetes שבו נוצר המשאב החדש. הוא חייב להיות מרחב השמות זהה לזה של SecretProviderClass.
    • KSA_NAME: השם של Kubernetes ServiceAccount שהבקר SecretSync משתמש בו כדי ליצור ולעדכן את יעד Kubernetes Secret. לחשבון השירות הזה צריכות להיות ההרשאות הנדרשות כדי לגשת לסודות חיצוניים מ-Secret Manager.
    • SECRET_PROVIDER_CLASS_NAME: השם של אובייקט SecretProviderClass שיצרתם בשלב הקודם. המשאב SecretSync משתמש בזה כדי למצוא את ההגדרה הנכונה של הסודות.
    • KUBERNETES_SECRET_TYPE: סוג הסוד של Kubernetes שייווצר, כמו Opaque,‏ tls או docker-registry. ההגדרה הזו קובעת איך Kubernetes מטפל בנתונים של הסוד.
    • sourcePath: שם הקובץ המקומי או הכינוי (הערך של השדה path ב-SecretProviderClass) שמזהה את נתוני הסוד שיש לאחזר. הבקר SecretSync משתמש ב-sourcePath הזה כדי לבקש את התוכן הספציפי של הסוד ולהמיר אותו לסוד חדש של Kubernetes.
    • targetKey: המפתח שישמש בקטע data של סוד Kubernetes החדש שנוצר. ההגדרה הזו קובעת איך התוכן הסודי שאוחזר באמצעות sourcePath ייקרא ויאוחסן באובייקט הסודי הסופי של Kubernetes. שימוש בכמה רשומות במערך הנתונים מאפשר להגדיר כמה צמדים של מפתח-ערך באותו סוד יעד.
  6. כדי להחיל את קובץ המניפסט, מריצים את הפקודה הבאה:

    kubectl apply -f secret-sync.yaml
    

    במהלך הסנכרון, נוצר סוד של Kubernetes במרחב השמות שצוין. הסוד הזה מכיל את הנתונים שמופים מ-Secret Manager.

  7. מוודאים שנוצר סוד של Kubernetes:

    kubectl get secret KUBERNETES_SECRET_NAME -n NAMESPACE -o yaml
    

    מחליפים את מה שכתוב בשדות הבאים:

    • KUBERNETES_SECRET_NAME: השם של הסוד החדש ב-Kubernetes
    • NAMESPACE: מרחב השמות ב-Kubernetes שבו נוצר הסוד החדש
  8. כדי לפתור בעיה בסנכרון, משתמשים בפקודה הבאה:

    kubectl describe secretSync KUBERNETES_SECRET_NAME -n NAMESPACE
    

    מחליפים את מה שכתוב בשדות הבאים:

    • KUBERNETES_SECRET_NAME: השם של הסוד החדש ב-Kubernetes
    • NAMESPACE: מרחב השמות של Kubernetes שבו צריך ליצור את הסוד החדש

ניהול סבב סודות

אם מפעילים את הדגל --enable-secret-sync-rotation באשכול, בקר הסנכרון בודק מעת לעת ב-Secret Manager אם יש גרסאות חדשות של הסודות שצוינו במשאב SecretProviderClass. הדגל --secret-sync-rotation-interval קובע באיזו תדירות הבקר בודק אם יש עדכונים.

אם בקר מזהה גרסה חדשה של סוד ב-Secret Manager, הבקר מעדכן את הסוד התואם ב-Kubernetes. הבקר משווה בין הגיבובים של התוכן הסודי כדי לעדכן סודות רק כשמתרחשים שינויים.

אפליקציות שמשתמשות בסודות האלה צריכות לזהות את ערכי הסודות המעודכנים ולטעון אותם מחדש מ-Kubernetes Secret. העיצוב של האפליקציה קובע איך המידע הזה מטופל.

השבתת סנכרון הסודות

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

gcloud

כדי להשתמש ב-Secret Manager בשורת הפקודה, קודם צריך להתקין את Google Cloud CLI או לשדרג לגרסה 378.0.0 ואילך. ב-Compute Engine או ב-GKE, צריך לעבור אימות באמצעות ההיקף cloud-platform.

gcloud container clusters update CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --no-enable-secret-sync

מחליפים את מה שכתוב בשדות הבאים:

  • CLUSTER_NAME: השם של אשכול GKE
  • CONTROL_PLANE_LOCATION: האזור של מישור הבקרה של האשכול, למשל us-central1 או us-east1-a

הפקודה הזו מפסיקה את בקר הסנכרון. הפעולה הזו לא מוחקת סודות של Kubernetes שכבר נוצרו. אם כבר אין לכם צורך בסודות של Kubernetes שסונכרנו, אתם צריכים למחוק אותם באופן ידני.

מחיקת סודות מסונכרנים

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

    kubectl delete secretsync KUBERNETES_SECRET_NAME --namespace NAMESPACE

מחליפים את מה שכתוב בשדות הבאים:

  • KUBERNETES_SECRET_NAME: השם של הסוד ב-Kubernetes
  • NAMESPACE: מרחב השמות ב-Kubernetes שבו קיים הסוד

מעבר מ-Secrets Store CSI Driver הקיים

אם אתם מבצעים העברה מההתקנה הקיימת של Secrets Store CSI Driver, אתם צריכים לפעול לפי השלבים הבאים:

  1. מעדכנים את השדה provider ב-SecretProviderClass מ-gcp ל-gke. בדוגמה הבאה אפשר לראות איך מעדכנים את השדה provider:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: app-secrets-gke
    spec:
      provider: gke
      parameters:
        secrets: |
          -   resourceName: "projects/87654321/secrets/api-key-secret/versions/2"
              path: "good1.txt"
    
  2. יוצרים משאב SecretSync. משתמשים בהגדרות לדוגמה הבאות:

    apiVersion: secret-sync.gke.io/v1
    kind: SecretSync
    metadata:
      name: my-kube-secret
      namespace: NAMESPACE
    spec:
      serviceAccountName: KSA_NAME
      secretProviderClassName: my-app-secrets
      secretObject:
        type: Opaque # Or other Kubernetes Secret types
        data:
          -   sourcePath: "my-secret.txt"
              targetKey: "USERNAME"
          -   sourcePath: "another-secret.txt"
              targetKey: "PASSWORD"
    

שיקולי אבטחה

‫Secret Manager מציע תכונות אבטחה כמו בקרת גישה באמצעות IAM, מפתחות הצפנה בניהול הלקוח (CMEK) ורישום ביומן ביקורת. הסודות מוצפנים במנוחה ובזמן ההעברה ב-Secret Manager. כשמסנכרנים סודות עם סודות של Kubernetes, האבטחה שלהם בתוך האשכול תלויה בהגדרה של אשכול GKE. כמה נקודות שכדאי לחשוב עליהן:

  • אחסון: סודות של Kubernetes מאוחסנים ב-etcd, שהוא מאגר הנתונים הראשי של GKE. כברירת מחדל, GKE מצפין נתונים במנוחה. כדי לשפר את האבטחה, אפשר להצפין סודות של Kubernetes בשכבת האפליקציה באמצעות מפתח שמנוהל ב-Cloud Key Management Service ‏(Cloud KMS). הצפנה של סודות מספקת שכבת אבטחה נוספת לעומסי עבודה רגישים.

  • בקרת גישה: GKE תומך בכמה אפשרויות לניהול גישה למשאבים בפרויקטים ובאשכולות שלהם באמצעות בקרת גישה מבוססת-תפקידים (RBAC). הרשאות RBAC רחבות מדי עלולות לחשוף סודות לעומסי עבודה או למשתמשים לא מכוונים. מעניקים גישה בהתאם לעיקרון של הרשאות מינימליות, ומבצעים ביקורת על הגישה ל-Secret Manager ולסודות של Kubernetes באופן קבוע.

  • משתני סביבה: כדי לשפר את האבטחה, כדאי להטמיע סודות של Kubernetes כנפחים במקום להשתמש בהם כמשתני סביבה. כך אפשר להפחית את הסיכון לרישום ביומן בטעות או לחשיפה לתהליכים אחרים.

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