ทำให้ใช้งานได้และอัปเดตแอป .NET Core ใน Google Kubernetes Engine

1. ภาพรวม

Microsoft .NET Core เป็น .NET เวอร์ชันโอเพนซอร์สและข้ามแพลตฟอร์มที่ทำงานในคอนเทนเนอร์ได้โดยตรง .NET Core พร้อมใช้งานใน GitHub และได้รับการดูแลโดย Microsoft และชุมชน .NET ห้องปฏิบัติการนี้จะติดตั้งใช้งานแอป .NET Core ที่สร้างโดยใช้คอนเทนเนอร์ใน Google Kubernetes Engine (GKE)

ห้องทดลองนี้เป็นไปตามรูปแบบการพัฒนาทั่วไปที่แอปพลิเคชันได้รับการพัฒนาในสภาพแวดล้อมภายในของนักพัฒนาซอฟต์แวร์ แล้วจึงนำไปใช้งานจริง ในส่วนแรกของห้องทดลองนี้ ระบบจะตรวจสอบแอป .NET Core ตัวอย่างโดยใช้คอนเทนเนอร์ที่ทำงานใน Cloud Shell เมื่อตรวจสอบแล้ว ระบบจะติดตั้งใช้งานแอปใน Kubernetes โดยใช้ GKE ห้องทดลองนี้มีขั้นตอนในการสร้างคลัสเตอร์ GKE

ในส่วนที่ 2 ของห้องทดลอง จะมีการเปลี่ยนแปลงเล็กน้อยในแอปที่แสดงชื่อโฮสต์ของคอนเทนเนอร์ที่เรียกใช้อินสแตนซ์แอปนั้น จากนั้นระบบจะตรวจสอบแอปพลิเคชันที่อัปเดตใน Cloud Shell และอัปเดตการทำให้ใช้งานได้เพื่อใช้เวอร์ชันใหม่ ภาพประกอบต่อไปนี้แสดงลำดับกิจกรรมในห้องปฏิบัติการนี้

แผนภาพลำดับการสาธิต

ค่าใช้จ่าย

หากคุณทำตามขั้นตอนในห้องทดลองนี้ตามที่เขียนไว้ทุกประการ ระบบจะเรียกเก็บค่าบริการตามปกติสำหรับบริการต่อไปนี้

2. การตั้งค่าและข้อกำหนด

ข้อกำหนดเบื้องต้น

คุณต้องมีบัญชีและโปรเจ็กต์ Google Cloud จึงจะทำห้องทดลองนี้ให้เสร็จสมบูรณ์ได้ ดูวิธีการโดยละเอียดเพิ่มเติมเกี่ยวกับวิธีสร้างโปรเจ็กต์ใหม่ได้ที่ Codelab นี้

ห้องปฏิบัติการนี้ใช้ Docker ที่ทำงานใน Cloud Shell ซึ่งพร้อมใช้งานผ่านคอนโซล Google Cloud และได้รับการกำหนดค่าล่วงหน้าด้วยเครื่องมือที่มีประโยชน์มากมาย เช่น gcloud และ Docker วิธีเข้าถึง Cloud Shell จะแสดงอยู่ด้านล่าง คลิกไอคอน Cloud Shell ที่ด้านขวาบนเพื่อแสดงในแผงด้านล่างของหน้าต่างคอนโซล

Cloud Shell

ตัวเลือกการกำหนดค่าอื่นๆ สำหรับคลัสเตอร์ GKE (ไม่บังคับ)

ห้องปฏิบัติการนี้ต้องใช้คลัสเตอร์ Kubernetes ในส่วนถัดไป ระบบจะสร้างคลัสเตอร์ GKE ที่มีการกำหนดค่าแบบง่าย ส่วนนี้แสดงคำสั่ง gcloud บางคำสั่งที่มีตัวเลือกการกำหนดค่าอื่นๆ ให้ใช้เมื่อสร้างคลัสเตอร์ Kubernetes โดยใช้ GKE ตัวอย่างเช่น การใช้คำสั่งด้านล่างจะช่วยระบุประเภทเครื่อง โซน และแม้แต่ GPU (ตัวเร่ง) ที่แตกต่างกันได้

  • แสดงรายการประเภทเครื่องด้วยคำสั่ง gcloud compute machine-types list นี้
  • แสดงรายการ GPU ด้วยคำสั่งนี้ gcloud compute accelerator-types list
  • แสดงรายการโซนการประมวลผลด้วยคำสั่ง gcloud compute zones list นี้
  • รับความช่วยเหลือเกี่ยวกับคำสั่ง gcloud gcloud container clusters --help
    • ตัวอย่างเช่น วิดีโอนี้ให้รายละเอียดเกี่ยวกับการสร้างคลัสเตอร์ Kubernetes gcloud container clusters create --help

