חשיפת אפליקציות באמצעות שירותים

בדף הזה מוסבר איך ליצור שירותי Kubernetes ב-Google Kubernetes Engine ‏ (GKE) כדי לחשוף את האפליקציות שלכם, וכך לאפשר גישה אליהן מהרשת הפנימית או מהאינטרנט. הוא כולל חמישה סוגי שירותים: ClusterIP,‏ NodePort,‏ LoadBalancer,‏ ExternalName ו-Headless.

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

הדף הזה מיועד לאנשי תפעול ולמפתחים שמקצים ומגדירים משאבי ענן ופורסים אפליקציות ושירותים. מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שמוזכרים בתוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE. Cloud de Confiance by S3NS

לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את השימוש ב-kubectl.

מבוא

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

יש חמישה סוגים של שירותים:

  • ClusterIP (ברירת מחדל)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

אשכולות במצב Autopilot הם ציבוריים כברירת מחדל. אם בוחרים באשכול Autopilot פרטי, צריך להגדיר Cloud NAT כדי ליצור חיבורים יוצאים לאינטרנט, למשל כדי לשלוף תמונות מ-DockerHub.

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

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

לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:

  • מפעילים את ממשק Google Kubernetes Engine API.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • מוודאים שיש לכם אשכול קיים במצב Autopilot או במצב Standard. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.

יצירת שירות מסוג ClusterIP

בקטע הזה, יוצרים שירות מהסוג ClusterIP.

kubectl apply

הנה מניפסט של פריסה:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

מעתיקים את קובץ המניפסט לקובץ בשם my-deployment.yaml, ויוצרים את ה-Deployment:

kubectl apply -f my-deployment.yaml

מוודאים ששלושה פודים פועלים:

kubectl get pods

בפלט מוצגים שלושה Pods שפועלים:

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          7s
my-deployment-dbd86c8c4-qfw22   1/1     Running   0          7s
my-deployment-dbd86c8c4-wt4s6   1/1     Running   0          7s

זוהי מניפסט של שירות מסוג ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  # Uncomment the below line to create a Headless Service
  # clusterIP: None
  selector:
    app: metrics
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

לשירות יש בורר שמציין שתי תוויות:

  • app: metrics
  • department: sales

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

מעתיקים את המניפסט לקובץ בשם my-cip-service.yaml ויוצרים את השירות:

kubectl apply -f my-cip-service.yaml

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

kubectl get service my-cip-service --output yaml

בפלט מוצג ערך של clusterIP:

spec:
  clusterIP: 10.59.241.241

רשמו לכם את הערך clusterIP כדי שתוכלו להשתמש בו בהמשך.

המסוף

יצירת פריסה

  1. נכנסים לדף Workloads במסוף Cloud de Confiance .

    כניסה לדף Workloads

  2. לוחצים על פריסה.

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

  4. בשדה נתיב התמונה, מזינים us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0

  5. לוחצים על Done (סיום) ואז על Continue (המשך).

  6. בקטע הגדרה, בשדה שם האפליקציה, מזינים my-deployment.

  7. בקטע תוויות, יוצרים את התוויות הבאות:

    • מפתח: app וערך: metrics
    • מפתח: department וערך: sales
  8. בקטע Cluster, בוחרים את האשכול שבו רוצים ליצור את הפריסה.

  9. לוחצים על פריסה.

  10. כשהפריסה מוכנה, נפתח הדף פרטי הפריסה. בקטע Managed pods (תאי Pod מנוהלים), אפשר לראות שלפריסת האפליקציה יש תא Pod אחד או יותר שפועלים.

יצירת שירות לחשיפת הפריסה

  1. בדף פרטי הפריסה, לוחצים על פעולות > חשיפה.
  2. בתיבת הדו-שיח Expose (חשיפה), בקטע Port mapping (מיפוי יציאות), מגדירים את הערכים הבאים:

    • יציאה: 80
    • יציאת היעד: 8080
    • פרוטוקול: TCP
  3. ברשימה הנפתחת סוג השירות בוחרים באפשרות Cluster IP.

  4. לוחצים על Expose.

  5. כשהשירות מוכן, נפתח הדף פרטי השירות, ובו אפשר לראות את הפרטים של השירות. בקטע Cluster IP, רושמים את כתובת ה-IP ש-Kubernetes הקצה לשירות. זו כתובת ה-IP שבה לקוחות פנימיים יכולים להשתמש כדי להתקשר לשירות.

