הגדרת מאזן עומסים קלאסי של אפליקציות (ALB) ל-Cloud Service Mesh

סקירה כללית

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

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

Cloud Load Balancing מספק יכולות רבות של ניהול קצה בענן, כולל איזון עומסים גלובלי מסוג anycast, אישורים שמנוהלים על ידי Google, ניהול זהויות והרשאות גישה, Cloud Next Generation Firewall ומערכת לזיהוי פריצות בענן. Cloud Service Mesh יכול לשלב בצורה חלקה את היכולות האלה של קצה הרשת במודל הבא של תעבורת נתונים נכנסת לרשת. שער הענן של Service Mesh מספק דרך מאוחדת להגדיר שער כניסה של Cloud Service Mesh באמצעות Cloud Load Balancing בו-זמנית דרך Kubernetes Gateway API.

דיאגרמה שמציגה מאזן עומסים עם Cloud Service Mesh

בהשוואה למדריך הקודם שלנו, From edge to mesh: Exposing service mesh applications through GKE Ingress, עם שער ענן של רשת שירותים, עכשיו אפשר לפרוס את המודל הזה באמצעות משאב Kubernetes Gateway אחד, מה שמפשט את תהליך הפריסה של איזון עומסים בענן ובאשכול יחד.

הגבלות על תצוגה מקדימה

בגרסת הטרום-השקה של התכונה הזו, חלות המגבלות הבאות:

  • אין תמיכה בשערי כניסה מרובי-אשכולות.
  • אין תמיכה באשכולות Autopilot.
  • יש תמיכה רק במאזן עומסים קלאסי של אפליקציות (ALB). אין תמיכה במאזן עומסים גלובלי חיצוני של אפליקציות (שנקרא לפעמים מאזן עומסים מתקדם) ובמאזן עומסים פנימי של אפליקציות.
  • תעבורת הנתונים בין מאזן העומסים הקלאסי של אפליקציות לבין שער הכניסה של Cloud Service Mesh מוצפנת באמצעות TLS. עם זאת, מאזן העומסים הקלאסי של האפליקציות (ALB) לא יאמת את האישור שסופק על ידי שער הכניסה של Cloud Service Mesh. המגבלה הזו חלה על כל המשתמשים ב-HTTP(S) Load Balancer. Google Cloud
  • אם Cloud Service Mesh GatewayClasses נמחק מאשכול, הוא לא יותקן מחדש באופן אוטומטי. עם זאת, זה לא ישפיע על השימושיות של התכונה.
  • הלוגיקה של התאמת המסלולים לא פועלת לפי המפרטים של Gateway API, אלא לפי הסדר של HTTPRoute. ההתנהגות הזו תשתנה בגרסאות עתידיות בהתאם למפרטים של Gateway API.

דרישות

  • Managed Cloud Service Mesh מותקן באשכול Google Kubernetes Engine ‏ (GKE) שפועלת בו גרסה 1.24 ואילך. אין תמיכה באשכולות אחרים של GKE Enterprise.
  • גרסה v1beta1 של Kubernetes Gateway API בלבד.

דרישות מוקדמות

  • מפעילים את ממשקי ה-API הבאים בפרויקט:

    • compute.googleapis.com
    • container.googleapis.com
    • certificatemanager.googleapis.com
    • serviceusage.googleapis.com
    gcloud services enable \
       compute.googleapis.com \
       container.googleapis.com \
       certificatemanager.googleapis.com \
       serviceusage.googleapis.com
    

פריסת שער ענן של רשת Service mesh עבור רשת עם אשכול יחיד

בקטע הזה מוסבר איך לפרוס משאב Kubernetes Gateway שפורס מאזן עומסים של אפליקציות קלאסי ושער כניסה של Cloud Service Mesh.

הפעלת Gateway API עם Cloud Service Mesh מנוהל

  1. מפעילים את Gateway API באשכול. גרסת אשכול GKE צריכה להיות 1.24 ואילך.

  2. מתקינים את Cloud Service Mesh מנוהל עם rapid או regular כערוץ ההפצה.

פריסת משאב השער

כשפורסים שער ענן של Service mesh, משתמשים במשאבי שער Kubernetes כדי לפרוס גם Cloud Load Balancing וגם שער כניסה של Cloud Service Mesh בפעולה אחת. שימו לב: משאבי Kubernetes Gateway שונים ממשאבי Istio Gateway.

