פריסת אפליקציית Spring Boot Java ב-Kubernetes ב-Google Kubernetes Engine

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

Kubernetes הוא פרויקט קוד פתוח שיכול לפעול בסביבות שונות, ממחשבים ניידים ועד לאשכולות מרובי צמתים עם זמינות גבוהה, מעננים ציבוריים ועד לפריסות מקומיות, וממכונות וירטואליות (VM) ועד ל-Bare Metal.

ב-codelab הזה תפרסו אפליקציית אינטרנט פשוטה של Spring Boot Java ב-Kubernetes ב-GKE, במטרה להפעיל את אפליקציית האינטרנט כאפליקציה משוכפלת ב-Kubernetes. תקחו קוד שפיתחתם במחשב, תהפכו אותו לקובץ אימג' של קונטיינר של Docker ותפעילו את הקובץ אימג' ב-GKE.

תשתמשו ב-GKE, שירות Kubernetes מנוהל באופן מלא ב-Google Cloud, כדי שתוכלו להתמקד יותר בהתנסות ב-Kubernetes, במקום בהגדרת התשתית הבסיסית.

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

ב-Codelab הזה נשתמש בקוד לדוגמה מהמדריך בנושא פיתוח אפליקציה באמצעות Spring Boot.

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

  • היכרות עם שפת התכנות Java ועם כלים
  • ידע בכלי עריכת טקסט סטנדרטיים של Linux, כמו Vim,‏ Emacs ו-nano

מה תעשו

  • לארוז אפליקציית Java פשוטה כקונטיינר של Docker.
  • יוצרים את אשכול Kubernetes ב-GKE.
  • פריסת אפליקציית Java ב-Kubernetes ב-GKE.
  • להרחיב את השירות ולבצע שדרוג.
  • גישה ל-Dashboard, ממשק משתמש של Kubernetes מבוסס-אינטרנט.

מה תצטרכו

‫2. הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו אחרי שהוא מוגדר. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר לאורך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

הפעלת Cloud Shell

  1. ב-Cloud Console, לוחצים על Activate Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים עם תיאור של השירות. אם הוצג לכם מסך ביניים, לחצו על המשך.

9c92662c6a846a5c.png

הקצאת המשאבים והחיבור ל-Cloud Shell נמשכים רק כמה רגעים.

9f0e51b578fecce5.png

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

אחרי שמתחברים ל-Cloud Shell, אמור להופיע אימות ושהפרויקט מוגדר לפי מזהה הפרויקט.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שעברתם אימות:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם לא, אפשר להגדיר אותו באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

‫3. קבלת קוד מקור

אחרי ההפעלה של Cloud Shell, אפשר להשתמש בשורת הפקודה כדי לשכפל את קוד המקור לדוגמה בספריית הבית.

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. הפעלת האפליקציה באופן מקומי

  1. מוודאים ש-JAVA_HOME מוגדר לגרסה הנכונה:
$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
  1. אפשר להפעיל את אפליקציית Spring Boot כרגיל באמצעות הפלאגין Spring Boot.
$ ./mvnw -DskipTests spring-boot:run
  1. אחרי שהאפליקציה מופעלת, לוחצים על תצוגה מקדימה באינטרנט1a94d5bd10bfc072.pngבסרגל הכלים של Cloud Shell ובוחרים באפשרות תצוגה מקדימה ביציאה 8080.

6252b94905f3f7bd.png

תיפתח כרטיסייה בדפדפן ותתבצע התחברות לשרת שהפעלתם.

9b6c29059957bd0.jpeg

5. אריזת אפליקציית Java כקונטיינר Docker

השלב הבא הוא להכין את האפליקציה להרצה ב-Kubernetes. השלב הראשון הוא הגדרת מאגר התגים והתוכן שלו.

  1. יוצרים את קובץ ה-JAR שניתן לפריסה עבור האפליקציה.