גישה לשירות

מציגים את הפודים הפועלים:

kubectl get pods

בפלט, מעתיקים את אחד משמות ה-Pod שמתחיל ב-my-deployment.

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          2m51s

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

kubectl exec -it POD_NAME -- sh

מחליפים את POD_NAME בשם של אחד מ-Pods ב-my-deployment.

במעטפת, מתקינים את curl:

apk add --no-cache curl

בקונטיינר, שולחים בקשה לשירות באמצעות כתובת ה-IP של האשכול ויציאה 80. שימו לב שהערך 80 הוא הערך של השדה port של Service. זהו הפורט שבו משתמשים כלקוח של השירות.

curl CLUSTER_IP:80

מחליפים את CLUSTER_IP בערך של clusterIP בשירות.

הבקשה מועברת לאחד מה-Pods החברים ביציאת TCP‏ 8080, שהוא הערך של השדה targetPort. חשוב לציין שבכל אחד מהפודים החברים בשירות צריך להיות קונטיינר שמקשיב ליציאה 8080.

התגובה מציגה את הפלט של hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf

כדי לצאת מהמעטפת לקונטיינר, מזינים exit.

יצירת שירות מסוג NodePort

בקטע הזה, יוצרים שירות מהסוג NodePort.

kubectl apply

הנה מניפסט של פריסה:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

שימו לב לאובייקט env במניפסט. האובייקט env מציין שלמשתנה הסביבה PORT של הקונטיינר הפועל יהיה ערך של 50000. האפליקציה hello-app מאזינה ליציאה שצוינה על ידי משתנה הסביבה PORT. לכן בתרגיל הזה, אתם אומרים לקונטיינר להאזין ליציאה 50000.

מעתיקים את קובץ המניפסט לקובץ בשם my-deployment-50000.yaml, ויוצרים את ה-Deployment:

kubectl apply -f my-deployment-50000.yaml

מוודאים ששלושה פודים פועלים:

kubectl get pods

זוהי דוגמה למניפסט של שירות מסוג NodePort:

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

מעתיקים את המניפסט לקובץ בשם my-np-service.yaml ויוצרים את השירות:

kubectl apply -f my-np-service.yaml

צפייה בשירות:

kubectl get service my-np-service --output yaml

הפלט יציג ערך nodePort:

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

יוצרים כלל חומת אש שמאפשר תעבורת TCP ביציאת הצומת:

gcloud compute firewall-rules create test-node-port \
    --allow tcp:NODE_PORT

מחליפים את NODE_PORT בערך של השדה nodePort בשירות.

המסוף

יצירת פריסה

  1. נכנסים לדף Workloads במסוף Cloud de Confiance .

    כניסה לדף Workloads

  2. לוחצים על פריסה.

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

  4. בשדה Image path (נתיב התמונה), מזינים us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. לוחצים על הוספת משתנה סביבה.

  6. בשדה מפתח, מזינים PORT, ובשדה ערך, מזינים 50000.

  7. לוחצים על Done (סיום) ואז על Continue (המשך).

  8. בקטע הגדרה, בשדה שם האפליקציה, מזינים my-deployment-50000.

  9. בקטע תוויות, יוצרים את התוויות הבאות:

    • מפתח: app וערך: metrics
    • מפתח: department וערך: engineering
  10. בקטע Cluster, בוחרים את האשכול שבו רוצים ליצור את הפריסה.

  11. לוחצים על פריסה.

  12. כשהפריסה מוכנה, נפתח הדף פרטי הפריסה. בקטע Managed pods (תאי Pod מנוהלים), אפשר לראות שלפריסת האפליקציה יש תא Pod אחד או יותר שפועלים.