ดูรายการตัวเลือกการกำหนดค่าทั้งหมดสำหรับ GKE ได้ที่เอกสารนี้

เตรียมสร้างคลัสเตอร์ Kubernetes

ใน Cloud Shell คุณต้องตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างและกำหนดค่าไคลเอ็นต์ gcloud ซึ่งทำได้โดยใช้คำสั่งต่อไปนี้

export PROJECT_ID=YOUR_PROJECT_ID
export DEFAULT_ZONE=us-central1-c

gcloud config set project ${PROJECT_ID}
gcloud config set compute/zone ${DEFAULT_ZONE}

สร้างคลัสเตอร์ GKE

เนื่องจากห้องทดลองนี้ติดตั้งใช้งานแอป .NET Core ใน Kubernetes จึงจำเป็นต้องสร้างคลัสเตอร์ ใช้คำสั่งต่อไปนี้เพื่อสร้างคลัสเตอร์ Kubernetes ใหม่ใน Google Cloud โดยใช้ GKE

gcloud container clusters create dotnet-cluster \
  --zone ${DEFAULT_ZONE} \
  --num-nodes=1 \
  --node-locations=${DEFAULT_ZONE},us-central1-b \
  --enable-stackdriver-kubernetes \
  --machine-type=n1-standard-1 \
  --workload-pool=${PROJECT_ID}.svc.id.goog \
  --enable-ip-alias
  • --num-nodes คือจำนวนโหนดที่จะเพิ่มต่อโซน และสามารถปรับขนาดได้ในภายหลัง
  • --node-locations คือรายการโซนที่คั่นด้วยคอมมา ในกรณีนี้ ระบบจะใช้โซนที่คุณระบุในตัวแปรสภาพแวดล้อมด้านบนและ us-central1-b
    • หมายเหตุ: รายการนี้ต้องไม่มีรายการที่ซ้ำกัน
  • --workload-pool สร้าง Workload Identity เพื่อให้ภาระงาน GKE เข้าถึงบริการของ Google Cloud ได้

ขณะที่กำลังสร้างคลัสเตอร์ ระบบจะแสดงข้อความต่อไปนี้

Creating cluster dotnet-cluster in us-central1-b... Cluster is being deployed...⠼

กำหนดค่า kubectl

kubectl CLI เป็นวิธีหลักในการโต้ตอบกับคลัสเตอร์ Kubernetes หากต้องการใช้กับคลัสเตอร์ใหม่ที่เพิ่งสร้างขึ้น คุณต้องกำหนดค่าเพื่อตรวจสอบสิทธิ์กับคลัสเตอร์ ซึ่งทำได้โดยใช้คำสั่งต่อไปนี้

$ gcloud container clusters get-credentials dotnet-cluster --zone ${DEFAULT_ZONE}
Fetching cluster endpoint and auth data.
kubeconfig entry generated for dotnet-cluster.

ตอนนี้คุณควรใช้ kubectl เพื่อโต้ตอบกับคลัสเตอร์ได้แล้ว

$ kubectl get nodes
NAME                                            STATUS   ROLES    AGE     VERSION
gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   Ready    <none>   2m15s   v1.16.13-gke.401
gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   Ready    <none>   2m24s   v1.16.13-gke.401

3. ทดสอบในเครื่องและยืนยันฟังก์ชันการทำงานที่ต้องการ

ห้องทดลองนี้ใช้รูปภาพคอนเทนเนอร์ต่อไปนี้จากที่เก็บ .NET อย่างเป็นทางการใน Docker Hub

เรียกใช้คอนเทนเนอร์ในเครื่องเพื่อยืนยันฟังก์ชันการทำงาน

ใน Cloud Shell ให้ตรวจสอบว่า Docker ทำงานอย่างถูกต้องและคอนเทนเนอร์ .NET ทำงานตามที่คาดไว้โดยเรียกใช้คำสั่ง Docker ต่อไปนี้

