Tutorial ini menunjukkan cara memecahkan masalah layanan penayangan Knative yang rusak menggunakan alat Stackdriver untuk penemuan dan alur kerja pengembangan lokal untuk penyelidikan.
Pendamping "studi kasus" langkah demi langkah untuk panduan pemecahan masalah ini menggunakan project contoh yang menghasilkan error runtime saat di-deploy, yang Anda pecahkan masalahnya untuk ditemukan dan diperbaiki masalahnya.
Tujuan
- Menulis, mem-build, dan men-deploy layanan ke penayangan Knative
- Menggunakan Cloud Logging untuk mengidentifikasi error
- Mengambil image container dari Container Registry untuk analisis akar masalah
- Perbaiki layanan "produksi", lalu tingkatkan kualitas layanan untuk mengurangi masalah di masa mendatang
Biaya
Dalam dokumen ini, Anda akan menggunakan komponen Google Cloud yang dapat ditagih berikut:
Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda,
gunakan kalkulator harga.
Sebelum memulai
- Tutorial ini mengasumsikan bahwa Anda telah menginstal dan mengonfigurasi layanan Knative di cluster.
- Pastikan lingkungan command line Anda sudah disiapkan dan alat tersebut sudah yang terbaru:
- Instal curl untuk mencoba layanan.
- Instal Docker secara lokal.
Susun kode
Bangun layanan penyambut baru yang ditayangkan Knative langkah demi langkah. Sebagai sebuah pengingat, layanan ini sengaja membuat error runtime untuk latihan pemecahan masalah.
Membuat sebuah project baru.
Node.js
Membuat sebuah project Node.js dengan menentukan paket layanan, dependensi awal, dan beberapa operasi umum.Buat direktori
hello-service
:mkdir hello-service cd hello-service
Buat file
package.json
:npm init --yes npm install --save express@4
Buka file
package.json
baru di editor Anda dan konfigurasikan skripstart
untuk menjalankannode index.js
Setelah selesai, filenya akan terlihat seperti ini:{ "name": "hello-service", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1" } }
Jika Anda terus mengembangkan layanan ini hingga lebih dari sekadar tutorial langsung, pertimbangkan untuk mengisi deskripsi, penulis, dan mengevaluasi lisensinya. Untuk mengetahui detail lengkapnya, baca dokumentasi package.json.
Python
Membuat direktori
hello-service
baru:mkdir hello-service cd hello-service
Membuat file requirements.txt dan salin dependensi Anda ke dalamnya:
Go
Buat direktori
hello-service
:mkdir hello-service cd hello-service
Membuat project Go dengan melakukan inisialisasi modul go baru:
go mod init <var>my-domain</var>.com/hello-service
Anda dapat memperbarui nama spesifiknya sesuai keinginan: Anda harus memperbarui nama tersebut jika kode dipublikasikan ke repositori kode yang dapat diakses melalui web.
Java
Membuat project maven:
mvn archetype:generate \ -DgroupId=com.example \ -DartifactId=hello-service \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false
Salin dependensi ke daftar dependensi
pom.xml
Anda (di antara elemen<dependencies>
):Salin setelan build ke dalam
pom.xml
Anda (di bawah elemen<dependencies>
):
Membuat layanan HTTP untuk menangani permintaan masuk:
Node.js
Python
Go
Java
Membuat
Dockerfile
untuk menentukan image container yang digunakan untuk men-deploy layanan:Node.js
Python
Go
Java
Contoh ini menggunakan Jib untuk mem-build image Docker menggunakan alat Java umum. Jib mengoptimalkan build container tanpa memerlukan Dockerfile atau menginstal Docker. Pelajari lebih lanjut cara mem-build container Java dengan Jib.
Mengirimkan kode
Kode pengiriman terdiri dari tiga langkah: mem-build image container dengan Cloud Build, mengupload image container ke Container Registry, dan men-deploy image container ke penayangan Knative.
Untuk kode pengiriman Anda:
Build container Anda dan publikasikan di Container Registry:
Node.js
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
Dengan PROJECT_ID sebagai project ID Google Cloud Anda. Anda dapat memeriksa project ID Anda saat ini dengan
gcloud config get-value project
.Setelah berhasil, Anda akan melihat pesan SUCCESS yang berisi ID, waktu pembuatan, dan nama image. Image tersebut disimpan di Container Registry dan dapat digunakan kembali bila diinginkan.
Python
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
Dengan PROJECT_ID sebagai project ID Google Cloud Anda. Anda dapat memeriksa project ID Anda saat ini dengan
gcloud config get-value project
.Setelah berhasil, Anda akan melihat pesan SUCCESS yang berisi ID, waktu pembuatan, dan nama image. Image tersebut disimpan di Container Registry dan dapat digunakan kembali bila diinginkan.
Go
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
Dengan PROJECT_ID sebagai project ID Google Cloud Anda. Anda dapat memeriksa project ID Anda saat ini dengan
gcloud config get-value project
.Setelah berhasil, Anda akan melihat pesan SUCCESS yang berisi ID, waktu pembuatan, dan nama image. Image tersebut disimpan di Container Registry dan dapat digunakan kembali bila diinginkan.
Java
mvn compile jib:build -Dimage=gcr.io/PROJECT_ID/hello-service
Dengan PROJECT_ID sebagai project ID Google Cloud Anda. Anda dapat memeriksa project ID Anda saat ini dengan
gcloud config get-value project
.Setelah berhasil, Anda akan melihat pesan BUILD SUCCESS. Image tersebut disimpan di Container Registry dan dapat digunakan kembali bila diinginkan.
Jalankan perintah berikut ini untuk menggunakan aplikasi anda:
gcloud run deploy hello-service --image gcr.io/PROJECT_ID/hello-service
Ganti PROJECT_ID dengan ID project Google Cloud Anda.
hello-service
adalah nama image container dan nama layanan penayangan Knative. Perhatikan bahwa image container di-deploy ke layanan dan cluster yang Anda konfigurasikan sebelumnya di bagian Menyiapkan gcloudTunggu hingga deployment selesai: proses ini memerlukan waktu sekitar setengah menit. Apabila berhasil, command line akan menampilkan URL layanan:
Melakukan Percobaan
Cobalah layanan untuk mengonfirmasi bahwa anda telah berhasil men-deploy-nya. Berbagai permintaan akan gagal apabila menggunakan HTTP 500 atau 503 error (anggota-anggota dari kelas 5xx Server errors). Tutorial ini berisi penjelasan mengenai pemecahan masalah pada tanggapan yang error.
Jika cluster Anda dikonfigurasi dengan domain default yang dapat dirutekan, lewati langkah-langkah di atas dan salin URL ke browser web Anda.
Jika tidak menggunakan sertifikat TLS otomatis dan pemetaan domain, Anda tidak akan diberikan URL yang dapat dijelajahi untuk layanan Anda.
Sebagai gantinya, gunakan URL yang disediakan dan alamat IP gateway masuk layanan untuk membuat perintah curl
yang dapat membuat permintaan ke layanan Anda:
-
Untuk mendapatkan IP eksternal untuk Load Balancer, jalankan perintah berikut:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
Ganti ASM-INGRESS-NAMESPACE dengan namespace tempat ingress Cloud Service Mesh Anda berada. Tentukan
istio-system
jika Anda menginstal Cloud Service Mesh menggunakan konfigurasi defaultnya.Output yang dihasilkan akan terlihat mirip dengan berikut ini:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
dengan nilai EXTERNAL-IP adalah alamat IP eksternal Load Balancer Anda.
Jalankan perintah
curl
menggunakan alamatGATEWAY_IP
ini di URL.curl -G -H "Host: SERVICE-DOMAIN" https://EXTERNAL-IP/
Ganti SERVICE-DOMAIN dengan domain default yang ditetapkan untuk layanan Anda. Anda bisa mendapatkannya dengan mengambil URL default dan menghapus protokol
http://
.Lihat pesan error HTTP 500 atau HTTP 503.
Menyelidiki masalah
Visualisasikan bahwa HTTP 5xx error yang ditemukan di atas dalam Trying it out ditemukan sebagai sebuah error runtime production. Tutorial ini berisi penjelasan mengenai proses formal untuk menangani itu. Meskipun proses resolusi error produksi sangat bervariasi, tutorial ini menyajikan langkah-langkah tertentu untuk menunjukkan pengaplikasian dari fitur-fitur dan teknik-teknik yang berguna.
Untuk menyelidiki masalah ini kamu akan menggunakan fase ini:
- Kumpulkan detail selengkapnya tentang error yang dilaporkan untuk mendukung penyelidikan lebih lanjut dan menetapkan strategi mitigasi.
- Kurangi dampak pengguna dengan memutuskan untuk meneruskan perbaikan atau rollback ke versi yang sehat.
- Reproduksi error untuk konfirmasi bahwa detail yang benar telah dikumpulkan dan error bukanlah glitch satu kali
- Lakukan analisis akar masalah pada bug untuk menemukan kode konfigurasi, atau proses yang membuat error ini
Pada saat memulai investigasi anda memiliki URL, stempel waktu, dan pesan. "Error Server Internal"
Mengumpulkan detail selengkapnya
Kumpulkan informasi selengkapnya tentang masalah untuk memahami yang terjadi dan menentukan langkah selanjutnya.
Gunakan alat yang tersedia untuk mengumpulkan detail selengkapnya:
Lihat log untuk mengetahui detail selengkapnya.
Gunakan Cloud Logging untuk meninjau urutan operasi yang menyebabkan masalah, termasuk pesan error.
Rollback ke versi stabil
Jika memiliki revisi yang Anda ketahui berfungsi, Anda dapat melakukan rollback layanan untuk menggunakan revisi tersebut. Misalnya,
Anda tidak akan dapat melakukan rollback pada layanan
hello-service
baru yang Anda deploy dalam
tutorial ini karena hanya berisi satu revisi.
Untuk menemukan revisi dan melakukan rollback layanan:
Mengulangi error
Gunakan detail anda dapat sebelumnya, konfirmasi masalah yang terjadi secara konsisten pada kondisi tes.
kirim permintaan HTTP yang sama dengan melakukan percobaan lagi, dan lihat jika detail dan error yang sama di laporkan. Itu mungkin membutuhkan beberapa waktu untuk detail error muncul.
Karena layanan sampel pada tutorial ini adalah hanya baca dan tidak dapat memicu berbagai efek samping yang rumit, reproduksi error pada produksi adalah aman. Namun, untuk layanan nyata kebanyakan, ini tidak akan menjadi kasus: anda mungkin butuh untuk mereproduksi error dalam lingkungan pengujian atau batas langkah ini pada penyelidikan lokal.
mereproduksi error akan membangun konteks untuk pekerjaan lebih lanjut. misalnya, jika developer tidak dapat mereproduksi error, penyelidikan selanjutnya mungkin diperlukan instrumentasi tambahan dari layanan.
Melakukan analisis akar masalah
Analisis akar masalah adalah langkah penting dalam pemecahan masalah yang efektif untuk memastikan bahwa anda menyelesaikan masalah, bukan menemukan gejala.
Sebelumnya dalam tutorial ini, Anda mereproduksi masalah pada penayangan Knative yang mengonfirmasi bahwa masalah aktif saat layanan dihosting pada penayangan Knative. Sekarang, reproduksi masalah secara lokal untuk menentukan apakah masalah tersebut terisolasi pada kode atau itu hanya muncul di hosting produksi.
Jika Anda belum menggunakan Docker CLI secara lokal dengan mengautentikasi Container Registry, itu dengan gcloud:
gcloud auth configure-docker
Untuk pendekatan alternatif lihat metode autentifikasi Container Registry.
Jika nama image container yang paling baru digunakan tidak tersedia, deskripsi layanan tersebut memiliki informasi mengenai image container yang di-deploy paling baru:
gcloud run services describe hello-service
Temukan nama image container di dalam objek
spec
. Perintah yang lebih ditargetkan dapat secara langsung mengambilnya:gcloud run services describe hello-service \ --format="value(spec.template.spec.containers.image)"
Perintah ini menampilkan nama image container seperti
gcr.io/PROJECT_ID/hello-service
.Tarik image container dari Container Registry ke lingkungan anda. langkah ini mungkin memerlukan waktu beberapa menit saat mendownload image container:
docker pull gcr.io/PROJECT_ID/hello-service
pembaruan selanjutnya pada image container yang menggunakan kembali nama ini dapat diambil dengan perintah yang sama. Jika anda melewati langkah ini, perintah
docker run
di bawah akan menarik image container jika tidak ada di komputer lokal.Jalankan secara lokal untuk mengonfirmasi bahwa masalahnya tidak hanya terjadi pada penayangan Knative:
PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ gcr.io/PROJECT_ID/hello-service
lihat rincian elemen dari perintah di atas,
- Variabel lingkungan
PORT
digunakan oleh layanan untuk menentukan port yang akan memproses di dalam container. - Perintah
run
memulai container, secara default ke perintah entrypoint yang ditentukan di Dockerfile atau image container induk. - Flag
--rm
menghapus instance penampung saat keluar. - Flag
-e
menetapkan nilai ke variabel lingkungan.-e PORT=$PORT
menerapkan variabelPORT
dari sistem lokal ke dalam container dengan nama variabel yang sama. - Flag
-p
memublikasikan container sebagai layanan yang tersedia di host lokal pada port 9000. Permintaan ke host lokal:9000 akan diarahkan kepada penampung pada port 8080. Artinya, output dari layanan tentang nomor port yang digunakan tidak akan cocok dengan cara layanan yang diakses. - Argumen terakhir
gcr.io/PROJECT_ID/hello-service
adalah jalur repositori yang mengarah ke versi terbaru image penampung. Jika tidak tersedia secara lokal, Docker akan mencoba mengambil image dari registry jarak jauh.
Pada browser anda, buka http://localhost:9000. Periksa output terminal untuk menemukan pesan error yang cocok dengan pesan di Google Cloud Observability.
Jika masalah tidak dapat direproduksi secara lokal, masalah mungkin hanya terjadi di lingkungan penayangan Knative. Tinjau panduan pemecahan masalah penayangan Knative untuk area tertentu yang perlu diselidiki.
Dalam hal ini, error akan direproduksi secara lokal.
- Variabel lingkungan
Setelah error dikonfirmasi dua kali sebagai persisten dan disebabkan oleh kode layanan bukan platform hosting, saatnya untuk menyelidiki kode tersebut lebih mendalam.
Untuk tujuan tutorial ini, anda dapat mengasumsikan bahwa kode di dalam penampung dan kode di sistem lokal adalah identik.
Node.js
Temukan sumber pesan error di dalam fileindex.js
di sekitar nomor baris
yang dipanggil dalam pelacakan tumpukan yang ditampilkan dalam log:
Python
Temukan sumber pesan error di dalam filemain.py
di sekitar nomor baris
yang dipanggil dalam pelacakan tumpukan yang ditampilkan dalam log:
Go
Temukan sumber pesan error di dalam file main.go
di sekitar nomor baris
yang dipanggil dalam pelacakan tumpukan yang ditampilkan dalam log:
Java
Temukan sumber dari pesan error dalam file App.java
di sekitar nomor baris
yang dipanggil dalam pelacakan tumpukan yang ditampilkan dalam log:
Memeriksa kode ini, tindakan berikut akan dilakukan saat variabel lingkungan NAME
tidak ditetapkan:
- Error dicatat ke dalam log Google Cloud Observability
- Respon error HTTP dikirim
Masalah ini disebabkan oleh tidak adanya variabel, tetapi akar masalahnya lebih spesifik: perubahan kode yang menambahkan dependensi keras pada variabel lingkungan tidak menyertakan perubahan terkait pada skrip deployment dan dokumentasi persyaratan runtime.
Memperbaiki akar masalah
Setelah mengumpulkan kode dan mengidentifikasi potensi penyebab utamanya, kita dapat mengambil langkah-langkah untuk memperbaikinya.
Periksa apakah layanan berfungsi secara lokal dengan lingkungan
NAME
yang tersedia di tempat:Jalankan container secara lokal dengan variabel lingkungan yang telah ditambahkan:
PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ -e NAME="Local World!" \ gcr.io/PROJECT_ID/hello-service
Buka http://localhost:9000 pada browser anda
Lihat "Hello Local World!" muncul pada halaman tersebut
Ubah lingkungan layanan penayangan Knative yang sedang berjalan untuk menyertakan variabel ini:
Jalankan perintah update layanan dengan parameter
--update-env-vars
untuk menambahkan variabel lingkungan:gcloud run services update hello-service \ --update-env-vars NAME=Override
Tunggu beberapa detik saat penayangan Knative membuat revisi baru berdasarkan revisi sebelumnya dengan menambahkan variabel lingkungan baru.
Pastikan layanan kini telah diperbaiki:
- Arahkan browser Anda ke URL layanan penayangan Knative.
- Lihat "Halo Penggantian!" akan muncul pada halaman tersebut.
- Pastikan tidak ada pesan atau error yang tidak terduga yang muncul di Cloud Logging.
Meningkatkan kecepatan pemecahan masalah di masa mendatang
Dalam contoh masalah produksi ini, error terkait dengan konfigurasi operasional. Ada perubahan kode yang akan meminimalkan dampak masalah ini di masa mendatang.
- Memperbaiki log error untuk menyertakan detail yang lebih spesifik.
- Daripada menampilkan error, buat layanan kembali ke default yang aman. Jika penggunaan default mewakili perubahan pada fungsi normal, gunakan pesan peringatan untuk tujuan pemantauan.
Mari kita lanjutkan dengan menghapus variabel lingkungan NAME
sebagai dependensi kuat.
Hapus kode penanganan
NAME
yang sudah ada:Node.js
Python
Go
Java
Tambahkan kode baru yang menetapkan nilai penggantian:
Node.js
Python
Go
Java
Uji secara lokal dengan mem-build ulang dan menjalankan container melalui kasus konfigurasi yang terpengaruh:
Node.js
docker build --tag gcr.io/PROJECT_ID/hello-service .
Python
docker build --tag gcr.io/PROJECT_ID/hello-service .
Go
docker build --tag gcr.io/PROJECT_ID/hello-service .
Java
mvn compile jib:build
Pastikan variabel lingkungan
NAME
masih berfungsi:PORT=8080 && docker run --rm -e $PORT -p 9000:$PORT \ -e NAME="Robust World" \ gcr.io/PROJECT_ID/hello-service
Pastikan layanan berfungsi tanpa variabel
NAME
:PORT=8080 && docker run --rm -e $PORT -p 9000:$PORT \ gcr.io/PROJECT_ID/hello-service
Jika layanan tidak menampilkan hasil, pastikan penghapusan kode pada langkah pertama tidak menghapus baris tambahan, seperti yang digunakan untuk menulis respons.
Deploy ini dengan membuka kembali bagian Men-deploy kode Anda.
Setiap deployment ke layanan membuat revisi baru dan otomatis mulai menyalurkan traffic jika sudah siap.
Untuk menghapus variabel lingkungan yang telah disetel sebelumnya:
gcloud run services update hello-service --clear-env-vars
Tambahkan fungsi baru untuk nilai default ke cakupan pengujian otomatis untuk layanan.
Menemukan masalah lain di log
Anda mungkin melihat masalah lain di Log Viewer untuk layanan ini. Misalnya, panggilan sistem yang tidak didukung akan muncul di log sebagai "Container Sandbox Limitation".
Misalnya, layanan Node.js terkadang menghasilkan pesan log ini:
Container Sandbox Limitation: Unsupported syscall statx(0xffffff9c,0x3e1ba8e86d88,0x0,0xfff,0x3e1ba8e86970,0x3e1ba8e86a90). Please, refer to https://gvisor.dev/c/linux/amd64/statx for more information.
Dalam hal ini, kurangnya dukungan tidak mempengaruhi layanan sampel hello-service.
Pembersihan
Anda dapat menghapus resource yang dibuat untuk tutorial ini agar tidak menimbulkan biaya.
Menghapus resource tutorial
Hapus layanan penayangan Knative yang Anda deploy dalam tutorial ini:
gcloud run services delete SERVICE-NAME
Dengan SERVICE-NAME adalah nama layanan pilihan Anda.
Anda juga dapat menghapus layanan penayangan Knative dari konsol Google Cloud:
Hapus konfigurasi default gcloud yang Anda tambahkan selama penyiapan tutorial:
gcloud config unset run/platform gcloud config unset run/cluster gcloud config unset run/cluster_location
Hapus konfigurasi project:
gcloud config unset project
Hapus resource Google Cloud lain yang dibuat dalam tutorial ini:
- Hapus image container bernama
gcr.io/<var>PROJECT_ID</var>/hello-service
dari Container Registry. - Jika Anda membuat cluster untuk tutorial ini, hapus cluster.
- Hapus image container bernama
Langkah selanjutnya
- Pelajari lebih lanjut cara menggunakan Cloud Logging untuk memperoleh insight pada perilaku produksi.
- Untuk mengetahui informasi selengkapnya tentang pemecahan masalah penayangan Knative.
- Pelajari arsitektur referensi, diagram, dan praktik terbaik tentang Google Cloud. Lihat Cloud Architecture Center kami.