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

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

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

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

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

המסוף

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

    כניסה לאשכולות GKE

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

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

קונטיינרים

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

  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. מזינים את שתי התוויות הבאות:

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

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

חשיפה

  1. מסמנים את האפשרות Expose deployment as a new service.

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

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

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

  5. בקטע Service type, בוחרים באפשרות LoadBalancer.

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

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

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

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

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

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

העברה לשירות

נניח שלקוח מחוץ לאשכול שולח בקשה לכתובת ה-IP של מאזן העומסים ביציאת TCP‏ 80. הבקשה מנותבת למאזן העומסים של האשכול. מאזן העומסים מעביר את הבקשה לפוד חבר ביציאת 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 ויוצרים את הפריסה:

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

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

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

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

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

מציגים את הפודים בפריסה:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

בפלט אפשר לראות שבפריסה יש שלושה Pods פועלים:

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

הפלט מציג פרטים בפורמט נוח על ה-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

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

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

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

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

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

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

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

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

שומרים את המניפסט בקובץ בשם 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 שלקוחות מחוץ לאשכול יכולים להשתמש בה כדי לקרוא לשירות.

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

לקוח שולח בקשה ל-‎203.0.113.1 ביציאת TCP‏ 80. הבקשה מנותבת למאזן העומסים של האשכול. מאזן העומסים מעביר את הבקשה ל-Pod חבר ביציאת 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