ניתוב תנועה מעומסי עבודה של Cloud Service Mesh לשירותי Cloud Run

בדף הזה מוסבר איך לנתב באופן מאובטח תעבורת רשת מעומסי עבודה של Cloud Service Mesh ב-GKE לשירותי Cloud Run.

שימו לב: כשמנתבים תעבורה מ-GKE ל-Cloud Run, לא צריך להוסיף את שירות Cloud Run ל-Cloud Service Mesh. עם זאת, שירות Cloud Run חייב להיות באותו פרויקט כמו אשכול GKE של Cloud Service Mesh. המגבלה הזו קיימת בזמן שהתכונה זמינה בגרסת טרום-השקה (Public Preview).

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

בקטעים הבאים אנחנו מניחים:

  1. אשכול GKE עם Cloud Service Mesh מופעל.
  2. פרסתם שירות של Cloud Run.

לחלופין, אפשר להריץ את הפקודות הבאות כדי לפרוס שירות לדוגמה ב-Cloud Run.

  1. יוצרים הקשר kubeconfig לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME --project=PROJECT_ID  --location=CLUSTER_LOCATION
    

    כאשר:

    • CLUSTER_NAME הוא שם האשכול.
    • PROJECT_ID הוא מזהה הפרויקט.
    • CLUSTER_LOCATION הוא האזור או האזור הזמין של האשכול.
  2. פורסים שירות לדוגמה ב-Cloud Run:

    gcloud run deploy hello-world \
      --image=us-docker.pkg.dev/cloudrun/container/hello \
      --no-allow-unauthenticated \
      --port=8080 \
      --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --region=us-central1 \
      --project=PROJECT_ID
    

    כאשר:

    • PROJECT_NUMBER הוא מספר הפרויקט.
    • PROJECT_ID הוא מזהה הפרויקט.

הגדרת IAM

כדי להפעיל שירותים של Cloud Run, צריך לעבור את הבדיקות של ניהול הזהויות והרשאות הגישה (IAM) ב-Cloud Run. צריך להקצות לחשבון השירות של Google את התפקיד Cloud Run Invoker. בנוסף, צריך להגדיר את חשבון השירות של GKE Kubernetes (KSA) כדי להתחזות לחשבון השירות של Google.

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

  1. הוספת מדיניות IAM שמקושרת לחשבון שירות ב-IAM:

    gcloud iam service-accounts add-iam-policy-binding PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA]"
    

    כאשר:

    • NAMESPACE הוא שם מרחב השמות. לצורך המדריך הזה, אפשר להשתמש במרחב השמות default.
    • KSA הוא השם של חשבון השירות של Kubernetes. לצורך המדריך הזה, אפשר להשתמש ב-KSA default.
  2. מוסיפים הערה לחשבון השירות:

    kubectl annotate serviceaccount KSA \
      --namespace NAMESPACE \
      iam.gke.io/gcp-service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
    
  3. מקצים את התפקיד Cloud Run Invoker לחשבון השירות של Google:

    gcloud run services add-iam-policy-binding hello-world \
      --region=us-central1 \
      --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
      --role="roles/run.invoker"
    

הגדרת שירות Cloud Run כ-GCPBackend

בקטע הזה, חושפים את שירות Cloud Run לעומסי העבודה של GKE באמצעות GCPBackend. ‫GCPBackend מורכב מהרכיבים הבאים:

  1. פרטים על חזית העורף (Frontend) – במיוחד, שם המארח והיציאה שבהם עומסי העבודה של GKE ישתמשו כדי להתקשר אל GCPBackend הזה.
  2. פרטי ה-Backend – פרטי שירות Cloud Run כמו שם השירות, המיקום ומספר הפרויקט.

השדה GCPBackend מכיל את פרטי שם המארח והיציאה, וגם את פרטי CloudService (שם השירות, המיקום ומספר הפרויקט). עומסי העבודה של GKE צריכים להשתמש בשם המארח ובפורט של GCPBackend בבקשות ה-HTTP שלהם כדי לגשת לשירות Cloud Run.

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

  1. יוצרים אזור מנוהל:

    gcloud dns managed-zones create prod \
        --description="zone for gcpbackend" \
        --dns-name=gcpbackend \
        --visibility=private \
        --networks=default
    

    בדוגמה הזו, שם ה-DNS הוא gcpbackend ורשת ה-VPC היא default.

  2. מגדירים את הרשומה כך שהדומיין יהיה ניתן לפתרון:

    gcloud beta dns record-sets create *.gcpbackend \
      --ttl=3600 --type=A --zone=prod \
      --rrdatas=10.0.0.1
    
  3. יוצרים את GCPBackend עם שם מארח בדומיין הקודם:

    cat <<EOF > gcp-backend.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPBackend
    metadata:
      name: cr-gcp-backend
      namespace: NAMESPACE
    spec:
      hostname: hello-world.gcpbackend
      type: CloudRun
      cloudrun:
        service: hello-world
        regions: [us-central1]
    EOF
    kubectl apply -f gcp-backend.yaml
    

    בדוגמה הזו, GCP_BACKEND_NAME הוא cr-gcp-backend.

  4. יוצרים Pod לבדיקה כדי לוודא את הקישוריות מ-GKE ל-Cloud Run:

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: testcurl
      namespace: default
    spec:
      containers:
      - name: curl
        image: curlimages/curl
        command: ["sleep", "3000"]
    EOF
    
    kubectl exec testcurl -c curl -- curl http://hello-world.gcpbackend/hello
    

    עכשיו עומסי העבודה שלכם ב-GKE יכולים לגשת לשירות Cloud Run על ידי שליחת בקשות HTTP אל hello-world.gcpbackend/hello.

