יצירת אפליקציית אינטרנט מרובת רמות באמצעות Redis ו-PHP

במדריך הזה נדגים איך ליצור אפליקציית אינטרנט רב-שכבתית באמצעות Google Kubernetes Engine ‏ (GKE).

במדריך הזה תלמדו:

בדוגמה מתוארים המושגים הבאים ב-Kubernetes:

מטרות

כדי לפרוס את האפליקציה ולהריץ אותה ב-GKE:

  1. הגדרת ה-leader של Redis
  2. הגדרת שני עוקבים של Redis
  3. הגדרת הקצה הקדמי של האתר
  4. כניסה לאתר
  5. הגדלת קנה המידה של הקצה הקדמי של האתר

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

ארכיטקטורת אשכול GKE

עלויות

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

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

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

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

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

ב-Cloud Shell מותקנת מראש התוכנה שדרושה למדריך זה, כולל kubectl ו-ה-CLI של gcloud. אם אתם לא משתמשים ב-Cloud Shell, אתם צריכים להתקין את ה-CLI של gcloud.

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. התקינו את ה-CLI של Google Cloud.

  3. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  4. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  5. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

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

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

  7. מפעילים את GKE API, אם הוא עדיין לא מופעל:

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

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable container.googleapis.com
  8. התקינו את ה-CLI של Google Cloud.

  9. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  10. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  11. יוצרים או בוחרים Google Cloud פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Google Cloud שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

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

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

  13. מפעילים את GKE API, אם הוא עדיין לא מופעל:

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

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable container.googleapis.com

הכנת הסביבה

כדי להגדיר את הסביבה:

  1. הגדרת משתני סביבה:

    export PROJECT_ID=PROJECT_ID
    export COMPUTE_LOCATION=COMPUTE_LOCATION
    

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

  2. משכפלים את המאגר ב-GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. עוברים לספריית העבודה:

    cd kubernetes-engine-samples/quickstarts/guestbook/
    

יצירת אשכול GKE

יוצרים אשכול GKE במצב Autopilot או במצב Standard:

Autopilot

gcloud container clusters create-auto guestbook \
    --location=${COMPUTE_LOCATION} \

רגילה

gcloud container clusters create guestbook \
    --location=${COMPUTE_LOCATION} \
    --num-nodes=4

התחברות לאשכול

מגדירים את kubectl לתקשורת עם האשכול:

gcloud container clusters get-credentials guestbook \
    --location=${COMPUTE_LOCATION}

הגדרת ה-leader של Redis

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

  1. קובץ המניפסט הבא מתאר פריסת Kubernetes שמריצה Pod יחיד של Redis leader:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: leader
            tier: backend
        spec:
          containers:
          - name: leader
            image: "docker.io/redis:6.0.5"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379

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

    kubectl apply -f redis-leader-deployment.yaml
    
  2. מוודאים שפוד ה-Redis הראשי פועל:

    kubectl get pods
    

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

    NAME                           READY     STATUS    RESTARTS   AGE
    redis-leader-343230949-qfvrq   1/1       Running   0          43s
    

    יכול להיות שיחלפו כמה דקות עד שהסטטוס של STATUS ישתנה מPending לRunning.

יצירת שירות Redis leader

אפליקציית האינטרנט צריכה לתקשר עם ה-leader של Redis כדי לכתוב את הנתונים שלה. אתם יכולים ליצור שירות כדי להעביר את התנועה ל-Pod הראשי של Redis.

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

  1. במניפסט הבא מתואר שירות למנהל Redis:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      ports:
      - port: 6379
        targetPort: 6379
      selector:
        app: redis
        role: leader
        tier: backend

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

    בקטע ports של קובץ המניפסט מוצהר על מיפוי יציאה יחיד. השירות מעביר את התנועה ב-port: 6379 אל targetPort: 6379 של מאגרי התגים שתואמים לתוויות selector שצוינו. ה-containerPort שמשמש בפריסה צריך להיות זהה ל-targetPort כדי להפנות תנועה אל הפריסה.

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

    kubectl apply -f redis-leader-service.yaml
    
  2. מוודאים ש-GKE יצר את השירות:

    kubectl get service
    

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

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    42s
    redis-leader   10.51.242.233   <none>        6379/TCP   12s
    