$ docker run --rm mcr.microsoft.com/dotnet/samples

      Hello from .NET!
      __________________
                        \
                        \
                            ....
                            ....'
                            ....
                          ..........
                      .............'..'..
                  ................'..'.....
                .......'..........'..'..'....
                ........'..........'..'..'.....
              .'....'..'..........'..'.......'.
              .'..................'...   ......
              .  ......'.........         .....
              .                           ......
              ..    .            ..        ......
            ....       .                 .......
            ......  .......          ............
              ................  ......................
              ........................'................
            ......................'..'......    .......
          .........................'..'.....       .......
      ........    ..'.............'..'....      ..........
    ..'..'...      ...............'.......      ..........
    ...'......     ...... ..........  ......         .......
  ...........   .......              ........        ......
  .......        '...'.'.              '.'.'.'         ....
  .......       .....'..               ..'.....
    ..       ..........               ..'........
            ............               ..............
          .............               '..............
          ...........'..              .'.'............
        ...............              .'.'.............
        .............'..               ..'..'...........
        ...............                 .'..............
        .........                        ..............
          .....
  
Environment:
.NET 5.0.1-servicing.20575.16
Linux 5.4.58-07649-ge120df5deade #1 SMP PREEMPT Wed Aug 26 04:56:33 PDT 2020

ยืนยันฟังก์ชันการทำงานของเว็บแอป

นอกจากนี้ คุณยังตรวจสอบเว็บแอปพลิเคชันตัวอย่างใน Cloud Shell ได้ด้วย คำสั่งเรียกใช้ Docker ด้านล่างจะสร้างคอนเทนเนอร์ใหม่ที่แสดงพอร์ต 80 และแมปพอร์ตนั้นกับพอร์ต 8080 ของ localhost โปรดทราบว่า localhost ในกรณีนี้อยู่ใน Cloud Shell

$ docker run -it --rm -p 8080:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/samples:aspnetapp
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {64a3ed06-35f7-4d95-9554-8efd38f8b5d3} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

เนื่องจากนี่เป็นเว็บแอป จึงต้องดูและตรวจสอบในเว็บเบราว์เซอร์ ส่วนถัดไปจะแสดงวิธีดำเนินการดังกล่าวใน Cloud Shell โดยใช้การแสดงตัวอย่างบนเว็บ

4. เข้าถึงบริการจาก Cloud Shell โดยใช้ "ตัวอย่างบนเว็บ"

Cloud Shell มีตัวอย่างบนเว็บ ซึ่งเป็นฟีเจอร์ที่ช่วยให้ใช้เบราว์เซอร์เพื่อโต้ตอบกับกระบวนการที่ทำงานในอินสแตนซ์ Cloud Shell ได้

ใช้ "ตัวอย่างเว็บ" เพื่อดูแอปใน Cloud Shell

ใน Cloud Shell ให้คลิกปุ่มแสดงตัวอย่างบนเว็บ แล้วเลือก "แสดงตัวอย่างบนพอร์ต 8080" (หรือพอร์ตใดก็ตามที่ตั้งค่าให้แสดงตัวอย่างบนเว็บใช้)

Cloud Shell

ซึ่งจะเปิดหน้าต่างเบราว์เซอร์ที่มีที่อยู่ดังนี้

https://8080-cs-754738286554-default.us-central1.cloudshell.dev/

ดูแอปพลิเคชันตัวอย่าง .NET โดยใช้การแสดงตัวอย่างบนเว็บ

ตอนนี้คุณสามารถดูแอปตัวอย่างที่เริ่มต้นในขั้นตอนสุดท้ายได้โดยเริ่มการแสดงตัวอย่างบนเว็บและโหลด URL ที่ระบุ ซึ่งควรมีหน้าตาเช่นนี้

ภาพหน้าจอของแอป .NET เวอร์ชัน 1

5. ติดตั้งใช้งานใน Kubernetes

สร้างไฟล์ YAML และนำไปใช้

ขั้นตอนถัดไปต้องใช้ไฟล์ YAML ที่อธิบายทรัพยากร Kubernetes 2 รายการ ได้แก่ การติดตั้งใช้งานและบริการ สร้างไฟล์ชื่อ dotnet-app.yaml ใน Cloud Shell และเพิ่มเนื้อหาต่อไปนี้ลงในไฟล์

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-deployment
  labels:
    app: dotnetapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dotnetapp
  template:
    metadata:
      labels:
        app: dotnetapp
    spec:
      containers:
      - name: dotnet
        image: mcr.microsoft.com/dotnet/samples:aspnetapp
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: dotnet-service
spec:
    selector:
      app: dotnetapp
    ports:
      - protocol: TCP
        port: 8080
        targetPort: 80

ตอนนี้ให้ใช้ kubectl เพื่อใช้ไฟล์นี้กับ Kubernetes

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment created
service/dotnet-service created