כדי למנוע התנגשות עם שירותי Kubernetes קיימים או עם רשומות שירות של Istio, מומלץ להשתמש בשמות שונים ל-GCPBackend. אם יש התנגשות, סדר העדיפות (מהגבוה לנמוך) הוא Kubernetes Service,‏ istio ServiceEntry ו-GCPBackend.

שימו לב: השירות הווירטואלי וה-GCPBackend חייבים להיות באותו מרחב שמות, והשירות של Cloud Run חייב להיות באותו פרויקט כמו אשכול ה-GKE של Cloud Service Mesh.

(אופציונלי) שימוש בשם המארח של Cloud Run במקום ב-Cloud DNS

לכל שירות Cloud Run מוקצה שם מארח (לדוגמה, hello-world.us-central1.run.app) שאפשר לפתור את ה-DNS שלו באופן גלובלי. אפשר להשתמש בשם המארח הזה ישירות בשם המארח של GCPBackend ולדלג על ההגדרה של Cloud DNS.

cat <<EOF | kubectl apply -f -
apiVersion: networking.gke.io/v1
kind: GCPBackend
metadata:
  name: cr-gcp-backend
  namespace: NAMESPACE
spec:
  hostname: hello-world.us-central1.run.app
  type: CloudRun
  cloudrun:
    service: hello-world
    region: [us-central1]
EOF

עכשיו עומסי העבודה שלכם ב-GKE יכולים לגשת לשירות Cloud Run על ידי שליחת בקשות HTTP אל hello-world.us-central1.run.app.

(אופציונלי) הגדרת Istio Virtual Service או Destination Rule

אפשר להגדיר את Istio Virtual Service או את Istio Destination Rule עבור שם המארח של GCPBackend כדי להגדיר מדיניות צרכנים או לקוחות לבקשות אל GCPBackend.

בדוגמה הבאה מוזרם עיכוב של 5 שניות ל-50% מהבקשות, ומתבצעת ביטול (סטטוס HTTP‏ 503) ל-10% מהבקשות שנשלחות אל GCPBackend.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: cr-virtual-service
  namespace: NAMESPACE
spec:
  hosts:
  - hello-world.us-central1.run.app
  gateways:
  - mesh
  http:
  - fault:
      delay:
        percentage:
          value: 50  # Delay 50% of requests
        fixedDelay: 5s
      abort:
        percentage:
          value: 10  # Abort 10% of requests
        httpStatus: 503
  - route:
    - destination:
        host: hello-world.us-central1.run.app
EOF

בדוגמה הזו, VIRTUAL_SERVICE_NAME הוא cr-virtual-service.

פתרון בעיות

בקטע הזה מוסבר איך לפתור בעיות נפוצות ב-Cloud Service Mesh וב-Cloud Run.

יומנים של Cloud Run Sidecar

שגיאות ב-Envoy מתועדות ב-Cloud Logging.

לדוגמה, אם לחשבון השירות של Cloud Run לא ניתן התפקיד trafficdirector client בפרויקט של רשת ה-mesh, השגיאה הבאה תתועד ביומן:

StreamAggregatedResources gRPC config stream to trafficdirector.googleapis.com:443 closed: 7, Permission 'trafficdirector.networks.getConfigs' denied on resource '//trafficdirector.googleapis.com/projects/525300120045/networks/mesh:test-mesh/nodes/003fb3e0c8927482de85f052444d5e1cd4b3956e82b00f255fbea1e114e1c0208dbd6a19cc41694d2a271d1ab04b63ce7439492672de4499a92bb979853935b03d0ad0' (or it may not exist).

CSDS

אפשר לאחזר את מצב הלקוח של Traffic Director באמצעות CSDS:

gcloud alpha container fleet mesh debug proxy-status --membership=<CLUSTER_MEMBERSHIP> --location=<CLUSTER_LOCATION>
External Clients:
....

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