מידע נוסף על ההבדלים מופיע במאמר בנושא Kubernetes Gateways ו-Istio Gateways. לכל שער Kubernetes יש GatewayClass שמציין את הסוג והיכולות שלו. לשער של Service mesh בענן יש GatewayClass עם היכולת לפרוס גם Cloud Load Balancing וגם שער כניסה של Cloud Service Mesh.

  1. שומרים את מניפסט GatewayClass הבא בקובץ בשם l7-gateway-class.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: GatewayClass
    metadata:
      name: asm-l7-gxlb
    spec:
      controllerName: mesh.cloud.google.com/gateway
    
  2. פורסים את GatewayClass באשכול:

    kubectl apply -f l7-gateway-class.yaml
    
  3. מוודאים ש-GatewayClass מופיע אחרי ההתקנה:

    kubectl get gatewayclasses.gateway.networking.k8s.io
    

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

    NAME          CONTROLLER
    asm-l7-gxlb   mesh.cloud.google.com/gateway
    gke-l7-rilb   networking.gke.io/gateway
    gke-l7-gxlb   networking.gke.io/gateway
    

    יכול להיות שיעברו כמה דקות עד שכל המשאבים יופעלו. אם לא רואים את הפלט הצפוי, צריך לוודא שאתם עומדים בכל הדרישות המוקדמות.

    יופיע גם GatewayClass:

    gke-l7-gxlb   networking.gke.io/gateway
    

    הפקודה הזו משמשת לפריסת מאזן העומסים הקלאסי של אפליקציות (ALB) ב-Google Cloud.

  4. יוצרים מרחב שמות ייעודי לשער הענן של רשת השירותים:

    kubectl create namespace istio-ingress
    
  5. שומרים את מניפסט השער הבא בקובץ בשם gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
    
  6. פורסים את ה-Gateway באשכול במרחב השמות istio-ingress:

    kubectl apply -f gateway.yaml
    
  7. מוודאים שאובייקטים של Kubernetes Gateway API נוצרו:

    kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
    

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

    NAME                                CLASS         ADDRESS         READY   AGE
    asm-gw-gke-servicemesh-cloud-gw     gke-l7-gxlb   34.111.114.64   True    9m40s
    asm-gw-istio-servicemesh-cloud-gw   istio                                 9m44s
    servicemesh-cloud-gw                asm-l7-gxlb                           9m44s
    

כשפורסים את אובייקט ה-API של Kubernetes Gateway, קורים הדברים הבאים:

  • מאזן עומסים חיצוני מסוג HTTP(S) נפרס ומוגדר. יכול להיות שיחלפו כמה דקות עד שהשער יופיע, אבל כשהוא יופיע, הוא יציין את כתובת ה-IP ויופיע עם הערות שכוללות את השמות של משאבי איזון העומסים ב-Compute Engine שנוצרו.
  • פריסת שער הכניסה של Cloud Service Mesh נוצרת במרחב השמות istio-ingress. הפעולה הזו יוצרת את מופעי ה-proxy של Envoy שיקבלו תנועה ממאזן העומסים.
  • מאזן העומסים יצפין את כל התנועה וינתב אותה אל שער הכניסה של Cloud Service Mesh.

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

פריסת אפליקציות וניתוב

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

  1. מתייגים את default Namespace כדי להפעיל הזרקה של sidecar.

    kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
    
  2. שומרים את מניפסט השער הבא בקובץ בשם whereami.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v1
      template:
        metadata:
          labels:
            app: whereami-v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v1
    spec:
      selector:
        app: whereami-v1
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v2
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v2
      template:
        metadata:
          labels:
            app: whereami-v2
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v2"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v2
    spec:
      selector:
        app: whereami-v2
      ports:
      - port: 8080
        targetPort: 8080
    

    קובץ המניפסט הזה יוצר את ההרשאות Service/whereami-v1, Service/whereami-v2, Deployment/whereami-v1 ו-Deployment/whereami-v2 עבור whereami, אפליקציה פשוטה שמפיקה פלט JSON כדי לציין את הזהות והמיקום שלה. תפרסו שתי גרסאות שונות של האפליקציה.

  3. יוצרים את השירותים והפריסות:

    kubectl apply -f whereami.yaml
    

    אחרי שהיא תפעל, יהיו ארבעה פודים של whereami שפועלים באשכול.

  4. מוודאים שכל ארבעת ה-Pods פועלים:

    kubectl get pods
    

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

    whereami-v1-7c76d89d55-qg6vs       2/2     Running   0          28s
    whereami-v1-7c76d89d55-vx9nm       2/2     Running   0          28s
    whereami-v2-67f6b9c987-p9kqm       2/2     Running   0          27s
    whereami-v2-67f6b9c987-qhj76       2/2     Running   0          27s
    
  5. שומרים את מניפסט ה-HTTPRoute הבא בקובץ בשם http-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: where-route
    spec:
     parentRefs:
     - kind: Gateway
       name: servicemesh-cloud-gw
       namespace: istio-ingress
     hostnames:
     - "where.example.com"
     rules:
     - matches:
       - headers:
         - name: version
           value: v2
       backendRefs:
       - name: whereami-v2
         port: 8080
     - backendRefs:
       - name: whereami-v1
         port: 8080
    
  6. פורסים את http-route.yaml באשכול:

    kubectl apply -f http-route.yaml
    

    ה-HTTPRoute הזה מפנה אל servicemesh-cloud-gw, כלומר הוא יגדיר את שער הענן של Service mesh כך שהוא יגדיר את שער הכניסה הבסיסי של Cloud Service Mesh עם כללי הניתוב האלה. ה-HTTPRoute מבצע את אותה פעולה כמו Istio VirtualService, אבל הוא משתמש ב-Kubernetes Gateway API כדי לעשות זאת. מכיוון ש-Gateway API הוא מפרט של OSS עם הרבה הטמעות בסיסיות, הוא ה-API הכי מתאים להגדרת ניתוב בשילוב של מאזני עומסים שונים (כמו פרוקסי ומאזני עומסים של Cloud Service Mesh).

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

    VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
    

    הפלט הוא כתובת IP.

    echo $VIP
    
    34.111.61.135
    
  8. שולחים תנועה לכתובת ה-IP של השער כדי לוודא שההגדרה הזו פועלת בצורה תקינה. שולחים בקשה אחת עם הכותרת version: v2 ובקשה אחת בלי הכותרת כדי לוודא שהניתוב מתבצע בצורה נכונה בשתי גרסאות האפליקציה.

    curl ${VIP} -H "host: where.example.com"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v1",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v1-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    
    curl ${VIP} -H "host: where.example.com" -H "version: v2"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v2",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v2-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    

