אוטומציה של ניהול אישורי TLS בשער הכניסה של Cloud Service Mesh באמצעות Certificate Authority Service

במדריך הזה נסביר למפעילים של פלטפורמות איך להשתמש במנפיק של Certificate Authority Service‏ (CA Service) בכלי cert-manager כדי לבצע אוטומציה של ניהול אישורי TLS בשער הכניסה של Cloud Service Mesh. האישורים מאפשרים לשער הכניסה לסיים את תעבורת הנתונים של HTTPS ושל TLS ו-mTLS אחרים שמגיעים מלקוחות בענן וירטואלי פרטי (VPC), אבל מחוץ ל-Service mesh. ההנחה במדריך הזה היא שיש לכם היכרות בסיסית עם Kubernetes ועם אישורי TLS.

מבוא

‫Cloud Service Mesh מספק אישורי TLS לכל עומס עבודה ברשת שירותים. האישורים האלה מאפשרים תקשורת מוצפנת ומאומתת הדדית של TLS‏ (mTLS) בין עומסי עבודה ב-Service mesh. אחד ממרכזי האישורים הנתמכים מנפיק את האישורים וחותם עליהם.

עם זאת, Cloud Service Mesh לא מקצה אישורים באופן אוטומטי לשער הכניסה לתנועה שנכנסת לרשת שירותים. פתרון נפוץ הוא שימוש בכלי cert-manager בקוד פתוח כדי להפוך את ניהול האישורים של שער הכניסה לאוטומטי.

הכלי cert-manager מבקש אישורים ממנפיק, שמייצג רשות אישורים (CA). שירות CA הואGoogle Cloud שירות שמאפשר לכם ליצור רשות CA פרטית משלכם. הכלי cert-manager יכול לבקש אישורים משירות CA באמצעות הנפקת אישורים חיצונית לשירות CA בקוד פתוח.

רשות אישורים פרטית יכולה להנפיק אישורי TLS שמאמתים ומצפינים תנועה בתוך רשת פנימית. שערי כניסה של Cloud Service Mesh מוגדרים לעיתים קרובות כדי לאפשר תעבורה נכנסת מלקוחות שנמצאים בתוך ה-VPC אבל מחוץ ל-Service Mesh. לתעבורת נתונים ברשת פנימית, אפשר להשתמש ב-CA פרטי בשירות CA כדי להנפיק אישורים לשער הכניסה.

במדריך הזה מוסבר איך להגדיר את הכלי cert-manager ואת ספק האישורים CA Service כדי להפוך את ההקצאה והחידוש של אישורי TLS לאוטומטיים בשער הכניסה. הכלי cert-manager מקצה אישורים בתור משאבי סודות של Kubernetes מסוג TLS. כשכלי cert-manager מחדש אישור, הוא מעדכן את משאב הסוד עם אישור חדש. שער הכניסה מפעיל את Envoy Proxy, והוא תומך בשירות גילוי הסודות (SDS) של Envoy. ‫SDS מאפשר לשער הכניסה להתחיל להשתמש באישור חדש בלי שמנהל מערכת יצטרך להפעיל מחדש או לטעון מחדש את התהליך.

שרתי proxy מסוג Sidecar שמהווים חלק מהרשת יכולים לקבל אישורי TLS משירות CA או מרשות האישורים של Cloud Service Mesh. במדריך הזה, משתמשים ב-CA Service גם לאישורים של שרת proxy מסוג קובץ עזר חיצוני וגם לאישורים של שער כניסה. כך אפשר להשתמש ברשות אישורים בסיסית אחת לכל אישורי ה-TLS.

בתרשים הבא מוצגים המשאבים שאתם מקצים במדריך הזה. אתם מקצים מאזן עומסי רשת פנימי להעברת סיגנל ללא שינוי לשער הכניסה. מאזן עומסי רשת פנימי להעברת סיגנל ללא שינוי הוא לא שרת proxy, ולכן הוא לא סוגר חיבורי TCP או מבצע לחיצות ידיים של TLS. במקום זאת, הוא מנתב את החיבורים אל הפודים של פריסת istio-ingressgateway.

הסוד hello-example-com-credential מכיל אישור ומפתח פרטי. שער hello מגדיר את הפודים של פריסת istio-ingressgateway לשימוש באישור ובמפתח הפרטי האלה כדי לבצע לחיצות יד ב-TLS לבקשות עם שם המארח hello.example.com.

ניהול mtls באמצעות שירות CA

ה-pods של פריסת google-cas-issuer במרחב השמות cert-manager מבקשים אישורים מרשות האישורים שאתם יוצרים בשירות CA. יוצרים קשר בין מדיניות ניהול הזהויות והגישה לבין ca-service-isser פודים, כדי לאפשר להם להתחזות לחשבון שירות של Google באמצעות איחוד זהויות של עומסי עבודה ל-GKE. אתם נותנים לחשבון השירות הזה של Google הרשאה לבקש אישורים מה-CA שלכם בשירות CA על ידי יצירת קשירת מדיניות IAM במאגר ה-CA שלכם.

