פריסת אפליקציה

במאמר הזה מובאת דוגמה לפריסת אפליקציה באשכול משתמשים שנוצר באמצעות Google Distributed Cloud (תוכנה בלבד) ל-VMware.

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

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

אתם יכולים להשתמש ב Google Cloud מסוף או בכלי שורת פקודה kubectl בתחנת העבודה של האדמין כדי לפרוס את האפליקציה.

המסוף

  1. במסוף, נכנסים לדף Google Kubernetes Engine clusters overview.

    מעבר לאשכולות GKE

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

    אם עדיין לא נכנסתם לאשכול המשתמשים, היכנסו אליו לפי ההוראות במאמר ניהול אשכולות ממסוף Google Cloud .

קונטיינרים

  1. בקטע קונטיינר חדש, בוחרים באפשרות קובץ אימג' קיים של קונטיינר.

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

  3. לוחצים על Continue.

Configuration

  1. בשדה Deployment name (שם הפריסה), מזינים my-deployment.

  2. בשדה Namespace (מרחב שמות), מזינים default.

  3. מזינים את שתי התוויות האלה:

    • Key 1: app, ‏ Value 1: metrics
    • Key 2: department, Value 2 sales
  4. בתפריט הנפתח Kubernetes cluster, בוחרים את האשכול.

  5. לוחצים על Continue.

Expose

  1. מסמנים את התיבה Expose deployment as a new service (חשיפת הפריסה כשירות חדש).

  2. בשדה Port 1 (יציאה 1), מזינים 80.

  3. בשדה יציאת יעד 1, מזינים 8080. זה הערך המתאים כי כברירת מחדל, מאגר hello-app מאזין ליציאת TCP‏ 8080. אפשר לראות את זה בקובץ ה-Dockerfile ובקוד המקור של האפליקציה.

  4. בשדה Protocol 1, בוחרים באפשרות TCP.

  5. בקטע סוג השירות, בוחרים באפשרות LoadBalancer.

בתחתית הדף, לוחצים על הלחצן פריסה.

הצגת פרטי הפריסה והשירות

  1. כשהפריסה מוכנה, הדף פרטי הפריסה נפתח בקטע עומסי עבודה של Kubernetes במסוף Google Cloud . בדף הזה אפשר לראות פרטים על הפריסה ושלושת ה-Pods שלה.

  2. בקטע Exposing services (חשיפת שירותים), לוחצים על שם השירות שחושף את הפריסה. בתרגיל הזה, השם הוא my-deployment-service.

  3. ייפתח הדף פרטי השירות. בדף הזה מוצגים פרטים על השירות. לדוגמה, אפשר לראות שכל Pod עם התוויות app: metrics ו-department: sales הוא חבר בשירות. תזכורת: ל-Pods ב-my-deployment יש את התוויות האלה.

אפשר לראות גם ערך של Load balancer IP (כתובת ה-IP של מאזן העומסים). כתובת ה-IP של מאזן העומסים הוגדרה אוטומטית במאזן העומסים של האשכול.

העברה אוטומטית בשירות

נניח שלקוח מחוץ לאשכול שולח בקשה לכתובת ה-IP של מאזן העומסים ביציאת TCP מספר 80. הבקשה מנותבת למאזן העומסים של האשכול. מאזן העומסים מעביר את הבקשה אל Pod חבר ביציאת TCP‏ 8080. כדאי לזכור שלכל Pod ב-my-deployment יש קונטיינר שמקשיב ביציאת TCP‏ 8080.

בדיקת השירות

עוברים למכונה שכתובת ה-IP של מאזן העומסים ניתנת לניתוב בה.

כדי להתקשר לשירות, מזינים את כתובת ה-IP של מאזן העומסים בדפדפן או משתמשים בפקודה כמו curl. לדוגמה:

curl [LOAD_BALANCER_IP]:80

בפלט תופיע ההודעה Hello, world!. לדוגמה:

curl 203.0.113.1:80
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

מחיקת הפריסה

נכנסים לדף Workloads בקטע Kubernetes Engine במסוף.

כניסה לדף Workloads

ברשימת הפריסות, בוחרים באפשרות my-deployment.

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

שורת הפקודה

חיבור לתחנת העבודה של האדמין

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

יצירת פריסה

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

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 --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml

USER_CLUSTER_KUBECONFIG הוא הנתיב של קובץ ה-kubeconfig עבור אשכול המשתמשים.