สังเกตข้อความที่ระบุว่ามีการสร้างทรัพยากรที่ต้องการแล้ว

สำรวจแหล่งข้อมูลที่ได้

เราสามารถใช้ kubectl CLI เพื่อตรวจสอบทรัพยากรที่สร้างขึ้นด้านบนได้ ก่อนอื่น ให้ดูที่ทรัพยากรการติดตั้งใช้งานและยืนยันว่ามีการติดตั้งใช้งานใหม่แล้ว

$ kubectl get deployment
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
dotnet-deployment   3/3     3            3           80s

ต่อไปให้ดูที่ ReplicaSet ควรมี ReplicaSet ที่สร้างขึ้นโดยการติดตั้งใช้งานข้างต้น

$ kubectl get replicaset
NAME                           DESIRED   CURRENT   READY   AGE
dotnet-deployment-5c9d4cc4b9   3         3         3       111s

สุดท้าย ให้ดูที่ Pod การติดตั้งใช้งานระบุว่าควรมี 3 อินสแตนซ์ คำสั่งด้านล่างควรแสดงว่ามี 3 อินสแตนซ์ ระบบจะเพิ่มตัวเลือก -o wide เพื่อให้แสดงโหนดที่อินสแตนซ์เหล่านั้นทำงานอยู่

$ kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP          NODE                                            NOMINATED NODE   READINESS GATES
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running   0          2m25s   10.16.0.8   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running   0          2m25s   10.16.1.7   gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   <none>           <none>
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running   0          2m25s   10.16.0.7   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>

ตรวจสอบแหล่งข้อมูลของบริการ

ทรัพยากร Service ใน Kubernetes คือตัวจัดสรรภาระงาน ปลายทางจะกำหนดโดยป้ายกำกับในพ็อด ด้วยวิธีนี้ ทันทีที่มีการเพิ่มพ็อดใหม่ลงในการติดตั้งใช้งานผ่านการดำเนินการ kubectl scale deployment ข้างต้น พ็อดที่ได้จะพร้อมใช้งานทันทีสำหรับคำขอที่จัดการโดยบริการนั้น

คำสั่งต่อไปนี้ควรแสดงทรัพยากร Service

$ kubectl get svc
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
dotnet-service   ClusterIP   10.20.9.124   <none>        8080/TCP   2m50s
...

คุณดูรายละเอียดเพิ่มเติมเกี่ยวกับบริการได้โดยใช้คำสั่งต่อไปนี้

$ kubectl describe svc dotnet-service
Name:              dotnet-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=dotnetapp
Type:              ClusterIP
IP:                10.20.9.124
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.16.0.7:80,10.16.0.8:80,10.16.1.7:80
Session Affinity:  None
Events:            <none>

โปรดทราบว่าบริการเป็นประเภท ClusterIP ซึ่งหมายความว่าพ็อดใดก็ตามภายในคลัสเตอร์จะสามารถแปลงชื่อบริการ dotnet-service เป็นที่อยู่ IP ของบริการได้ คำขอที่ส่งไปยังบริการจะได้รับการจัดสรรภาระงานในอินสแตนซ์ (พ็อด) ทั้งหมด ค่า Endpoints ด้านบนแสดง IP ของพ็อดที่พร้อมใช้งานสำหรับบริการนี้ในปัจจุบัน เปรียบเทียบ IP เหล่านี้กับ IP ของพ็อดที่แสดงผลด้านบน

ยืนยันแอปที่ทำงานอยู่

ตอนนี้แอปพลิเคชันพร้อมใช้งานและพร้อมสำหรับคำขอของผู้ใช้แล้ว หากต้องการเข้าถึง ให้ใช้พร็อกซี คำสั่งต่อไปนี้จะสร้างพร็อกซีภายในที่ยอมรับคำขอในพอร์ต 8080 และส่งคำขอไปยังคลัสเตอร์ Kubernetes

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

ตอนนี้ให้ใช้ตัวอย่างเว็บใน Cloud Shell เพื่อเข้าถึงเว็บแอปพลิเคชัน

เพิ่ม /api/v1/namespaces/default/services/dotnet-service:8080/proxy/ ต่อท้าย URL ที่สร้างโดยตัวอย่างเว็บ ซึ่งจะมีลักษณะดังนี้

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

ยินดีด้วยที่ติดตั้งใช้งานแอป .NET Core ใน Google Kubernetes Engine ได้สำเร็จ ต่อไปเราจะทำการเปลี่ยนแปลงแอปและทำให้ใช้งานได้อีกครั้ง