מטרות

עלויות

במדריך הזה השתמשנו ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

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

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

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

  1. במסוף Google Cloud , עוברים לדף לבחירת הפרויקט ואז בוחרים פרויקט או יוצרים פרויקט.

  2. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  3. במסוף Google Cloud , עוברים אל Cloud Shell.

    בחלק התחתון של Google Cloud המסוף ייפתח סשן של Cloud Shell ותופיע הודעה של שורת הפקודה. כדי להריץ את כל הפקודות במדריך הזה, משתמשים ב-Cloud Shell.

  4. מגדירים את הפרויקט במסוף שבו רוצים להשתמש במדריך הזה: Google Cloud

    gcloud config set core/project PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט ב-Cloud.

    בתיבת הדו-שיח לאישור Cloud Shell, לוחצים על אישור. כשלוחצים על Authorize, מאשרים לפקודות gcloud שמריצים ב-Cloud Shell להשתמש בפרטי הכניסה של המשתמש כדי לבצע אימות ל-Google APIs.

  5. מפעילים את ממשקי מנהל המשאבים,‏ GKE,‏ GKE Fleet,‏ Cloud Service Mesh certificate authority ו-CA Service API:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        gkehub.googleapis.com \
        meshca.googleapis.com \
        privateca.googleapis.com
    

הגדרת שירות CA

בקטע הזה, יוצרים CA בסיסי ושני CAs משניים בשירות CA. רשות CA משנית אחת מנפיקה אישורים לשער הכניסה, ורשות CA משנית אחרת מנפיקה אישורים לשרתי proxy מסוג sidecar ברשת.

כדי לפשט את התהליך, במדריך הזה משתמשים באותו פרויקט עבור אשכול GKE וגם עבור רשויות אישורים (CA) בסיסיות ומשניות. בסביבה שלכם, אתם יכולים להשתמש בפרויקט אחר עבור אשכול GKE ורשויות האישורים.

  1. ב-Cloud Shell, יוצרים מאגר CA לשימוש ב-CA הבסיסי:

    gcloud privateca pools create ROOT_CA_POOL \
        --location CA_LOCATION \
        --tier enterprise
    
    • ROOT_CA_POOL הוא שם מאגר אישורי ה-CA. לדוגמה, root-ca-pool-tutorial.
    • CA_LOCATION הוא המיקום של מאגר האישורים. לדוגמה, us-central1.

    אפשר לראות את רשימת המיקומים שבהם שירות ה-CA זמין באמצעות הפקודה הבאה: gcloud privateca locations list

  2. יצירה והפעלה של רשות אישורים (CA) עליונה:

    gcloud privateca roots create ROOT_CA \
        --auto-enable \
        --key-algorithm ec-p384-sha384 \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --subject "CN=Example Root CA, O=Example Organization" \
        --use-preset-profile root_unconstrained
    
    • ROOT_CA הוא השם שרוצים להשתמש בו עבור רשות האישורים הבסיסית. לדוגמה, root-ca-tutorial.
  3. יוצרים מאגר CA לשימוש ב-CA המשני שמנפיק אישורים לשער הכניסה:

    gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --tier devops
    
    • SUBORDINATE_CA_POOL_GATEWAYS הוא השם של מאגר רשויות האישורים. לדוגמה, subordinate-ca-mtls-pool-gateways-tutorial.
  4. יוצרים ומפעילים את רשות האישורים המשנית שמנפיקה אישורים לשער הכניסה:

    gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --subject "CN=Example Gateway mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS הוא השם שרוצים להשתמש בו עבור רשות האישורים המשנית. לדוגמה, subordinate-ca-mtls-gateways-tutorial.
    • הדגל --use-preset-profile מגדיר את ה-CA המשני לשימוש בפרופיל האישור Subordinate mTLS. הפרופיל הזה מאפשר לרשות האישורים המשנית להנפיק אישורי TLS ללקוח ולשרת עבור mTLS.

    אם רוצים ששער הכניסה ישתמש ב-TLS פשוט במקום ב-mTLS, רשות האישורים המשנית צריכה להנפיק רק אישורי TLS לשרתים. במקרה כזה, אפשר להשתמש בפרופיל האישור Subordinate server TLS (subordinate_server_tls_pathlen_0) במקום זאת.

  5. יוצרים מדיניות הנפקת אישורים:

    cat << EOF > policy.yaml
    baselineValues:
      keyUsage:
        baseKeyUsage:
          digitalSignature: true
          keyEncipherment: true
        extendedKeyUsage:
          serverAuth: true
          clientAuth: true
      caOptions:
        isCa: false
    identityConstraints:
      allowSubjectPassthrough: false
      allowSubjectAltNamesPassthrough: true
      celExpression:
        expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") )
    EOF
    

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

  6. יוצרים מאגר CA לשימוש ב-CA המשני שמנפיק אישורים לשרתי ה-proxy מסוג sidecar ברשת. החלת מדיניות ההנפקה על מאגר ה-CA:

    gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \
     --issuance-policy policy.yaml \
     --location CA_LOCATION \
     --tier devops
    
    • SUBORDINATE_CA_POOL_SIDECARS הוא השם של מאגר רשויות האישורים. לדוגמה, subordinate-ca-mtls-pool-sidecars-tutorial.
  7. יוצרים ומפעילים את רשות ה-CA המשנית שמנפיקה אישורים לשרתי ה-proxy של Sidecar ברשת:

    gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS הוא השם שרוצים להשתמש בו עבור רשות האישורים המשנית. לדוגמה, subordinate-ca-mtls-sidecars-tutorial.