לקבל מידע בסיסי על הפריסה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

הפלט מראה שלפריסת ה-Deployment יש שלושה Pods שכולם זמינים:

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           27s

מציגים ברשימה את ה-Pods בפריסה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

הפלט מראה שלפריסת ה-Deployment יש שלושה פודים פעילים:

NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-54944c8d55-4srm2   1/1     Running   0          6s
my-deployment-54944c8d55-7z5nn   1/1     Running   0          6s
my-deployment-54944c8d55-j62n9   1/1     Running   0          6s

קבלת מידע מפורט על הפריסה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml

בפלט מוצגים פרטים על מפרט הפריסה והסטטוס:

kind: Deployment
metadata:
  ...
  generation: 1
  name: my-deployment
  namespace: default
  ...
spec:
  ...
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: metrics
      department: sales
  ...
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: hello
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  ‑ lastTransitionTime: "2019-11-11T18:44:02Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  ‑ lastTransitionTime: "2019-11-11T18:43:58Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: ReplicaSet "my-deployment-54944c8d55" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

תארו את הפריסה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment

הפלט מציג פרטים בפורמט נוח לקריאה על הפריסה, כולל ReplicaSet המשויך:

Name:                   my-deployment
Namespace:              default
CreationTimestamp:      Mon, 11 Nov 2019 10:43:58 -0800
Labels:                 
...
Selector:               app=metrics,department=sales
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=metrics
           department=sales
  Containers:
    hello:
    Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    Port:         
    Host Port:    
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   my-deployment-54944c8d55 (3/3 replicas created)

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

אחת הדרכים לחשוף את ה-Deployment ללקוחות מחוץ לאשכול היא ליצור שירות Kubernetes מסוג LoadBalancer.

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

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: sales
  type: LoadBalancer
  ports:
  ‑ port: 80
    targetPort: 8080

לצורך התרגיל הזה, אלה הדברים החשובים שצריך להבין לגבי השירות:

  • כל פוד שיש לו את התווית app: metrics ואת התווית department: sales הוא חבר בשירות. שימו לב: ל-Pods ב-my-deployment יש את התוויות האלה.

  • כשלקוח שולח בקשה לשירות ביציאת TCP‏ 80, הבקשה מועברת אל Pod של חבר ביציאת TCP‏ 8080.

  • לכל Pod של חבר חייב להיות מאגר שמקשיב ליציאת TCP‏ 8080.

כברירת מחדל, מאגר התגים hello-app מאזין ליציאת TCP מספר 8080. כדי לראות את זה, אפשר לעיין ב-Dockerfile ובקוד המקור של האפליקציה.

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml

USER_CLUSTER_KUBECONFIG הוא הנתיב של קובץ ה-kubeconfig עבור אשכול המשתמשים.

כשיוצרים את השירות, Google Distributed Cloud מגדיר באופן אוטומטי את כתובת loadBalancerIP במאזן העומסים של האשכול.

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml

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

kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: 10.96.1.39
  clusterIPs:
  - 10.96.1.39
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31184
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.1

בפלט הקודם אפשר לראות שלשירות יש clusterIP ו-loadBalancerIP. יש בו גם port וtargetPort.

המאפיין clusterIP לא רלוונטי לתרגיל הזה. ‫loadBalancerIP היא כתובת ה-IP שבה לקוחות מחוץ לאשכול יכולים להשתמש כדי להתקשר לשירות.

לדוגמה, נשתמש בערכים שמוצגים בפלט הקודם. כלומר, נניח שכתובת ה-IP של השירות היא loadBalancerIP = 203.0.113.1, מספר היציאה הוא port = 80, ומספר היציאה של ה-proxy הוא targetPort = 8080.

לקוח שולח בקשה לכתובת 203.0.113.1 ביציאת TCP מספר 80. הבקשה מנותבת למאזן העומסים של האשכול. מאזן העומסים מעביר את הבקשה לתא חבר ביציאת TCP‏ 8080.

מתקשרים לשירות:

curl LOAD_BALANCER_IP

הפלט יציג את ההודעה Hello, world!:

curl 203.0.113.1
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

מחיקת השירות

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service

כדי לוודא שהשירות נמחק:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services

הפלט לא יכלול יותר את my-service.

מחיקת הפריסה

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment

מוודאים שהפריסה נמחקה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments

הפלט לא יכלול יותר את my-deployment.

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

יצירת שירות ו-Ingress