פריסת שער בסביבת ייצור

בקטע הקודם ראינו דוגמה פשוטה מאוד של שער ענן של Service mesh. השלבים הבאים מבוססים על הדוגמה הפשוטה, ומציגים הגדרה מוכנה לייצור שממחישה את היתרונות של העברת חלק מהפונקציונליות של ניתוב תעבורת הנתונים הנכנסת (ingress) למאזן העומסים (LB).

בדוגמה הבאה, לוקחים את servicemesh-cloud-gw מהקטע הקודם ומוסיפים את היכולות הבאות כדי ליצור שער מאובטח וקל יותר לניהול:

  • פורסים את שער הגישה עם כתובת IP סטטית שתישמר גם אם התשתית הבסיסית תשתנה.
  • ממירים את השער לקבלת תנועת HTTPS עם אישור בחתימה עצמית.
  1. יוצרים כתובת IP חיצונית סטטית. כתובת IP סטטית שימושית כי התשתית הבסיסית עשויה להשתנות בעתיד, אבל אפשר לשמור את כתובת ה-IP.

    gcloud compute addresses create whereami-ip \
        --global \
        --project PROJECT_ID
    
  2. יוצרים אישור בחתימה עצמית לדומיין where-example-com:

    openssl genrsa -out key.pem 2048
    cat <<EOF >ca.conf
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    [dn_requirements]
    0.organizationName        = example
    commonName                = where.example.com
    [sans_list]
    DNS.1                     = where.example.com
    EOF
    
    openssl req -new -key key.pem \
        -out csr.pem \
        -config ca.conf
    
    openssl x509 -req \
        -signkey key.pem \
        -in csr.pem \
        -out cert.pem \
        -extfile ca.conf \
        -extensions extension_requirements \
        -days 365
    
    gcloud compute ssl-certificates create where-example-com \
        --certificate=cert.pem \
        --private-key=key.pem \
        --global \
        --project PROJECT_ID
    

    יש הרבה דרכים ליצור אישורי TLS. אפשר ליצור אותם באופן ידני בשורת הפקודה, ליצור אותם באמצעות אישורים שמנוהלים על ידי Google, או ליצור אותם באופן פנימי על ידי מערכת תשתית המפתח הציבורי (PKI) של החברה. בדוגמה הזו, יוצרים באופן ידני אישור בחתימה עצמית. בדרך כלל לא משתמשים באישורים בחתימה עצמית בשירותים ציבוריים, אבל הם מאפשרים להבין את המושגים האלה בקלות רבה יותר.

    למידע נוסף על יצירת אישור בחתימה עצמית באמצעות Kubernetes Secret, ראו אבטחת שער.

  3. מעדכנים את gateway.yaml באמצעות המניפסט הבא:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: where-example-com
      addresses:
      - type: NamedAddress
        value: whereami-ip
    
  4. פורסים מחדש את שער הכניסה באשכול:

    kubectl apply -f gateway.yaml
    
  5. משיגים את כתובת ה-IP של כתובת ה-IP הסטטית:

    VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
    
  6. משתמשים ב-curl כדי לגשת לדומיין של שער הכניסה. מכיוון ש-DNS לא מוגדר לדומיין הזה, צריך להשתמש באפשרות ‎--resolve כדי להנחות את curl לתרגם את שם הדומיין לכתובת ה-IP של השער:

    curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
    

    אחרי שהפעולה תושלם, הפלט ייראה כך:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=where.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: where.example.com (matched)
    *  issuer: O=example; CN=where.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "where-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "where-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

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

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