יצירת אשכול של Google Kubernetes Engine

  1. ב-Cloud Shell, יוצרים אשכול GKE:

    gcloud container clusters create CLUSTER_NAME \
        --enable-ip-alias \
        --num-nodes 4 \
        --release-channel regular \
        --scopes cloud-platform \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
    

    מחליפים את CLUSTER_NAME בשם שרוצים לתת לאשכול. לדוגמה, asm-ingress-cert-manager-ca-service.

    מחליפים את ZONE באזור שבו רוצים להשתמש עבור האשכול. לדוגמה, us-central1-f.

    כמה נקודות חשובות לגבי הפקודה:

    • הדגל --release-channel בוחר את ערוץ ההפצה של GKE לאשכול.
    • גם Cloud Service Mesh וגם הנפקת שירות CA לכלי cert-manager מחייבים הגדרה של היקף cloud-platform בצמתי האשכול.
    • הארגומנט --workload-pool מפעיל את איחוד שירותי אימות הזהות של עומסי עבודה ל-GKE, שמאפשר לחשבון השירות של Kubernetes שהנפיק את שירות CA להתחזות לחשבון שירות של Google. ההתחזות הזו מאפשרת ל-pods של הנפקת אישורים בשירות CA לגשת ל-CA Service API בלי להוריד קובץ מפתח לחשבון השירות של Google.
  2. להעניק הרשאות אדמין של אשכול לחשבון המשתמש:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    כדי ליצור את הכללים של בקרת גישה מבוססת-תפקידים (RBAC) עבור Cloud Service Mesh, וכדי להתקין את הכלי cert-manager, אתם צריכים את ההרשאות שמוענקות על ידי Kubernetes cluster-adminClusterRole.

התקנת מישור הבקרה של Anthos Service Mesh

במדריך הזה מוסבר איך להתקין Cloud Service Mesh מנוהל עבור אשכול GKE ב- Google Cloud, כשכל המשאבים נמצאים בפרויקט אחד. בסביבה שלכם, אתם יכולים להחיל את הפתרון שמתואר במסמך הזה באמצעות Cloud Service Mesh מנוהל או מישור בקרה בתוך האשכול.

ב-Cloud Service Mesh יש מגוון אפשרויות התקנה לתרחישים שונים. אחרי שתסיימו את המדריך הזה, מומלץ לעיין במדריך ההתקנה כדי לבחור את האפשרות שהכי מתאימה לסביבה שלכם.

  1. ב-Cloud Shell, מורידים את כלי ההתקנה asmcli:

    curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.19
    
    chmod +x asmcli
    

    משתמשים ב-asmcli כדי להתקין את מישור הבקרה של Cloud Service Mesh.

  2. מתקינים את מישור הבקרה של Cloud Service Mesh:

    ./asmcli install \
        --ca gcp_cas \
        --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \
        --cluster_location ZONE \
        --cluster_name CLUSTER_NAME \
        --enable_all \
        --enable_registration \
        --fleet_id PROJECT_ID \
        --managed \
        --output_dir asm-files \
        --project_id PROJECT_ID \
        --verbose
    

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

    asmcli: Successfully installed ASM.
    

