1. Ringkasan
Microsoft .NET Core adalah versi .NET open source dan lintas platform yang dapat berjalan secara native dalam container. .NET Core tersedia di GitHub serta dikelola oleh Microsoft dan komunitas .NET. Lab ini men-deploy aplikasi .NET Core dalam container ke dalam Google Kubernetes Engine (GKE).
Lab ini mengikuti pola pengembangan umum, yaitu aplikasi dikembangkan di lingkungan lokal developer, lalu di-deploy ke produksi. Di bagian pertama lab, contoh aplikasi .NET core divalidasi menggunakan container yang berjalan di Cloud Shell. Setelah divalidasi, aplikasi kemudian di-deploy di Kubernetes menggunakan GKE. Lab ini mencakup langkah-langkah untuk membuat cluster GKE.
Di bagian kedua lab ini, dilakukan perubahan kecil pada aplikasi yang menunjukkan nama host container yang menjalankan instance aplikasi tersebut. Aplikasi yang telah diupdate kemudian divalidasi di Cloud Shell dan deployment akan diupdate untuk menggunakan versi baru ini. Ilustrasi berikut menunjukkan urutan aktivitas dalam lab ini:
Biaya
Jika Anda menjalankan lab ini persis seperti yang tertulis, biaya normal untuk layanan berikut akan berlaku
2. Penyiapan dan Persyaratan
Prasyarat
Untuk menyelesaikan lab ini, Anda memerlukan akun dan project Google Cloud. Untuk petunjuk yang lebih mendetail tentang cara membuat project baru, lihat Codelab ini.
Lab ini memanfaatkan Docker yang berjalan di Cloud Shell, yang tersedia melalui Konsol Google Cloud dan sudah dikonfigurasi sebelumnya dengan banyak alat berguna, seperti gcloud dan Docker. Cara mengakses Cloud Shell ditampilkan di bawah. Klik ikon Cloud Shell di kanan atas untuk menampilkannya di panel bawah jendela konsol.
Opsi konfigurasi alternatif untuk cluster GKE (opsional)
Lab ini memerlukan cluster Kubernetes. Di bagian berikutnya, cluster GKE dengan konfigurasi sederhana akan dibuat. Bagian ini menunjukkan beberapa perintah gcloud
yang memberikan opsi konfigurasi alternatif untuk digunakan saat membangun cluster Kubernetes menggunakan GKE. Misalnya, dengan menggunakan perintah di bawah ini, Anda dapat mengidentifikasi berbagai jenis mesin, zona, dan bahkan GPU (akselerator).
- Tampilkan daftar jenis mesin dengan perintah ini
gcloud compute machine-types list
- Tampilkan GPU dengan perintah ini
gcloud compute accelerator-types list
- Tampilkan daftar zona komputasi dengan perintah ini
gcloud compute zones list
- Mendapatkan bantuan terkait perintah gcloud
gcloud container clusters --help
- Misalnya, bagian ini memberikan detail tentang pembuatan cluster kubernetes
gcloud container clusters create --help
- Misalnya, bagian ini memberikan detail tentang pembuatan cluster kubernetes
Untuk mengetahui daftar lengkap opsi konfigurasi untuk GKE, lihat dokumen ini
Bersiap untuk membuat cluster kubernetes
Di Cloud Shell, Anda perlu menetapkan beberapa variabel lingkungan dan mengonfigurasi klien gcloud. Hal ini dapat dilakukan dengan perintah berikut.
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}
Membuat cluster GKE
Karena lab ini men-deploy aplikasi .NET Core di Kubernetes, Anda perlu membuat cluster. Gunakan perintah berikut untuk membuat cluster Kubernetes baru di Google Cloud menggunakan 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
adalah jumlah node yang akan ditambahkan per zona dan dapat diskalakan nanti--node-locations
adalah daftar zona yang dipisahkan koma. Dalam hal ini, zona yang Anda identifikasi dalam variabel lingkungan di atas danus-central1-b
digunakan- CATATAN: Daftar ini tidak boleh berisi duplikat
--workload-pool
menetapkan workload identity sehingga workload GKE dapat mengakses layanan Google Cloud
Saat cluster sedang membangun, hal berikut akan ditampilkan
Creating cluster dotnet-cluster in us-central1-b... Cluster is being deployed...⠼
Mengonfigurasi kubectl
CLI kubectl
adalah cara utama untuk berinteraksi dengan cluster Kubernetes. Agar dapat digunakan dengan cluster baru yang baru saja dibuat, cluster perlu dikonfigurasi untuk melakukan autentikasi terhadap cluster. Hal ini dilakukan dengan mengikuti perintah.
$ gcloud container clusters get-credentials dotnet-cluster --zone ${DEFAULT_ZONE}
Fetching cluster endpoint and auth data.
kubeconfig entry generated for dotnet-cluster.
Sekarang seharusnya kubectl
sudah dapat digunakan untuk berinteraksi dengan cluster.
$ 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. Menguji secara lokal dan mengonfirmasi fungsi yang diinginkan
Lab ini menggunakan image container berikut dari repositori .NET resmi di hub Docker.
Jalankan container secara lokal untuk memverifikasi fungsi
Di Cloud Shell, pastikan Docker sudah aktif dan berjalan dengan benar serta bahwa container .NET berfungsi seperti yang diharapkan dengan menjalankan perintah Docker berikut:
$ 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
Mengonfirmasi fungsi aplikasi web
Contoh aplikasi web di Cloud Shell juga dapat divalidasi. Perintah Docker run di bawah membuat container baru yang mengekspos port 80
dan memetakannya ke port localhost
8080
. Perlu diingat bahwa localhost
dalam kasus ini berada di 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
Karena ini adalah aplikasi web, aplikasi perlu dilihat dan divalidasi di browser web. Bagian berikutnya menunjukkan cara melakukannya di Cloud Shell menggunakan Web Preview.
4. Mengakses layanan dari Cloud Shell menggunakan "Web Preview"
Cloud Shell menawarkan Pratinjau Web, yaitu fitur yang dapat digunakan browser untuk berinteraksi dengan proses yang berjalan di instance Cloud Shell.
Menggunakan "Pratinjau Web" untuk melihat aplikasi di Cloud Shell
Di Cloud Shell, klik tombol pratinjau web, lalu pilih "Preview on port 8080" (atau port apa pun yang ingin digunakan untuk Pratinjau Web port).
Langkah itu akan membuka jendela browser dengan alamat seperti ini:
https://8080-cs-754738286554-default.us-central1.cloudshell.dev/?authuser=0
Melihat aplikasi contoh .NET menggunakan Pratinjau Web
Aplikasi contoh yang dimulai pada langkah terakhir kini dapat dilihat dengan memulai Pratinjau Web dan memuat URL yang diberikan. Ini akan terlihat seperti berikut:
5. Men-deploy ke Kubernetes
Membuat file YAML dan menerapkan
Langkah selanjutnya memerlukan file YAML yang menjelaskan dua resource Kubernetes, yaitu Deployment dan Service. Buat file bernama dotnet-app.yaml
di Cloud Shell dan tambahkan konten berikut ke dalamnya.
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
Sekarang gunakan kubectl
untuk menerapkan file ini ke kubernetes.
$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment created
service/dotnet-service created
Perhatikan pesan yang menunjukkan bahwa resource yang diinginkan telah dibuat.
Menjelajahi resource yang dihasilkan
Kita dapat menggunakan CLI kubectl
untuk memeriksa resource yang dibuat di atas. Pertama-tama, mari kita lihat resource Deployment dan konfirmasi bahwa deployment baru telah tersedia.
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
dotnet-deployment 3/3 3 3 80s
Selanjutnya, lihat ReplicaSets. Harus ada ReplicaSet yang dibuat oleh deployment di atas.
$ kubectl get replicaset
NAME DESIRED CURRENT READY AGE
dotnet-deployment-5c9d4cc4b9 3 3 3 111s
Terakhir, lihat Pod. Deployment menunjukkan bahwa harus ada tiga instance. Perintah di bawah akan menunjukkan bahwa ada tiga instance. Opsi -o wide
ditambahkan sehingga node tempat instance tersebut berjalan akan ditampilkan.
$ 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>
Meninjau resource Layanan
Resource Service di Kubernetes adalah load balancer. Endpoint ditentukan berdasarkan label pada Pod. Dengan cara ini, segera setelah Pod baru ditambahkan ke deployment melalui operasi kubectl scale deployment
di atas, Pod yang dihasilkan akan langsung tersedia untuk permintaan yang ditangani oleh Service tersebut.
Perintah berikut akan menampilkan resource Service.
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dotnet-service ClusterIP 10.20.9.124 <none> 8080/TCP 2m50s
...
Anda dapat melihat detail selengkapnya tentang Service dengan perintah berikut.
$ 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>
Perhatikan bahwa Layanan berjenis ClusterIP
. Artinya, setiap Pod dalam cluster dapat me-resolve nama Service, dotnet-service
ke alamat IP-nya. Permintaan yang dikirim ke layanan akan di-load balanced di semua instance (Pod). Nilai Endpoints
di atas menunjukkan IP Pod yang saat ini tersedia untuk service ini. Bandingkan ini dengan IP Pod yang output-nya di atas.
Memverifikasi aplikasi yang sedang berjalan
Pada tahap ini, aplikasi sudah aktif dan siap menerima permintaan pengguna. Untuk mengaksesnya, gunakan proxy. Perintah berikut membuat proxy lokal yang menerima permintaan pada port 8080
dan meneruskannya ke cluster kubernetes.
$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080
Sekarang gunakan Pratinjau Web di Cloud Shell untuk mengakses aplikasi web.
Tambahkan kode berikut ke URL yang dibuat oleh Pratinjau Web: /api/v1/namespaces/default/services/dotnet-service:8080/proxy/
. Hasilnya akan terlihat seperti ini:
https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/
Selamat, Anda telah men-deploy aplikasi .NET Core di Google Kubernetes Engine. Berikutnya, kita akan melakukan perubahan pada aplikasi dan men-deploy ulang.
6. Memodifikasi aplikasi
Di bagian ini, aplikasi akan diubah untuk menunjukkan host tempat instance berjalan. Dengan begitu, Anda dapat mengonfirmasi bahwa load balancing berfungsi dan Pod yang tersedia merespons seperti yang diharapkan.
Mendapatkan kode sumber
git clone https://github.com/dotnet/dotnet-docker.git
cd dotnet-docker/samples/aspnetapp/
Update aplikasi untuk menyertakan nama host
vi aspnetapp/Pages/Index.cshtml
<tr>
<td>Host</td>
<td>@Environment.MachineName</td>
</tr>
Membuat image container baru dan melakukan pengujian secara lokal
Bangun image container baru dengan kode yang diperbarui.
docker build --pull -t aspnetapp:alpine -f Dockerfile.alpine-x64 .
Seperti sebelumnya, uji aplikasi baru secara lokal
$ 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
Seperti sebelumnya, aplikasi dapat diakses menggunakan Pratinjau Web. Kali ini parameter Host akan terlihat, seperti yang ditunjukkan di sini:
Buka tab baru di Cloud Shell dan jalankan docker ps
untuk melihat bahwa ID penampung cocok dengan nilai Host yang ditampilkan di atas.
$ 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
Memberi tag dan mengirim image agar tersedia untuk Kubernetes
Gambar harus diberi tag dan dikirim agar Kubernetes dapat menariknya. Mulai dengan mencantumkan image container dan menentukan image yang diinginkan.
$ docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
aspnetapp alpine 95b4267bb6d0 6 days ago 110MB
Selanjutnya, beri tag pada image tersebut dan kirim ke Google Container Registry. Menggunakan ID GAMBAR di atas, akan terlihat seperti ini
docker tag 95b4267bb6d0 gcr.io/${PROJECT_ID}/aspnetapp:alpine
docker push gcr.io/${PROJECT_ID}/aspnetapp:alpine
7. Men-deploy ulang aplikasi yang sudah diupdate
Mengedit file YAML
Ubah kembali ke direktori tempat file dotnet-app.yaml
disimpan. Cari baris berikut dalam {i>file<i} YAML
image: mcr.microsoft.com/dotnet/core/samples:aspnetapp
Hal ini perlu diubah untuk mereferensikan image container yang dibuat dan dikirimkan ke gcr.io di atas.
image: gcr.io/PROJECT_ID/aspnetapp:alpine
Jangan lupa untuk mengubahnya agar dapat menggunakan PROJECT_ID
. Hasilnya akan terlihat seperti ini setelah Anda selesai
image: gcr.io/myproject/aspnetapp:alpine
Menerapkan file YAML yang diperbarui
$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment configured
service/dotnet-service unchanged
Perhatikan bahwa resource Deployment menunjukkan bahwa resource yang diupdate dan resource Service tidak berubah. Pod yang diupdate dapat dilihat seperti sebelumnya dengan perintah kubectl get pod
, tetapi kali ini kita akan menambahkan -w
, yang akan memantau semua perubahan saat terjadi.
$ 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
Output di atas menunjukkan update berkelanjutan yang sedang terjadi. Pertama, container baru dimulai, dan saat container tersebut berjalan, container lama dihentikan.
Memverifikasi aplikasi yang sedang berjalan
Pada tahap ini, aplikasi akan diupdate dan siap menerima permintaan pengguna. Seperti sebelumnya, {i>page<i} dapat diakses menggunakan {i>proxy<i}.
$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080
Sekarang gunakan Pratinjau Web di Cloud Shell untuk mengakses aplikasi web.
Tambahkan kode berikut ke URL yang dibuat oleh Pratinjau Web: /api/v1/namespaces/default/services/dotnet-service:8080/proxy/
. Hasilnya akan terlihat seperti ini:
https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/
Memastikan Layanan Kubernetes mendistribusikan beban
Refresh URL ini beberapa kali dan perhatikan bahwa Host berubah saat permintaan diseimbangkan oleh beban di berbagai Pod berdasarkan Layanan. Bandingkan nilai Host dengan daftar Pod di atas untuk melihat apakah semua Pod menerima traffic.
Meningkatkan skala instance
Menskalakan aplikasi di Kubernetes itu mudah. Perintah ikuti akan menskalakan deployment hingga 6 instance aplikasi.
$ kubectl scale deployment dotnet-deployment --replicas 6
deployment.apps/dotnet-deployment scaled
Pod baru dan statusnya saat ini dapat dilihat dengan perintah ini
kubectl get pod -w
Perhatikan bahwa memuat ulang jendela browser yang sama akan menunjukkan bahwa traffic kini seimbang di semua Pod baru.
8. Selamat!
Di lab ini, aplikasi web contoh .NET Core divalidasi di lingkungan developer, lalu di-deploy ke Kubernetes menggunakan GKE. Aplikasi kemudian dimodifikasi untuk menampilkan nama host penampung tempatnya dijalankan. Deployment Kubernetes kemudian diupdate ke versi baru dan aplikasi ditingkatkan skalanya untuk menunjukkan cara beban didistribusikan di seluruh instance tambahan.
Untuk mempelajari .NET dan Kubernetes lebih lanjut, pertimbangkan tutorial ini. Hal ini dikembangkan berdasarkan hal yang telah dipelajari di lab ini dengan memperkenalkan Istio Service Mesh untuk pola ketahanan dan perutean yang lebih canggih.
9. Pembersihan
Untuk mengatasi biaya yang tidak diinginkan, gunakan perintah berikut untuk menghapus cluster dan image container yang dibuat di lab ini.
gcloud container clusters delete dotnet-cluster --zone ${DEFAULT_ZONE}
gcloud container images delete gcr.io/${PROJECT_ID}/aspnetapp:alpine