יצירת שירות לחשיפת הפריסה

  1. בדף פרטי הפריסה, לוחצים על פעולות > חשיפה.
  2. בתיבת הדו-שיח Expose (חשיפה), בקטע Port mapping (מיפוי יציאות), מגדירים את הערכים הבאים:

    • יציאה: 80
    • יציאת היעד: 50000
    • פרוטוקול: TCP
  3. ברשימה הנפתחת סוג השירות, בוחרים באפשרות יציאת צומת.

  4. לוחצים על Expose.

  5. כשהשירות מוכן, נפתח הדף פרטי השירות, ובו אפשר לראות את הפרטים של השירות. בקטע Ports, רושמים את Node Port ש-Kubernetes הקצה לשירות.

יצירת כלל לחומת האש עבור יציאת הצומת

  1. נכנסים לדף Firewall policies במסוף Cloud de Confiance .

    לדף Firewall policies

  2. לוחצים על יצירת כלל לחומת האש.

  3. בשדה Name (שם), מזינים test-node-port.

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

  5. בשדה Source IPv4 ranges (טווחים של כתובות IPv4 של המקור), מזינים 0.0.0.0/0.

  6. בקטע Protocols and ports (פרוטוקולים ויציאות), בוחרים באפשרות Specified protocols and ports (פרוטוקולים ויציאות שצוינו).

  7. מסמנים את התיבה tcp ומזינים את ערך יציאת הצומת שרשמתם.

  8. לוחצים על יצירה.

קבלת כתובת IP של צומת

מציאת כתובת ה-IP החיצונית של אחד מהצמתים:

kubectl get nodes --output wide

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

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

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

גישה לשירות

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

NODE_IP_ADDRESS:NODE_PORT

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

  • NODE_IP_ADDRESS: כתובת ה-IP החיצונית של אחד מהצמתים שלכם, שמופיעה כשיוצרים את השירות במשימה הקודמת.
  • NODE_PORT: ערך יציאת הצומת.

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

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f

יצירת שירות מסוג LoadBalancer

בקטע הזה, יוצרים שירות מהסוג LoadBalancer.

kubectl apply

הנה מניפסט של פריסה:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

שימו לב שהקונטיינרים בפריסה הזו יאזינו ביציאה 50001.

מעתיקים את קובץ המניפסט לקובץ בשם my-deployment-50001.yaml, ויוצרים את ה-Deployment:

kubectl apply -f my-deployment-50001.yaml

מוודאים ששלושה פודים פועלים:

kubectl get pods

זוהי מניפסט של שירות מסוג LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

מעתיקים את המניפסט לקובץ בשם my-lb-service.yaml, ויוצרים את השירות:

kubectl apply -f my-lb-service.yaml

כשיוצרים שירות מסוג LoadBalancer, בקר Cloud de Confianceמופעל ומגדיר מאזן עומסי רשת חיצוני להעברת סיגנל ללא שינוי. מחכים דקה עד שהבקר מגדיר את מאזן עומסי הרשת החיצוני להעברת סיגנל ללא שינוי ויוצר כתובת IP יציבה.

צפייה בשירות:

kubectl get service my-lb-service --output yaml

בפלט מוצגת כתובת IP חיצונית יציבה בקטע loadBalancer:ingress:

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

המסוף

יצירת פריסה

  1. נכנסים לדף Workloads במסוף Cloud de Confiance .

    כניסה לדף Workloads

  2. לוחצים על פריסה.

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

  4. בשדה Image path (נתיב התמונה), מזינים us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. לוחצים על הוספת משתנה סביבה.

  6. בשדה מפתח, מזינים PORT, ובשדה ערך, מזינים 50001.

  7. לוחצים על Done (סיום) ואז על Continue (המשך).

  8. בקטע הגדרה, בשדה שם האפליקציה, מזינים my-deployment-50001.

  9. בקטע תוויות, יוצרים את התוויות הבאות:

    • מפתח: app וערך: products
    • מפתח: department וערך: sales
  10. בקטע Cluster, בוחרים את האשכול שבו רוצים ליצור את הפריסה.

  11. לוחצים על פריסה.

  12. כשהפריסה מוכנה, נפתח הדף פרטי הפריסה. בקטע Managed pods (תאי Pod מנוהלים), אפשר לראות שלפריסת האפליקציה יש תא Pod אחד או יותר שפועלים.