התקנת שער הכניסה

  1. ב-Cloud Shell, יוצרים מרחב שמות של Kubernetes עבור שער הכניסה:

    kubectl create namespace GATEWAY_NAMESPACE
    
    • GATEWAY_NAMESPACE הוא השם של מרחב השמות שרוצים להשתמש בו לשער הכניסה. לדוגמה, istio-ingress.
  2. שומרים כתובת IP פנימית סטטית לשימוש במאזן עומסי רשת פנימי להעברת סיגנל ללא שינוי של שער הכניסה:

    LOAD_BALANCER_IP=$(gcloud compute addresses create \
        asm-ingress-gateway-ilb \
        --region REGION \
        --subnet default \
        --format 'value(address)')
    
    • מחליפים את REGION באזור שמכיל את האזור או האזורים שבהם משתמשים הצמתים של אשכול GKE. לדוגמה, אם האזור us-central1-f משמש באשכול, צריך להחליף את REGION ב-us-central1.

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

  3. יוצרים מניפסט של אופרטור בשביל שער הכניסה:

    cat << EOF > ingressgateway-operator.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      name: ingressgateway-operator
      annotations:
        config.kubernetes.io/local-config: "true"
    spec:
      profile: empty
      revision: asm-managed
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: GATEWAY_NAMESPACE
          enabled: true
          k8s:
            overlays:
            - apiVersion: apps/v1
              kind: Deployment
              name: istio-ingressgateway
              patches:
              - path: spec.template.metadata.annotations
                value:
                  inject.istio.io/templates: gateway
              - path: spec.template.metadata.labels.sidecar\.istio\.io/inject
                value: "true"
              - path: spec.template.spec.containers[name:istio-proxy]
                value:
                  name: istio-proxy
                  image: auto
            service:
              loadBalancerIP: $LOAD_BALANCER_IP
            serviceAnnotations:
              networking.gke.io/load-balancer-type: Internal
              networking.gke.io/internal-load-balancer-allow-global-access: "true"
    EOF
    

    חשוב לדעת את הפרטים הבאים על מניפסט האופרטור:

  4. יוצרים את מניפסט ההתקנה של שער הכניסה באמצעות מניפסט האופרטור וכלי istioctl שהסקריפט asmcli הוריד כשמתקינים את מישור הבקרה:

    ./asm-files/istioctl manifest generate \
        --filename ingressgateway-operator.yaml \
        --output ingressgateway
    
  5. מתקינים את שער הכניסה:

    kubectl apply --recursive --filename ingressgateway/
    

התקנה של הכלי cert-manager

  1. ב-Cloud Shell, מורידים ומחילים את מניפסט ההתקנה של הכלי cert-manager:

    CERT_MANAGER_VERSION=v1.5.4
    
    curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
    
    kubectl apply --filename cert-manager.yaml
    

    ההתקנה של הכלי cert-manager נמשכת כדקה.

התקנת בקר הנפקת אישורי CA

בקר הנפקת האישורים של שירות CA מאפשר לכלי cert-manager לבקש אישורים באמצעות שירות CA. הבקר משתמש במנגנון ההרחבה external issuer של הכלי cert-manager.

  1. ב-Cloud Shell, יוצרים חשבון שירות של Google:

    gcloud iam service-accounts create CAS_ISSUER_GSA \
        --display-name "CA Service issuer for cert-manager"
    
    • CAS_ISSUER_GSA הוא השם של חשבון השירות של Google. לדוגמה, cert-manager-ca-service-issuer.

    בקר הנפקת האישורים של Certificate Authority Service משתמש בחשבון השירות הזה של Google כדי לבצע אימות ל-APIs של Certificate Authority Service.

  2. יוצרים קשר בין מדיניות ניהול הזהויות והגישה (IAM) לבין חשבון השירות של Google, שהוא בקר הנפקת האישורים של Certificate Authority Service, כדי לאפשר לו לבקש אישורים ממאגר רשויות האישורים שמכיל את רשות האישורים המשנית שלכם:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  3. מורידים את מניפסט ההתקנה של בקר הנפקת האישורים של שירות רשות האישורים:

    CAS_ISSUER_VERSION=v0.5.3
    
    curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
    
  4. יוצרים קשר בין מדיניות IAM כדי לאפשר לksa-google-cas-issuerחשבון השירות של Kubernetes במרחב השמות cert-manager להתחזות לחשבון השירות של Google ‏ (GSA) באמצעות איחוד זהויות של עומסי עבודה ל-GKE:

    gcloud iam service-accounts add-iam-policy-binding \
     CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    

    קבוצות ה-Pod של בקר הנפקת האישורים של CA Service משתמשות בחשבון השירות של Kubernetes‏ ksa-google-cas-issuer.

  5. מתקינים את בקר הנפקת אישורי CA בשירות באשכול GKE:

    kubectl apply --filename ca-service-issuer.yaml
    
  6. מוסיפים את ההערה iam.gke.io/gcp-service-account של איחוד שירותי אימות הזהות של עומסי עבודה ל-GKE לחשבון השירות של Kubernetes שבו נעשה שימוש בקבוצות ה-Pod של בקר הנפקת אישורי CA:

    kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \
       "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
    

    ההערה הזו מודיעה ל-GKE שחשבון השירות ב-Kubernetes יכול להתחזות לחשבון השירות ב-Google כדי לגשת ל-Google APIs.

