ทำให้ใช้งานได้และอัปเดตแอป .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 จึงจะทำ Lab นี้ให้เสร็จสมบูรณ์ได้ ดูวิธีการโดยละเอียดเพิ่มเติมเกี่ยวกับวิธีสร้างโปรเจ็กต์ใหม่ได้ที่ Codelab นี้

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

Cloud Shell

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

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

  • แสดงประเภทเครื่องด้วยคำสั่ง 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

เนื่องจาก Lab นี้จะทําให้แอป .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 run ด้านล่างจะสร้างคอนเทนเนอร์ใหม่ที่เปิดเผยพอร์ต 80 และแมปพอร์ตดังกล่าวกับพอร์ต localhost 8080 โปรดทราบว่า 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/?authuser=0

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

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

ภาพหน้าจอของแอป .NET V1

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

สุดท้าย ให้ดูที่พอด การติดตั้งใช้งานระบุว่าควรมีอินสแตนซ์ 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 คือตัวจัดสรรภาระงาน ระบบจะกำหนดปลายทางตามป้ายกำกับใน Pod ด้วยวิธีนี้ ทันทีที่มีการเพิ่ม Pod ใหม่ลงในการติดตั้งใช้งานผ่านkubectl scale deploymentการดำเนินการข้างต้น Pod ที่ได้จะพร้อมใช้งานทันทีสำหรับคำขอที่บริการนั้นจัดการ

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

$ 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 ของ Pod ที่พร้อมใช้งานสำหรับบริการนี้ในปัจจุบัน เปรียบเทียบค่าเหล่านี้กับ IP ของพ็อดที่แสดงผลด้านบน

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

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

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

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

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

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

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

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

โปรดสังเกตว่าทรัพยากรการติดตั้งใช้งานแสดงข้อมูลที่อัปเดตแล้ว และทรัพยากรบริการแสดงข้อมูลที่ไม่เปลี่ยนแปลง คุณจะเห็น Pod ที่อัปเดตแล้วได้เช่นเดิมด้วยคำสั่ง 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 เพื่อเข้าถึงเว็บแอปพลิเคชัน

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

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 Service Mesh สำหรับรูปแบบการกำหนดเส้นทางและความยืดหยุ่นที่ซับซ้อนยิ่งขึ้น

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

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

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