Tutorial ini menunjukkan cara memecahkan masalah yang rusak Layanan inferensi Knative menggunakan alat Stackdriver untuk penemuan dan pengembangan aplikasi 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, membangun, dan men-deploy layanan ke inferensi 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 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 memiliki penayangan Knative diinstal dan dikonfigurasi pada cluster Anda.
- Pastikan lingkungan command line Anda sudah disiapkan dan alatnya up-to-date:
- Instal curl untuk mencoba layanan.
- Instal Docker secara lokal.
Susun kode
Membangun layanan service greeter Knative baru, 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: membuat image container dengan Cloud Build, mengupload image container ke Container Registry, dan untuk 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
sama dengan baik nama image container maupun nama layanan penayangan Knative. Perhatikan bahwa image container di-deploy ke layanan dan cluster yang telah dikonfigurasi 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 perintah routable, domain default, lewati langkah di atas dan salin URL ke browser web Anda.
Jika Anda tidak menggunakan sertifikat TLS otomatis dan pemetaan domain, Anda tidak diberikan URL yang dapat ditelusuri untuk layanan Anda.
Sebagai gantinya, gunakan URL yang disediakan dan alamat IP traffic 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 ditemukan. Tentukan
istio-system
jika Anda menginstal Cloud Service Mesh menggunakan konfigurasi defaultnya.Output yang dihasilkan 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 Anda Penyeimbang.
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 Anda layanan. Anda bisa mendapatkannya dengan mengambil URL default dan menghapus protokol
http://
.Lihat pesan error HTTP 500 atau HTTP 503.
Menyelidiki masalahnya
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.
Menggunakan alat yang tersedia untuk mengumpulkan detail lebih lanjut:
Lihat log untuk mengetahui detail selengkapnya.
Gunakan Cloud Logging untuk meninjau urutan operasi yang mengarah ke bukan masalah, termasuk pesan error.
Rollback ke versi stabil
Jika Anda memiliki revisi yang Anda tahu
berfungsi, Anda dapat melakukan rollback layanan
Anda untuk menggunakan revisi itu. Misalnya,
Anda tidak akan dapat melakukan rollback
hello-service
yang telah Anda deploy di
karena hanya berisi satu revisi.
Untuk menemukan revisi dan melakukan rollback layanan Anda:
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 merekonstruksi masalah pada penyaluran Knative yang mengonfirmasi bahwa masalah telah aktif ketika layanan di-{i>host<i} di Penyajian 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
akan menghapus instance container saat keluar. - Tanda
-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 container gambar. Jika tidak tersedia secara lokal, Docker akan mencoba mengambil gambar dari {i>registry<i} jarak jauh.
Pada browser anda, buka http://localhost:9000. Periksa output terminal untuk pesan error yang cocok dengan yang ada di Google Cloud Observability.
Jika masalah tidak dapat direproduksi secara lokal, masalah tersebut mungkin unik Lingkungan penyaluran Knative. Ulas Panduan pemecahan masalah penayangan Knative area tertentu untuk diselidiki.
Dalam hal ini, error 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 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 berjalan untuk menyertakan hal ini variabel:
Jalankan perintah update layanan dengan parameter
--update-env-vars
untuk tambahkan variabel lingkungan:gcloud run services update hello-service \ --update-env-vars NAME=Override
Tunggu beberapa detik selagi Knative membuat revisi baru berdasarkan revisi sebelumnya dengan menambahkan variabel lingkungan baru.
Pastikan bahwa layanan telah diperbaiki:
- Buka browser Anda ke URL layanan penayangan Knative.
- Lihat "Halo Penggantian!" akan muncul pada halaman tersebut.
- Pastikan tidak ada pesan atau error 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 untuk menghindari timbulnya 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 kluster.
- Hapus image container bernama
Langkah selanjutnya
- Pelajari lebih lanjut cara menggunakan Cloud Logging untuk mendapatkan insight tentang 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.