יצירת מנפיק אישורים

  1. ב-Cloud Shell, יוצרים ומחילים מניפסט של GoogleCASIssuer:

    cat << EOF > gateway-cas-issuer.yaml
    apiVersion: cas-issuer.jetstack.io/v1beta1
    kind: GoogleCASIssuer
    metadata:
      name: gateway-cas-issuer
      namespace: GATEWAY_NAMESPACE
    spec:
      caPoolId: SUBORDINATE_CA_POOL_GATEWAYS
      location: CA_LOCATION
      project: PROJECT_ID
    EOF
    
    kubectl apply --filename gateway-cas-issuer.yaml
    

    הנפקן מאפשר לכלי cert-manager להקצות אישורים ממאגר רשויות האישורים המשניות במרחב השמות של שער הכניסה

פריסת אפליקציה לדוגמה

בקטע הזה מאמתים שכלי cert-manager יכול להשתמש במונפק של CA Service כדי לקבל אישורים מ-CA Service. כדי לאמת, מבצעים פריסה של אפליקציית דוגמה עם הגדרת ניתוב בקשות ואישור לשער הכניסה.

  1. ב-Cloud Shell, יוצרים מרחב שמות למשאבים של האפליקציה לדוגמה:

    cat << EOF > sample-app-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: APP_NAMESPACE
      annotations:
        mesh.cloud.google.com/proxy: '{"managed":"true"}'
      labels:
        istio.io/rev: asm-managed
    EOF
    
    kubectl apply --filename sample-app-namespace.yaml
    
    • APP_NAMESPACE הוא שם מרחב השמות של האפליקציה לדוגמה. לדוגמה, sample-app.

    ההערה mesh.cloud.google.com/proxy מפעילה את מישור הנתונים המנוהל למרחב השמות.

    התווית istio.io/rev: asm-managed בוחרת את ערוץ ההפצה הרגיל עבור מישור הנתונים המנוהל במרחב השמות של האפליקציה לדוגמה. אם אתם משתמשים בערוצי הפצה מהירים או יציבים, אתם יכולים לשנות את הערך של התווית הזו.

  2. יוצרים משאב Deployment לאפליקציה לדוגמה:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: APP_NAMESPACE
      labels:
        app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - image: gcr.io/google-samples/hello-app:1.0
            name: hello-app
            ports:
            - containerPort: 8080
    EOF
    
    kubectl apply --filename deployment.yaml
    
  3. יוצרים משאב Service לאפליקציה לדוגמה:

    cat << EOF > service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
      namespace: APP_NAMESPACE
    spec:
      ports:
      - name: http-hello
        port: 8080
      selector:
        app: hello
      type: ClusterIP
    EOF
    
    kubectl apply --filename service.yaml
    
    • SERVICE_NAME הוא שם השירות. לדוגמה, hello.
  4. יוצרים משאב אישור לשם הדומיין hello.example.com באמצעות מנפיק האישורים:

    cat << EOF > certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: hello-example-com-certificate
      namespace: GATEWAY_NAMESPACE
    spec:
      secretName: hello-example-com-credential
      commonName: hello.example.com
      dnsNames:
      - hello.example.com
      duration: 24h
      renewBefore: 8h
      issuerRef:
        group: cas-issuer.jetstack.io
        kind: GoogleCASIssuer
        name: gateway-cas-issuer
    EOF
    
    kubectl apply --filename certificate.yaml
    

    מרחב השמות של האישור חייב להיות זהה למרחב השמות של שער הכניסה. בדרך כלל, רק אדמינים של הפלטפורמה יכולים לשנות משאבים במרחב השמות הזה, כי שינויים יכולים להשפיע על כל Service mesh. הכלי cert-manager יוצר את משאב הסוד לאישור ה-TLS באותו מרחב שמות. המשמעות היא שאדמינים של אפליקציות לא צריכים גישה למרחב השמות של שער הכניסה.

    אפשר להוסיף שמות מארחים נוספים בdnsNames הרשימה שבאישור. שמות המארחים האלה נכללים באישור כשמות חלופיים של נושאים (SAN).

  5. יוצרים משאב Gateway לאפליקציה לדוגמה:

    cat << EOF > gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - APP_NAMESPACE/hello.example.com
        port:
          name: https-hello
          number: 443
          protocol: HTTPS
        tls:
          credentialName: hello-example-com-credential
          mode: MUTUAL
    EOF
    
    kubectl apply --filename gateway.yaml
    
    • GATEWAY_NAME הוא שם השער. לדוגמה, hello.
    • השדה credentialName ב-Gateway תואם לשדה secretName באישור. הכלי cert-manager יוצר סוד של Kubernetes עם אישור ה-TLS מ-CA Service. האישור הזה מאפשר לשער הכניסה לסיים את תנועת ה-TLS שמיועדת ל-hello.example.com.

    קובץ המניפסט של שער הגישה מציין TLS MUTUAL (mTLS). אם רוצים להגדיר את השער ל-TLS רגיל, צריך להגדיר את מצב ה-TLS של השער ל-SIMPLE.

  6. יוצרים משאב VirtualService לאפליקציה לדוגמה:

    cat << EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: hello
      namespace: APP_NAMESPACE
    spec:
      hosts:
      - hello.example.com
      gateways:
      - GATEWAY_NAMESPACE/GATEWAY_NAME
      http:
      - route:
        - destination:
            host: SERVICE_NAME
            port:
              number: 8080
    EOF
    
    kubectl apply --filename virtual-service.yaml
    

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

    אדמינים של אפליקציות עם הרשאות לעריכת VirtualService במרחב השמות של האפליקציה לדוגמה יכולים לשנות את הניתוב לפי שדות אחרים של בקשות, כמו נתיב כתובת ה-URL, בלי לתאם עם אדמינים של הפלטפורמה.