יצירת שירות לחשיפת הפריסה

  1. בדף פרטי הפריסה, לוחצים על פעולות > חשיפה.
  2. בתיבת הדו-שיח Expose (חשיפה), בקטע Port mapping (מיפוי יציאות), מגדירים את הערכים הבאים:

    • יציאה: 60000
    • יציאת היעד: 50001
    • פרוטוקול: TCP
  3. ברשימה הנפתחת סוג השירות, בוחרים באפשרות מאזן עומסים.

  4. לוחצים על Expose.

  5. כשהשירות מוכן, נפתח הדף פרטי השירות, ובו אפשר לראות את הפרטים של השירות. בקטע Load Balancer (מאזן עומסים), רושמים את כתובת ה-IP החיצונית של מאזן העומסים.

גישה לשירות

מחכים כמה דקות עד ש-GKE יגדיר את מאזן העומסים.

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

LOAD_BALANCER_ADDRESS:60000

מחליפים את LOAD_BALANCER_ADDRESS בכתובת ה-IP החיצונית של מאזן העומסים.

התגובה מציגה את הפלט של hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct

שימו לב שהערך של port בשירות הוא שרירותי. בדוגמה הקודמת השתמשנו בערך port של 60,000 כדי להמחיש את זה.

יצירת שירות מסוג ExternalName

בקטע הזה, יוצרים שירות מהסוג ExternalName.

שירות מסוג ExternalName מספק כינוי פנימי לשם DNS חיצוני. לקוחות פנימיים שולחים בקשות באמצעות שם ה-DNS הפנימי, והבקשות מופנות לשם החיצוני.

זוהי מניפסט של שירות מסוג ExternalName:

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

בדוגמה הקודמת, שם ה-DNS הוא my-xn-service.default.svc.cluster.local. כשלקוח פנימי שולח בקשה אל my-xn-service.default.svc.cluster.local, הבקשה מנותבת מחדש אל example.com.

שימוש ב-kubectl expose ליצירת שירות

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

כדי להציג את my-deployment, שמופיע מוקדם יותר בנושא הזה, אפשר להזין את הפקודה הבאה:

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

כדי לחשוף את my-deployment-50000, שמופיע בהמשך הנושא הזה, אפשר להזין את הפקודה הזו:

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

כדי לחשוף את my-deployment-50001, שמוצג בהמשך הנושא הזה, אפשר להזין את הפקודה הזו:

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

צפייה בשירותים

אפשר לראות את השירותים שיצרתם בדף Services במסוף Cloud de Confiance .

כניסה לדף Services

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

כדי לראות את השירותים ב-App Hub, נכנסים לדף App Hub במסוף Cloud de Confiance .

מעבר אל מרכז האפליקציות

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

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

במאמר הגדרת מרכז האפליקציות מוסבר איך להגדיר את מרכז האפליקציות בפרויקט.

סידור וארגון

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

kubectl apply

מחיקת השירותים

kubectl delete services my-cip-service my-np-service my-lb-service

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

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

מחיקת כלל חומת האש

gcloud compute firewall-rules delete test-node-port

המסוף

מחיקת השירותים

  1. נכנסים לדף Services במסוף Cloud de Confiance .

    כניסה לדף Services

  2. בוחרים את השירותים שיצרתם בתרגיל הזה ולוחצים על מחיקה.

  3. כשמופיעה בקשה לאישור, לוחצים על מחיקה.

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

  1. נכנסים לדף Workloads במסוף Cloud de Confiance .

    כניסה לדף Workloads

  2. בוחרים את הפריסות שיצרתם בתרגיל הזה ולוחצים על מחיקה.

  3. כשמוצגת בקשה לאישור, מסמנים את התיבה Delete Horizontal Pod Autoscalers associated with selected Deployments (מחיקת כלי Horizontal Pod Autoscalers שמשויכים לפריסות שנבחרו) ואז לוחצים על Delete (מחיקה).

מחיקת כלל חומת האש

  1. נכנסים לדף Firewall policies במסוף Cloud de Confiance .

    לדף Firewall policies

  2. מסמנים את תיבת הסימון test-node-port ולוחצים על מחיקה.

  3. כשמופיעה בקשה לאישור, לוחצים על מחיקה.

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