$ ./mvnw -DskipTests package
  1. מפעילים את Artifact Registry API כדי לאחסן את קובץ האימג' של הקונטיינר שתיצרו.
$ gcloud services enable artifactregistry.googleapis.com
  1. יוצרים מאגר Docker חדש אם הוא לא קיים. כדי להעלות תמונות למאגר, צריך קודם ליצור מאגר.
$ gcloud artifacts repositories create codelabrepo     --repository-format=docker --location=us-central1 
  1. התמונה תהיה בפורמט:

{LOCATION}-docker.pkg.dev/{PROJECT-ID}/{REPOSITORY}/{IMAGE-NAME}

לדוגמה, אם יצרתם את המאגר במיקום us-central1 בשם codelabrepo, ואתם רוצים לתת לאימג' את השם hello-java:v1, האימג' יהיה:

us-central1-docker.pkg.dev/{PROJECT-ID}/codelabrepo/hello-java:v1

  1. משתמשים ב-Jib כדי ליצור את קובץ אימג' של קונטיינר ולהעביר אותו בדחיפה ל-Artifact Registry.
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format="value(core.project)"`

$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/codelabrepo/hello-java:v1
  1. אפשר לראות את קובץ האימג' של הקונטיינר ברשימה במסוף. כדי לעשות את זה, עוברים אל הדף Artifact Registry Images במסוף Cloud. עכשיו יש לכם קובץ אימג' של Docker שזמין בכל הפרויקט, ו-Kubernetes יכול לגשת אליו ולתזמן אותו, כפי שתראו בעוד כמה דקות.
  2. (אופציונלי) אחרי שההורדה והחילוץ יסתיימו (זה ייקח קצת זמן), בודקים את קובץ האימג' של הקונטיינר באמצעות הפקודה הבאה, שתריץ קונטיינר Docker כדמון (daemon) ביציאה 8080 מקובץ האימג' החדש של הקונטיינר. אם נתקלים בבעיות שקשורות להרשאות, מריצים קודם את הפקודה gcloud auth configure-docker us-central1-docker.pkg.dev:
$ docker run -ti --rm -p 8080:8080 \
  us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. שוב, כדאי להשתמש בתכונת התצוגה המקדימה באינטרנט של Cloud Shell.

6252b94905f3f7bd.png

  1. הדף שמוגדר כברירת מחדל אמור להיפתח בכרטיסייה חדשה. אחרי שמוודאים שהאפליקציה פועלת באופן מקומי בקונטיינר Docker, אפשר להפסיק את הקונטיינר הפועל על ידי לחיצה על Control+C.

6. יצירת האשכול

הכול מוכן ליצירת אשכול GKE. אשכול מורכב משרת Kubernetes API שמנוהל על ידי Google ומקבוצה של צמתי עובדים. צמתי העובדים הם מכונות וירטואליות ב-Compute Engine.

  1. קודם כול, מוודאים שתכונות ה-API שקשורות מופעלות.
$ gcloud services enable compute.googleapis.com container.googleapis.com
  1. יוצרים אשכול עם שני צמתים של n1-standard-1 (התהליך יימשך כמה דקות).
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

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

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

עכשיו אמור להיות לכם אשכול Kubernetes שמופעל על ידי GKE ופועל באופן מלא.

758c7fca14f70623.png

עכשיו הגיע הזמן לפרוס את האפליקציה בקונטיינר באשכול Kubernetes. מעכשיו, תשתמשו בשורת הפקודה kubectl (שכבר מוגדרת בסביבת Cloud Shell). בשאר חלקי ה-codelab נדרשת גרסת לקוח ושרת של Kubernetes בגרסה 1.2 ומעלה. ‫kubectl version יציג את הגרסה הנוכחית של הפקודה.

7. פריסת האפליקציה ב-Kubernetes

  1. פריסת Kubernetes יכולה ליצור, לנהל ולשנות את גודלן של כמה מכונות של האפליקציה באמצעות קובץ האימג' של הקונטיינר שיצרתם. פורסים מופע אחד של האפליקציה ב-Kubernetes באמצעות הפקודה kubectl run.
$ kubectl create deployment hello-java --image=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. כדי לראות את הפריסה שיצרתם, פשוט מריצים את הפקודה הבאה:
$ kubectl get deployments

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. כדי לראות את מופעי האפליקציה שנוצרו על ידי הפריסה, מריצים את הפקודה הבאה:
$ kubectl get pods

NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

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

8. התרת תנועה חיצונית

כברירת מחדל, אפשר לגשת ל-Pod רק באמצעות כתובת ה-IP הפנימית שלו בתוך האשכול. כדי לאפשר גישה למאגר hello-java מחוץ לרשת הווירטואלית של Kubernetes, צריך לחשוף את ה-Pod כשירות Kubernetes.

  1. ב-Cloud Shell, אפשר לחשוף את ה-Pod לאינטרנט הציבורי על ידי יצירת שירות Kubernetes LoadBalancer.
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

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

ה-Kubernetes Master יוצר את מאזן העומסים ואת כללי ההעברה, מאגרי היעדים וכללי חומת האש שקשורים ל-Compute Engine, כדי שהשירות יהיה נגיש באופן מלא מחוץ ל-Google Cloud.

  1. כדי למצוא את כתובת ה-IP של השירות שאפשר לגשת אליה באופן ציבורי, פשוט שולחים בקשה kubectl כדי להציג את כל שירותי האשכול.
$ kubectl get services

NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. עכשיו אמורה להיות לך אפשרות לגשת לשירות על ידי הפניית הדפדפן אל http://<EXTERNAL_IP>:8080.

9. הרחבת השירות

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

$ kubectl scale deployment hello-java --replicas=3

deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

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

10. השקת שדרוג לשירות

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

  1. פותחים את עורך הקוד על ידי לחיצה על Open editor 2109d75686c889a.pngבתפריט Cloud Shell.
  2. עוברים אל src/main/java/com/example/springboot/HelloController.java ומעדכנים את ערך התשובה.
package com.example.springboot;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Google Kubernetes Engine!";
    }
}
  1. משתמשים ב-Jib כדי ליצור גרסה חדשה של קובץ אימג' של קונטיינר ולהעביר אותה בדחיפה. תהליך הבנייה וההעלאה של התמונה המעודכנת אמור להיות מהיר יותר, כי אתם מנצלים את היתרונות של שמירה במטמון.
$ ./mvnw -DskipTests package com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

הכל מוכן! עכשיו אפשר להשתמש ב-Kubernetes כדי לעדכן בצורה חלקה את בקר השכפול לגרסה החדשה של האפליקציה.

  1. כדי לשנות את תווית התמונה של הקונטיינר הפועל, צריך לערוך את הפריסה הקיימת hello-java ולשנות את התמונה מ-us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v1

אל us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v2

  1. אפשר להשתמש בפקודה kubectl set image כדי לבקש מ-Kubernetes לפרוס את הגרסה החדשה של האפליקציה בכל האשכול, מופע אחד בכל פעם, באמצעות עדכונים מדורגים.
$ kubectl set image deployment/hello-java hello-java=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

deployment "hello-java" image updated
  1. בודקים שוב את http://EXTERNAL_IP:8080 כדי לוודא שהתשובה החדשה מוחזרת.

11. הוחזר למצב קודם

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

$ kubectl rollout undo deployment/hello-java

אם תסמנו שוב את התיבה http://EXTERNAL_IP:8080, תראו את התשובה הקודמת.

12. מזל טוב

למדתם איך ליצור ולפרוס אפליקציית אינטרנט חדשה מבוססת-Java ב-Kubernetes ב-GKE.

פינוי נפח

$ gcloud container clusters delete hello-java-cluster --zone us-central1-c

$ gcloud container images delete us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1 us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

מידע נוסף