כדי לבדוק אפשרויות הגדרה אחרות, אפשר לקרוא את התיעוד של ה-API בנושא המשאבים Certificate,‏ Gateway ו-VirtualService.

אפשר להחיל מדיניות אימות והרשאה על תעבורה שנכנסת ל-Service mesh דרך שער הכניסה. לשם כך, מומלץ לקרוא את מאמרי העזרה בנושא ממשקי ה-API של Istio‏ PeerAuthentication ו-AuthorizationPolicy.

אימות הפתרון

בסעיף הזה מאמתים שאפשר לשלוח בקשות HTTPS באמצעות mTLS לאפליקציית הדוגמה מחוץ ל-Service mesh. כדי לאמת, יוצרים מכונת VM ב-Compute Engine, מבקשים אישור TLS של לקוח מ-CA Service ומשתמשים באישור הזה כדי לאמת את הבקשה לאפליקציית הדוגמה.

צריכה להיות לכם גישת SSH למופע של מכונה וירטואלית. רשת ברירת המחדל כוללת כלל חומת אש שמאפשר גישת SSH. אם אין לכם גישת SSH, אתם צריכים לפעול לפי המסמכים בנושא כללי חומת אש כדי ליצור כלל חומת אש שמאפשר חיבורי TCP נכנסים ביציאה 22.

  1. ב-Cloud Shell, יוצרים חשבון שירות של Google:

    gcloud iam service-accounts create CLIENT_VM_GSA \
        --display-name "CA Service tutorial VM instance service account"
    
    • CLIENT_VM_GSA הוא השם של חשבון השירות של Google. לדוגמה, cas-tutorial-client.

    מקצים את חשבון השירות הזה של Google למכונה וירטואלית של Compute Engine.

  2. מקצים לחשבון השירות של Google את התפקיד CA Service Certificate Requester (שליחת בקשות לאישור שירות CA) במאגר המשני של רשות האישורים בשערי הכניסה:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    

    לתפקיד הזה מוקצות הרשאות לבקשת אישורים ממאגר אישורי ה-CA.

  3. יוצרים מכונה וירטואלית ב-Compute Engine באותו VPC כמו אשכול GKE:

    gcloud compute instances create cas-tutorial-client \
        --scopes cloud-platform \
        --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --zone ZONE
    

    למכונה הווירטואלית נדרש היקף הגישה cloud-platform כדי לגשת ל-CA Service API.

  4. שומרים את כתובת ה-IP של מאזן עומסי הרשת הפנימי להעברת סיגנל ללא שינוי של שער הכניסה לקובץ:

    kubectl get services istio-ingressgateway \
       --namespace GATEWAY_NAMESPACE \
       --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
    
  5. שומרים בקובץ את האישור של המפתח הציבורי של רשות האישורים הבסיסית:

    gcloud privateca roots describe ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --format 'value(pemCaCertificates)' > root-ca-cert.pem
    
  6. מעתיקים את אישור הבסיס של הרשות שמנפיקה את האישורים (CA) ואת הקובץ שמכיל את כתובת ה-IP של מאזן עומסי הרשת הפנימי להעברת סיגנל ללא שינוי של שער הכניסה למכונה הווירטואלית:

    gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \
       --zone ZONE
    
  7. מתחברים למופע של המכונה הווירטואלית באמצעות SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    מריצים את שאר הפקודות שבקטע הזה מתוך סשן ה-SSH.

  8. מתקינים את החבילות ca-certificates ו-coreutils, ואת כלי שורת הפקודה curl,‏ openssl ו-jq:

    sudo apt-get update --yes
    
    sudo apt-get install --yes ca-certificates coreutils curl jq openssl
    
  9. יוצרים זוג מפתחות לאישור לקוח TLS:

    openssl genrsa -out private-key.pem 2048
    
    openssl rsa -in private-key.pem -pubout -out public-key.pem
    
  10. שולחים שאילתה לשרת המטא-נתונים כדי לקבל את כתובת האימייל של הזהות של חשבון השירות של Google שמחובר למכונה הווירטואלית:

    GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
    
  11. יוצרים קובץ JSON שמשמש כגוף הבקשה כשמבקשים אישור TLS ללקוח מ-API של Certificate Authority Service:

    cat << EOF > request.json
    {
      "config": {
        "publicKey": {
          "format": "PEM",
          "key": "$(base64 --wrap 0 public-key.pem)"
        },
        "subjectConfig": {
          "subject": {
            "commonName": "$(hostname --short)",
            "organization": "Example Organization"
          },
          "subjectAltName": {
            "dnsNames": [
              "$(hostname --fqdn)"
            ],
            "emailAddresses": [
              "$GSA_EMAIL"
            ]
          }
        },
        "x509Config": {
          "caOptions": {
            "isCa": false
          },
          "keyUsage": {
            "baseKeyUsage": {
              "digitalSignature": true,
              "keyEncipherment": true
            },
            "extendedKeyUsage": {
              "clientAuth": true
            }
          }
        }
      },
      "lifetime": "86400s"
    }
    EOF
    

    מידע נוסף על השדות בקטע config מופיע במאמרי העזרה של CA Service API בנושא סוג CertificateConfig.

  12. שולחים בקשה לאסימון גישה מסוג OAuth 2.0 משרת המטא-נתונים:

    TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
    

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

  13. שולחים בקשה לאישור לקוח TLS מ-CA Service API ושומרים את גוף התגובה בקובץ:

    curl --silent --request POST \
        --header "Authorization: Bearer $TOKEN" \
        --header "Content-Type: application/json" \
        --data @request.json \
        --output response.json \
        "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
    

    הפקודה משתמשת בטוקן הגישה כדי לאמת את בקשת ה-API.

  14. שומרים את אישור הלקוח ואת שרשרת האישורים בקובץ:

    jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
    
  15. משתמשים ב-curl כדי לשלוח בקשת HTTPS מהמכונה הווירטואלית לאפליקציה לדוגמה:

    curl --cert client-cert-chain.pem --key private-key.pem \
        --cacert root-ca-cert.pem \
        --resolve hello.example.com:443:$(cat ilb-ip.txt) \
        --silent https://hello.example.com | head -n1
    

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

    Hello, world!
    

    התגובה הזו מראה ש-curl שלח בהצלחה את בקשת ה-HTTPS באמצעות mTLS. האפליקציה לדוגמה הגיבה עם ההודעה שמוצגת בפלט של הטרמינל.

    הפקודה curl מבצעת את הפעולות הבאות:

    • הדגלים --cert ו---key מנחים את curl להשתמש באישור ה-TLS של הלקוח ובמפתח הפרטי כדי לאמת את הבקשה. קובץ אישור הלקוח מכיל את השרשרת המלאה של האישורים, מאישור הלקוח ועד לרשות האישורים הבסיסית.

    • הדגל --cacert מורה ל-curl לאמת שאישור השרת הונפק על ידי רשות ה-CA הבסיסית שיצרתם במדריך הזה, או על ידי אחת מרשויות ה-CA המשניות שלה.

      אם לא מציינים את הדגל הזה, curl מנסה לאמת את אישור השרת באמצעות חבילת ה-CA שמוגדרת כברירת מחדל במערכת ההפעלה, כמו חבילת ca-certificates ב-Debian. האימות נכשל כי חבילת ברירת המחדל של CA לא כוללת את ה-CA הבסיסי שיצרתם במדריך הזה.

    • הדגל --resolve מורה ל-curl להשתמש בכתובת ה-IP של מאזן עומסי הרשת הפנימי להעברת סיגנל ללא שינוי כיעד לבקשות למארח hello.example.com ביציאה 443.

      אם לא מציינים את הדגל הזה, curl מנסה להשתמש ב-DNS כדי לפתור את הבעיה בשם המארח של hello.example.com. פענוח ה-DNS נכשל כי אין רשומת DNS לשם המארח הזה.

      בסביבה שלכם, מומלץ ליצור רשומת DNS מסוג A שמפנה לכתובת ה-IP של מאזן עומסי רשת פנימי מסוג passthrough ($LOAD_BALANCER_IP). כדי ליצור את הרשומה הזו באמצעות Cloud DNS, פועלים לפי ההוראות במאמרי העזרה בנושא ניהול רשומות.

    • הדגל --silent משבית את הדיווח על התקדמות ההורדה של התשובה בפלט של הטרמינל.

    • הפקודה מעבירה את הפלט של curl ל-head -n1. התוצאה היא שהפלט במסוף כולל רק את השורה הראשונה של גוף התגובה.

  16. יוצאים מסשן ה-SSH:

    exit
    