הגדרת עוקבים ב-Redis

למרות ש-Redis leader הוא פוד יחיד, אפשר להוסיף כמה Redis followers, או רפליקות, כדי להפוך אותו לזמין מאוד ולעמוד בדרישות התנועה.

  1. במניפסט הבא מתואר פריסה של פודים של Redis follower:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: follower
            tier: backend
        spec:
          containers:
          - name: follower
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-redis-follower:v2
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f redis-follower-deployment.yaml
    
  3. מוודאים ששני העותקים המשוכפלים של Redis פועלים:

    kubectl get pods
    

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

    NAME                              READY   STATUS    RESTARTS   AGE
    redis-follower-76588f55b7-bnsq6   1/1     Running   0          27s
    redis-follower-76588f55b7-qvtws   1/1     Running   0          27s
    redis-leader-dd446dc55-kl7nl      1/1     Running   0          119s
    

    יכול להיות שיחלפו כמה דקות עד שהסטטוס של STATUS ישתנה מPending לRunning.

יצירת שירות Redis follower

אפליקציית האינטרנט צריכה לתקשר עם העותקים המשניים של Redis כדי לקרוא נתונים. כדי ששרתי ה-follower של Redis יהיו ניתנים לגילוי, צריך להגדיר שירות.

  1. המאניפסט הבא מתאר שירות עבור העוקבים של Redis:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      ports:
        # the port that this service should serve on
      - port: 6379
      selector:
        app: redis
        role: follower
        tier: backend

    קובץ המניפסט הזה מציין שהשירות פועל ביציאה 6379. השדה selector של השירות תואם לקבוצות ה-Pod של Redis follower שנוצרו בשלב הקודם.

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

    kubectl apply -f redis-follower-service.yaml
    
  2. מוודאים ש-GKE יצר את השירות:

    kubectl get service
    

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

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    1m
    redis-leader   10.51.242.233   <none>        6379/TCP   49s
    redis-follower 10.51.247.238   <none>        6379/TCP   3s
    

הגדרת הקצה הקדמי של האפליקציה באינטרנט

עכשיו, אחרי שיש לכם אחסון Redis לאפליקציה, אפשר להפעיל את שרתי האינטרנט. בדומה ל-Redis followers, הקצה הקדמי נפרס באמצעות Kubernetes Deployment.

אפליקציית האינטרנט משתמשת בחלק הקדמי של PHP, שמוגדר לתקשורת עם שירותי Redis follower או leader, בהתאם לסוג הבקשה (קריאה או כתיבה). הקצה הקדמי חושף ממשק JSON ומציג ממשק משתמש מבוסס-jQuery Ajax.

  1. המניפסט הבא מתאר פריסה של שרת אינטרנט:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      replicas: 3
      selector:
        matchLabels:
            app: guestbook
            tier: frontend
      template:
        metadata:
          labels:
            app: guestbook
            tier: frontend
        spec:
          containers:
          - name: php-redis
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
            env:
            - name: GET_HOSTS_FROM
              value: "dns"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 80

    קובץ המניפסט מציין את משתנה הסביבה GET_HOSTS_FROM=dns. כשמספקים את ההגדרה לאפליקציית הקצה הקדמי באינטרנט, אפליקציית הקצה הקדמי משתמשת בשמות המארחים redis-follower ו-redis-leader כדי לבצע חיפוש DNS. חיפוש ה-DNS מוצא את כתובות ה-IP של השירותים שיצרתם בשלבים הקודמים. המושג הזה נקרא זיהוי שירותים ב-DNS.

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

    kubectl apply -f frontend-deployment.yaml
    
  2. מוודאים שהרפליקות פועלות:

    kubectl get pods -l app=guestbook -l tier=frontend
    

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

    NAME                        READY   STATUS    RESTARTS   AGE
    frontend-7b78458576-8kp8s   1/1     Running   0          37s
    frontend-7b78458576-gg86q   1/1     Running   0          37s
    frontend-7b78458576-hz87g   1/1     Running   0          37s
    