6. แก้ไขแอป

ในส่วนนี้ ระบบจะแก้ไขแอปพลิเคชันเพื่อแสดงโฮสต์ที่อินสแตนซ์ทำงานอยู่ ซึ่งจะช่วยให้ยืนยันได้ว่าการจัดสรรภาระงานทำงานอยู่ และพ็อดที่พร้อมใช้งานตอบสนองตามที่คาดไว้

รับซอร์สโค้ด

git clone https://github.com/dotnet/dotnet-docker.git
cd dotnet-docker/samples/aspnetapp/

อัปเดตแอปให้มีชื่อโฮสต์

vi aspnetapp/Pages/Index.cshtml
    <tr>
        <td>Host</td>
        <td>@Environment.MachineName</td>
    </tr>

สร้างอิมเมจคอนเทนเนอร์ใหม่และทดสอบในเครื่อง

สร้างอิมเมจคอนเทนเนอร์ใหม่ด้วยโค้ดที่อัปเดต

docker build --pull -t aspnetapp:alpine -f Dockerfile.alpine-x64 .

ทดสอบแอปพลิเคชันใหม่ในเครื่องเหมือนก่อนหน้านี้

$ docker run --rm -it -p 8080:80 aspnetapp:alpine
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {f71feb13-8eae-4552-b4f2-654435fff7f8} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

คุณสามารถเข้าถึงแอปได้โดยใช้ Web Preview เช่นเดียวกับก่อนหน้านี้ ครั้งนี้พารามิเตอร์โฮสต์ควรปรากฏขึ้น ดังที่แสดงที่นี่

Cloud Shell

เปิดแท็บใหม่ใน Cloud Shell แล้วเรียกใช้ docker ps เพื่อดูว่ารหัสคอนเทนเนอร์ตรงกับค่าโฮสต์ที่แสดงด้านบนหรือไม่

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
ab85ce11aecd        aspnetapp:alpine    "./aspnetapp"       2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   relaxed_northcutt

ติดแท็กและพุชอิมเมจเพื่อให้ Kubernetes ใช้งานได้

รูปภาพต้องได้รับการติดแท็กและพุชเพื่อให้ Kubernetes ดึงข้อมูลได้ เริ่มต้นด้วยการแสดงรายการอิมเมจคอนเทนเนอร์และระบุอิมเมจที่ต้องการ

$ docker image list
REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
aspnetapp                                          alpine              95b4267bb6d0        6 days ago          110MB

จากนั้นติดแท็กรูปภาพนั้นและพุชไปยัง Google Container Registry เมื่อใช้รหัสรูปภาพด้านบน จะมีลักษณะดังนี้

docker tag 95b4267bb6d0 gcr.io/${PROJECT_ID}/aspnetapp:alpine
docker push gcr.io/${PROJECT_ID}/aspnetapp:alpine

7. ทำให้แอปพลิเคชันที่อัปเดตใช้งานได้อีกครั้ง

แก้ไขไฟล์ YAML

เปลี่ยนกลับไปยังไดเรกทอรีที่บันทึกไฟล์ dotnet-app.yaml ไว้ ค้นหาบรรทัดต่อไปนี้ในไฟล์ YAML

        image: mcr.microsoft.com/dotnet/core/samples:aspnetapp

ซึ่งจะต้องเปลี่ยนเพื่ออ้างอิงอิมเมจคอนเทนเนอร์ที่สร้างและพุชไปยัง gcr.io ด้านบน

        image: gcr.io/PROJECT_ID/aspnetapp:alpine

อย่าลืมแก้ไขเพื่อใช้ PROJECT_ID ของคุณ เมื่อเสร็จแล้วควรมีลักษณะดังนี้

        image: gcr.io/myproject/aspnetapp:alpine

ใช้ไฟล์ YAML ที่อัปเดตแล้ว

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment configured
service/dotnet-service unchanged

โปรดสังเกตว่าทรัพยากร Deployment แสดงสถานะ "อัปเดตแล้ว" และทรัพยากร Service แสดงสถานะ "ไม่มีการเปลี่ยนแปลง" คุณจะเห็นพ็อดที่อัปเดตแล้วเหมือนก่อนหน้านี้ด้วยคำสั่ง kubectl get pod แต่ครั้งนี้เราจะเพิ่ม -w ซึ่งจะคอยดูการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้น