בקטע הזה, שלחתם בקשה לאישור לקוח TLS ישירות אל CA Service API. במצב שבו הלקוח הוא שער היציאה של רשת שירותים אחרת באשכול Kubernetes נפרד, אפשר להשתמש בכלי cert-manager ובספק של שירות רשות האישורים עם אותה רשות אישורים בסיסית כדי לספק אישורי לקוח לשער היציאה.

במצבים אחרים, אפשר להשתמש בכלים כמו Hashicorp Vault, ‏ Terraform או gcloud כדי לבקש אישורי TLS של לקוחות עבור עומסי עבודה מחוץ לרשת שירותים. למידע נוסף, אפשר לעיין בפתרונות לדוגמה ובמסמכי העזרה של gcloud בנושא CA Service.

(אופציונלי) הוספה של אישורי CA למאגר האישורים

בסעיף האופציונלי הזה מוסבר איך להוסיף אישורי CA למאגר של אישורי CA מהימנים עבור הפצת Debian של Linux. ההוראות האלה חלות גם על הפצות שמקורן ב-Debian, כמו Ubuntu.

הוספת אישורי רשות האישורים למאגר הזה אומרת שלא צריך לציין את המיקום של אישורי רשות אישורים מהימנים כששולחים בקשות HTTPS באמצעות curl,‏ Python,‏ Go ו-Ruby.

  1. מתחברים למופע של המכונה הווירטואלית באמצעות SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    מריצים את שאר הפקודות שבקטע הזה מתוך סשן ה-SSH.

  2. מעתיקים את אישור ה-CA הבסיסי לספרייה /usr/local/share/ca-certificates ומוודאים שלקובץ יש את הסיומת .crt:

    sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
    
  3. מגדירים את הרשאות הקובץ כך שכל המשתמשים יוכלו לקרוא את קובץ אישור ה-CA הבסיסי:

    sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
    
  4. מריצים את הסקריפט update-ca-certificates:

    sudo update-ca-certificates
    

    הסקריפט הזה מוסיף את האישור לקבוצת האישורים המהימנים בספרייה /etc/ssl/certs ובקובץ /etc/ssl/certs/ca-certificates.crt.

    הפלט שיתקבל:

    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    
  5. משתמשים ב-curl כדי לשלוח בקשת HTTPS מהמכונה הווירטואלית לאפליקציה לדוגמה:

    curl --cert client-cert-chain.pem --key private-key.pem \
       --resolve hello.example.com:443:$(cat ilb-ip.txt) \
       --silent https://hello.example.com | head -n1
    

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

    Hello, world!
    

    התגובה הזו מראה ש-curl שלח בהצלחה את בקשת ה-HTTPS באמצעות mTLS, ואימת את אישור ה-TLS של השרת משער הכניסה באמצעות מאגר אישורי ה-CA שמוגדר כברירת מחדל.

  6. יוצאים מסשן ה-SSH:

    exit
    