חשיפת חזית האתר בכתובת IP חיצונית

בהגדרה הנוכחית, אפשר לגשת לשירותים redis-follower ו-redis-leader שיצרתם בשלבים הקודמים רק בתוך אשכול GKE, כי סוג ברירת המחדל של שירות הוא ClusterIP.

שירות ClusterIP מספק כתובת IP אחת לקבוצת ה-Pods שאליהם השירות מפנה. אפשר לגשת לכתובת ה-IP הזו רק בתוך האשכול.

כדי להפוך את שירות הקצה הקדמי של האינטרנט לנגיש חיצונית, אפשר לציין type: LoadBalancer או type: NodePort בהגדרת השירות, בהתאם לדרישות.

קובץ המניפסט הבא מתאר שירות מסוג LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend

ההצהרה על היציאה בקטע ports מציינת את port: 80 ולא מציינת את targetPort. אם לא מציינים את המאפיין targetPort, ערך ברירת המחדל שלו הוא הערך של השדה port. במקרה הזה, השירות הזה מעביר תנועה חיצונית ביציאה 80 ליציאה 80 של הקונטיינרים בפריסת frontend.

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

kubectl apply -f frontend-service.yaml

כשיוצרים את שירות frontend, ‏ GKE יוצר מאזן עומסים וכתובת IP חיצונית. המשאבים האלה מחויבים.

כניסה לאתר של האפליקציה

כדי לגשת לאתר האפליקציה, צריך לקבל את כתובת ה-IP החיצונית של שירות frontend:

kubectl get service frontend

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

NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

יכול להיות שבעמודה EXTERNAL-IP יופיע <pending> בזמן שמאזן העומסים נוצר. הפעולה עשויה להימשך כמה דקות. אם מופיעות שגיאות כמו Does not have minimum availability, צריך לחכות כמה דקות. השגיאה הזמנית הזו מתרחשת כי GKE יוצר מחדש את הצמתים כדי לבצע את השינויים.

מעתיקים את כתובת ה-IP ופותחים את הדף בדפדפן:

אפליקציית אינטרנט שפועלת ב-GKE

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

הגדלת קנה המידה של הקצה הקדמי של האתר

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

  1. הגדלת מספר ה-Pods של frontend:

    kubectl scale deployment frontend --replicas=5
    

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

    deployment.extensions/frontend scaled
    
  2. בודקים את מספר הרפליקות שפועלות:

    kubectl get pods
    

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

    NAME                             READY     STATUS    RESTARTS   AGE
    frontend-88237173-3s3sc          1/1       Running   0          1s
    frontend-88237173-twgvn          1/1       Running   0          1s
    frontend-88237173-5p257          1/1       Running   0          23m
    frontend-88237173-84036          1/1       Running   0          23m
    frontend-88237173-j3rvr          1/1       Running   0          23m
    redis-leader-343230949-qfvrq     1/1       Running   0          54m
    redis-follower-132015689-dp23k   1/1       Running   0          37m
    redis-follower-132015689-xq9v0   1/1       Running   0          37m
    

    כדי להקטין את מספר ה-Pods של frontend, משתמשים באותה פקודה ומחליפים את 5 ב-1.

הסרת המשאבים

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

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

    כדי למחוק Google Cloud פרויקט:

    gcloud projects delete PROJECT_ID

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

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

  1. מחיקת השירות frontend:

    kubectl delete service frontend
    
  2. מחיקת אשכול GKE:

    gcloud container clusters delete guestbook
    

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