ארכיטקטורת ASM

ה-servicemesh-cloud-gw וה-GatewayClass שלו asm-l7-gxlbמסתירים חלק מרכיבי התשתית הפנימיים כדי לפשט את חוויית המשתמש. שירות Cloud Load Balancing מפסיק את תעבורת ה-TLS באמצעות אישור פנימי, והוא גם מבצע בדיקות תקינות בשכבת ה-proxy של שער הכניסה של Cloud Service Mesh. ‫whereami-route שנפרס ב-App & Routing Deployment מגדיר את פרוקסי שער ה-Ingress של Cloud Service Mesh לניתוב תעבורה לשירות הנכון שמתארח ב-Mesh.

בדוגמה הבאה, לוקחים את servicemesh-cloud-gw מהקטע הקודם ומוסיפים את היכולות הבאות כדי ליצור שער מאובטח וקל יותר לניהול:

  • פורסים את שער הגישה עם כתובת IP סטטית שתישמר גם אם התשתית הבסיסית תשתנה.
  • ממירים את השער לקבלת תנועת HTTPS עם אישור בחתימה עצמית.
  1. יוצרים כתובת IP חיצונית סטטית. כתובת IP סטטית שימושית כי התשתית הבסיסית עשויה להשתנות בעתיד, אבל אפשר לשמור את כתובת ה-IP.

    gcloud compute addresses create whereami-ip \
        --global \
        --project PROJECT_ID
    
  2. יוצרים אישור בחתימה עצמית לדומיין where-example-com:

    openssl genrsa -out key.pem 2048
    cat <<EOF >ca.conf
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    [dn_requirements]
    0.organizationName        = example
    commonName                = where.example.com
    [sans_list]
    DNS.1                     = where.example.com
    EOF
    
    openssl req -new -key key.pem \
        -out csr.pem \
        -config ca.conf
    
    openssl x509 -req \
        -signkey key.pem \
        -in csr.pem \
        -out cert.pem \
        -extfile ca.conf \
        -extensions extension_requirements \
        -days 365
    
    gcloud compute ssl-certificates create where-example-com \
        --certificate=cert.pem \
        --private-key=key.pem \
        --global \
        --project PROJECT_ID
    

    יש הרבה דרכים ליצור אישורי TLS. אפשר ליצור אותם באופן ידני בשורת הפקודה, ליצור אותם באמצעות אישורים שמנוהלים על ידי Google, או ליצור אותם באופן פנימי על ידי מערכת תשתית המפתח הציבורי (PKI) של החברה. בדוגמה הזו, יוצרים באופן ידני אישור בחתימה עצמית. בדרך כלל לא משתמשים באישורים בחתימה עצמית בשירותים ציבוריים, אבל הם מאפשרים להבין את המושגים האלה בקלות רבה יותר.

    למידע נוסף על יצירת אישור בחתימה עצמית באמצעות Kubernetes Secret, ראו אבטחת שער.

  3. מעדכנים את gateway.yaml באמצעות המניפסט הבא:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: where-example-com
      addresses:
      - type: NamedAddress
        value: whereami-ip
    
  4. פורסים מחדש את שער הכניסה באשכול:

    kubectl apply -f gateway.yaml
    
  5. משיגים את כתובת ה-IP של כתובת ה-IP הסטטית:

    VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
    
  6. משתמשים ב-curl כדי לגשת לדומיין של שער הכניסה. מכיוון ש-DNS לא מוגדר לדומיין הזה, צריך להשתמש באפשרות ‎--resolve כדי להנחות את curl לתרגם את שם הדומיין לכתובת ה-IP של השער:

    curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
    

    אחרי שהפעולה תושלם, הפלט ייראה כך:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=where.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: where.example.com (matched)
    *  issuer: O=example; CN=where.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "where-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "where-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

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

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

ארכיטקטורת ASM

ה-servicemesh-cloud-gw וה-GatewayClass שלו asm-l7-gxlbמסתירים חלק מרכיבי התשתית הפנימיים כדי לפשט את חוויית המשתמש. שירות Cloud Load Balancing מפסיק את תעבורת ה-TLS באמצעות אישור פנימי, והוא גם מבצע בדיקות תקינות בשכבת ה-proxy של שער הכניסה של Cloud Service Mesh. ‫whereami-route שנפרס ב-App & Routing Deployment מגדיר את פרוקסי שער ה-Ingress של Cloud Service Mesh לניתוב תעבורה לשירות הנכון שמתארח ב-Mesh.

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