פתרון בעיות

אם בקר הנפקת האישורים של שירות CA לא יוצר את הסוד של אישור TLS, אפשר לעיין ביומנים של בקר הנפקת האישורים של שירות CA:

kubectl logs deployment/google-cas-issuer --namespace cert-manager

אם נתקלתם בבעיות בהתקנת Cloud Service Mesh, הריצו את הכלי asmcli כדי לאמת את פרויקט בענן ואת אשכול GKE.

אם נתקלתם בבעיות אחרות במהלך ההדרכה הזו, מומלץ לעיין במסמכים הבאים:

הסרת המשאבים

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

מחיקת הפרויקט

  1. ב-Cloud Shell, מוחקים את הפרויקט:

    gcloud projects delete PROJECT_ID
    

מחיקת המשאבים

אם רוצים לשמור את Google Cloud הפרויקט שבו השתמשתם במדריך הזה, צריך למחוק את המשאבים הבודדים:

  1. ב-Cloud Shell, מבטלים את הרישום של אשכול GKE מ-GKE Fleet:

    gcloud container hub memberships unregister CLUSTER_NAME \
        --gke-cluster ZONE/CLUSTER_NAME
    
  2. מחיקת אשכול GKE:

    gcloud container clusters delete CLUSTER_NAME \
        --zone ZONE --async --quiet
    
  3. מחיקת הקישורים למדיניות IAM במאגר המשני של רשות האישורים:

    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  4. משביתים ומתזמנים את המחיקה של רשויות האישורים המשניות ורשות האישורים העליונה:

    gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca roots disable ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --quiet
    
    gcloud privateca roots delete ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --ignore-active-certificates \
        --quiet
    
  5. מוחקים את הקישור של מדיניות IAM לחשבון השירות של Google של בקר הנפקת אישורי CA:

    gcloud iam service-accounts remove-iam-policy-binding \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    
  6. מוחקים את חשבונות השירות של Google:

    gcloud iam service-accounts delete --quiet \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
    
  7. מוחקים את כתובת ה-IP השמורה של מאזן העומסים:

    gcloud compute addresses delete asm-ingress-gateway-ilb \
        --region REGION --quiet
    
  8. מחיקת מכונה וירטואלית ב-Compute Engine:

    gcloud compute instances delete cas-tutorial-client \
        --zone ZONE --quiet
    

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