$ kubectl get pod -w
NAME                                 READY   STATUS              RESTARTS   AGE
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running             0          34m
dotnet-deployment-85f6446977-tmbdq   0/1     ContainerCreating   0          4s
dotnet-deployment-85f6446977-tmbdq   1/1     Running             0          5s
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     ContainerCreating   0          0s
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   1/1     Running             0          6s
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          2s
dotnet-deployment-85f6446977-hw24v   0/1     ContainerCreating   0          2s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   1/1     Running             0          3s
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-httw6   0/1     Terminating         0          34m

เอาต์พุตด้านบนแสดงการอัปเดตทีละส่วนที่เกิดขึ้น โดยระบบจะเริ่มคอนเทนเนอร์ใหม่ก่อน และเมื่อคอนเทนเนอร์ใหม่ทำงานแล้ว คอนเทนเนอร์เก่าจะหยุดทำงาน

ยืนยันแอปที่ทำงานอยู่

เมื่อมาถึงจุดนี้ แอปพลิเคชันจะได้รับการอัปเดตและพร้อมสำหรับคำขอของผู้ใช้แล้ว คุณยังคงเข้าถึงได้โดยใช้พร็อกซีเหมือนเดิม

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

ตอนนี้ให้ใช้ตัวอย่างเว็บใน Cloud Shell เพื่อเข้าถึงเว็บแอปพลิเคชัน

เพิ่ม /api/v1/namespaces/default/services/dotnet-service:8080/proxy/ ต่อท้าย URL ที่สร้างโดยตัวอย่างเว็บ ซึ่งจะมีลักษณะดังนี้

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

ยืนยันว่าบริการ Kubernetes กำลังกระจายโหลด

รีเฟรช URL นี้หลายๆ ครั้งและสังเกตว่าโฮสต์เปลี่ยนไปเมื่อมีการจัดสรรภาระงานของคำขอในพ็อดต่างๆ โดยบริการ เปรียบเทียบค่าโฮสต์กับรายการพ็อดจากด้านบนเพื่อดูว่าพ็อดทั้งหมดได้รับการเข้าชม

เพิ่มขนาดอินสแตนซ์

การปรับขนาดแอปใน Kubernetes เป็นเรื่องง่าย คำสั่งต่อไปนี้จะปรับขนาดการทำให้ใช้งานได้เป็น 6 อินสแตนซ์ของแอปพลิเคชัน

$ kubectl scale deployment dotnet-deployment --replicas 6
deployment.apps/dotnet-deployment scaled

คุณดูพ็อดใหม่และสถานะปัจจุบันได้ด้วยคำสั่งนี้

kubectl get pod -w

โปรดทราบว่าการรีเฟรชหน้าต่างเบราว์เซอร์เดียวกันจะแสดงให้เห็นว่าตอนนี้การเข้าชมได้รับการปรับสมดุลในพ็อดใหม่ทั้งหมดแล้ว

8. ยินดีด้วย

ในห้องทดลองนี้ เว็บแอปพลิเคชันตัวอย่าง .NET Core ได้รับการตรวจสอบในสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ และติดตั้งใช้งานใน Kubernetes โดยใช้ GKE ในภายหลัง จากนั้นแอปได้รับการแก้ไขให้แสดงชื่อโฮสต์ของคอนเทนเนอร์ที่แอปทำงานอยู่ จากนั้นการทำให้ Kubernetes ใช้งานได้ได้รับการอัปเดตเป็นเวอร์ชันใหม่ และแอปได้รับการปรับขนาดเพื่อสาธิตวิธีกระจายโหลดไปยังอินสแตนซ์เพิ่มเติม

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับ .NET และ Kubernetes โปรดดูบทแนะนำเหล่านี้ ซึ่งจะต่อยอดจากสิ่งที่ได้เรียนรู้ในห้องทดลองนี้โดยการแนะนำ Istio โครงข่ายบริการ สำหรับรูปแบบการกำหนดเส้นทางและความยืดหยุ่นที่ซับซ้อนยิ่งขึ้น

9. ล้างข้อมูล

เพื่อหลีกเลี่ยงค่าใช้จ่ายที่ไม่ได้ตั้งใจ ให้ใช้คำสั่งต่อไปนี้เพื่อลบคลัสเตอร์และอิมเมจคอนเทนเนอร์ที่สร้างขึ้นในห้องทดลองนี้

gcloud container clusters delete dotnet-cluster --zone ${DEFAULT_ZONE}
gcloud container images delete gcr.io/${PROJECT_ID}/aspnetapp:alpine