Catatan. terjemahan: Artikel ini adalah bagian dari materi proyek yang dipublikasikan dalam domain publik belajark8s, melatih perusahaan dan administrator individu untuk bekerja dengan Kubernetes. Di dalamnya, Daniele Polencic, manajer proyek, berbagi instruksi visual tentang langkah-langkah yang harus diambil jika terjadi masalah umum dengan aplikasi yang berjalan di cluster K8s.
TL;DR: berikut adalah diagram yang akan membantu Anda men-debug penerapan di Kubernetes:
Diagram alur untuk menemukan dan memperbaiki kesalahan dalam sebuah cluster. Versi asli (dalam bahasa Inggris) tersedia di PDF ΠΈ seperti gambar.
Saat men-deploy aplikasi ke Kubernetes, biasanya ada tiga komponen yang perlu Anda tentukan:
Penyebaran - ini adalah semacam resep untuk membuat salinan aplikasi, yang disebut pod;
Pelayanan β penyeimbang beban internal yang mendistribusikan lalu lintas antar pod;
Jalan masuk β deskripsi tentang bagaimana lalu lintas dari dunia luar menuju Layanan.
Berikut ringkasan grafis singkatnya:
1) Di Kubernetes, aplikasi menerima lalu lintas dari dunia luar melalui dua lapisan penyeimbang beban: internal dan eksternal.
2) Penyeimbang internal disebut Layanan, penyeimbang eksternal disebut Ingress.
3) Deployment membuat pod dan memantaunya (tidak dibuat secara manual).
Katakanlah Anda ingin menerapkan aplikasi sederhana ala Hello Dunia. Konfigurasi YAML untuknya akan terlihat seperti ini:
Definisinya cukup panjang dan mudah membuat bingung bagaimana komponen-komponen tersebut berhubungan satu sama lain.
Sebagai contoh:
Kapan sebaiknya Anda menggunakan port 80 dan kapan sebaiknya menggunakan 8080?
Haruskah saya membuat port baru untuk setiap layanan agar tidak konflik?
Apakah nama label penting? Haruskah semuanya sama di mana pun?
Sebelum fokus pada debugging, mari kita ingat bagaimana ketiga komponen tersebut berhubungan satu sama lain. Mari kita mulai dengan Penerapan dan Layanan.
Hubungan antara Penerapan dan Layanan
Anda akan terkejut, namun Deployment dan Service sama sekali tidak terhubung. Sebaliknya, Service menunjuk langsung ke Pod, melewati Deployment.
Oleh karena itu, kami tertarik pada bagaimana Pod dan Layanan saling terkait satu sama lain. Tiga hal yang perlu diingat:
Pemilih (selector) untuk Layanan harus cocok dengan setidaknya satu label Pod.
targetPort harus cocok containerPort wadah di dalam Pod.
port Pelayanan bisa berupa apa saja. Layanan yang berbeda dapat menggunakan port yang sama karena memiliki alamat IP yang berbeda.
Diagram berikut mewakili semua hal di atas dalam bentuk grafik:
1) Bayangkan layanan mengarahkan lalu lintas ke pod tertentu:
2) Saat membuat pod, Anda harus menentukannya containerPort untuk setiap kontainer di pod:
3) Saat membuat layanan, Anda harus menentukan port ΠΈ targetPort. Tapi yang mana yang digunakan untuk menyambung ke container?
4) Melalui targetPort. Itu harus cocok containerPort.
5) Misalkan port 3000 terbuka di container, maka nilainya targetPort harus sama.
Dalam file YAML, label dan ports / targetPort harus cocok:
Bagaimana dengan labelnya track: canary di bagian atas bagian Penerapan? Haruskah itu cocok?
Label ini khusus untuk penerapan dan tidak digunakan oleh layanan untuk merutekan lalu lintas. Dengan kata lain, itu dapat dihapus atau diberi nilai berbeda.
Bagaimana dengan pemilihnya matchLabels?
Label tersebut harus selalu cocok dengan label Pod, karena digunakan oleh Deployment untuk melacak pod.
Anggaplah Anda telah melakukan pengeditan yang benar. Bagaimana cara memeriksanya?
Anda dapat memeriksa label pod dengan perintah berikut:
kubectl get pods --show-labels
Atau, jika pod milik beberapa aplikasi:
kubectl get pods --selector any-name=my-app --show-labels
ΠΠ΄Π΅ any-name=my-app adalah label any-name: my-app.
Apakah masih ada kesulitan?
Anda dapat terhubung ke pod! Untuk melakukan ini, Anda perlu menggunakan perintah port-forward di kubectl. Ini memungkinkan Anda untuk terhubung ke layanan dan memeriksa koneksi.
service/<service name> - Nama layanan; dalam kasus kami memang demikian my-service;
3000 adalah port yang perlu dibuka di komputer;
80 - port yang ditentukan di lapangan port melayani.
Jika koneksi berhasil dibuat, maka pengaturannya sudah benar.
Jika koneksi gagal, ada masalah dengan label atau port tidak cocok.
Hubungan antara Layanan dan Ingress
Langkah selanjutnya dalam menyediakan akses ke aplikasi melibatkan pengaturan Ingress. Ingress perlu mengetahui cara menemukan layanan, kemudian menemukan pod dan mengarahkan lalu lintas ke layanan tersebut. Ingress menemukan layanan yang diperlukan berdasarkan nama dan port terbuka.
Dalam deskripsi Ingress dan Service, dua parameter harus cocok:
servicePort di Ingress harus sesuai dengan parameter port dalam pelayanan;
serviceName di Ingress harus sesuai dengan bidangnya name dalam pelayanan.
Diagram berikut merangkum koneksi port:
1) Seperti yang sudah Anda ketahui, Layanan mendengarkan hal tertentu port:
2) Ingress memiliki parameter yang disebut servicePort:
3) Parameter ini (servicePort) harus selalu cocok port dalam definisi Layanan:
4) Jika port 80 ditentukan dalam Layanan, maka itu perlu servicePort juga sama dengan 80:
Dalam praktiknya, Anda perlu memperhatikan baris-baris berikut:
Sekarang setiap kali Anda mengirim permintaan ke port 3000 di komputer Anda, permintaan itu akan diteruskan ke port 80 pod dengan pengontrol Ingress. Dengan pergi ke http://localhost:3000, Anda akan melihat halaman yang dihasilkan oleh aplikasi.
Ringkasan port
Mari kita ingat sekali lagi port dan label mana yang harus cocok:
Pemilih pada definisi Service harus cocok dengan label pod;
targetPort dalam definisi Layanan harus cocok containerPort wadah di dalam pod;
port dalam definisinya Pelayanan bisa berupa apa saja. Layanan yang berbeda dapat menggunakan port yang sama karena memiliki alamat IP yang berbeda;
servicePort Ingress harus cocok port dalam pengertian Jasa;
Nama layanan harus sesuai dengan bidangnya serviceName di masuknya.
Sayangnya, mengetahui cara menyusun konfigurasi YAML dengan benar saja tidak cukup.
Apa yang terjadi jika ada yang salah?
Pod mungkin tidak dapat dijalankan atau mungkin crash.
3 Langkah Mendiagnosis Masalah Aplikasi di Kubernetes
Sebelum memulai proses debug penerapan, Anda harus memiliki pemahaman yang baik tentang cara kerja Kubernetes.
Karena setiap aplikasi yang diunduh di K8s memiliki tiga komponen, komponen tersebut harus di-debug dalam urutan tertentu, dimulai dari paling bawah.
Pertama, Anda perlu memastikan bahwa podnya berfungsi, lalu...
Periksa apakah layanan memasok lalu lintas ke pod, dan kemudian...
Periksa apakah Ingress dikonfigurasi dengan benar.
Representasi visual:
1) Anda harus mulai mencari masalah dari paling bawah. Pertama periksa apakah pod memiliki status Ready ΠΈ Running:
2) Jika pod sudah siap (Ready), Anda harus mencari tahu apakah layanan mendistribusikan lalu lintas antar pod:
3) Terakhir, Anda perlu menganalisis hubungan antara layanan dan Ingress:
1. Diagnostik pod
Dalam sebagian besar kasus, masalahnya terkait dengan pod. Pastikan pod terdaftar sebagai Ready ΠΈ Running. Anda dapat memeriksanya menggunakan perintah:
kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 0/1 ImagePullBackOff 0 47h
app2 0/1 Error 0 47h
app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
Pada output perintah di atas, pod terakhir dicantumkan sebagai Running ΠΈ ReadyNamun, hal ini tidak terjadi pada dua lainnya.
Bagaimana memahami apa yang salah?
Ada empat perintah yang berguna untuk mendiagnosis pod:
kubectl logs <ΠΈΠΌΡ pod'Π°> memungkinkan Anda mengekstrak log dari container di dalam pod;
kubectl describe pod <ΠΈΠΌΡ pod'Π°> memungkinkan Anda melihat daftar acara yang terkait dengan pod;
kubectl get pod <ΠΈΠΌΡ pod'Π°> memungkinkan Anda mendapatkan konfigurasi YAML dari pod yang disimpan di Kubernetes;
kubectl exec -ti <ΠΈΠΌΡ pod'Π°> bash memungkinkan Anda meluncurkan shell perintah interaktif di salah satu kontainer pod
Yang mana yang harus Anda pilih?
Faktanya adalah tidak ada perintah universal. Kombinasi dari hal-hal tersebut harus digunakan.
Masalah umum pada pod
Ada dua jenis utama kesalahan pod: kesalahan startup dan kesalahan runtime.
Kesalahan permulaan:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Kesalahan waktu proses:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Beberapa kesalahan lebih umum terjadi dibandingkan kesalahan lainnya. Berikut beberapa kesalahan paling umum dan cara memperbaikinya.
GambarPullBackOff
Kesalahan ini terjadi ketika Kubernetes tidak dapat memperoleh image untuk salah satu container pod. Berikut adalah tiga alasan paling umum untuk hal ini:
Nama gambar salah - misalnya, Anda membuat kesalahan di dalamnya, atau gambar tidak ada;
Tag yang tidak ada telah ditentukan untuk gambar tersebut;
Gambar tersebut disimpan dalam registri pribadi dan Kubernetes tidak memiliki izin untuk mengaksesnya.
Dua alasan pertama mudah dihilangkan - cukup perbaiki nama gambar dan tag. Dalam kasus yang terakhir, Anda perlu memasukkan kredensial untuk registri tertutup di Rahasia dan menambahkan tautan ke dalamnya di pod. Dalam dokumentasi Kubernetes ada contohnya bagaimana hal ini dapat dilakukan.
Crash Loop Mundur
Kubenetes membuat kesalahan CrashLoopBackOff, jika penampung tidak dapat dimulai. Ini biasanya terjadi ketika:
Ada bug dalam aplikasi yang mencegah peluncurannya;
Anda harus mencoba mendapatkan log dari penampung untuk mengetahui alasan kegagalannya. Jika sulit mengakses log karena kontainer dimulai ulang terlalu cepat, Anda dapat menggunakan perintah berikut:
kubectl logs <pod-name> --previous
Ini menampilkan pesan kesalahan dari inkarnasi penampung sebelumnya.
JalankanContainerError
Kesalahan ini terjadi ketika penampung gagal dimulai. Ini sesuai dengan momen sebelum aplikasi diluncurkan. Biasanya disebabkan oleh pengaturan yang salah, misalnya:
mencoba memasang volume yang tidak ada seperti ConfigMap atau Secrets;
Upaya untuk memasang volume baca-saja sebagai baca-tulis.
Tim ini sangat cocok untuk menganalisis kesalahan seperti itu kubectl describe pod <pod-name>.
Pod berada dalam status Tertunda
Setelah dibuat, pod tetap berada dalam status Pending.
Kenapa ini terjadi?
Berikut adalah kemungkinan alasannya (saya berasumsi penjadwal berfungsi dengan baik):
Cluster tidak memiliki sumber daya yang cukup, seperti kekuatan pemrosesan dan memori, untuk menjalankan pod.
Objek dipasang di namespace yang sesuai ResourceQuota dan membuat pod akan menyebabkan namespace melebihi kuota.
Pod terikat pada Pending PersistentVolumeClaim.
Dalam hal ini, disarankan untuk menggunakan perintah kubectl describe dan periksa bagian tersebut Events:
kubectl describe pod <pod name>
Jika terjadi kesalahan terkait dengan ResourceQuotas, disarankan untuk melihat log cluster menggunakan perintah
kubectl get events --sort-by=.metadata.creationTimestamp
Pod belum Siap
Jika pod terdaftar sebagai Running, tetapi tidak dalam keadaan Ready, artinya mengecek kesiapannya (pemeriksaan kesiapan) gagal.
Jika hal ini terjadi, pod tidak akan terhubung ke layanan dan tidak ada lalu lintas yang mengalir ke layanan tersebut. Kegagalan uji kesiapan disebabkan oleh masalah pada aplikasi. Dalam hal ini, untuk menemukan kesalahan, Anda perlu menganalisis bagian tersebut Events dalam keluaran perintah kubectl describe.
2. Diagnostik layanan
Jika pod terdaftar sebagai Running ΠΈ Ready, namun masih belum ada respon dari aplikasi, sebaiknya periksa pengaturan layanan.
Layanan bertanggung jawab untuk merutekan lalu lintas ke pod bergantung pada labelnya. Oleh karena itu, hal pertama yang perlu Anda lakukan adalah memeriksa berapa banyak pod yang berfungsi dengan layanan tersebut. Untuk melakukan ini, Anda dapat memeriksa titik akhir di layanan:
kubectl describe service <service-name> | grep Endpoints
Titik akhir adalah sepasang nilai formulir <IP-Π°Π΄ΡΠ΅Ρ:ΠΏΠΎΡΡ>, dan setidaknya satu pasangan tersebut harus ada dalam output (yaitu, setidaknya satu pod berfungsi dengan layanan tersebut).
Jika bagian Endpoins kosong, ada dua opsi yang mungkin:
tidak ada pod dengan label yang benar (petunjuk: periksa apakah namespace dipilih dengan benar);
Ada kesalahan pada label layanan di pemilih.
Jika Anda melihat daftar titik akhir tetapi masih tidak dapat mengakses aplikasi, kemungkinan besar penyebabnya adalah bug di targetPort dalam deskripsi layanan.
Bagaimana cara memeriksa fungsionalitas layanan?
Apa pun jenis layanannya, Anda dapat menggunakan perintah ini kubectl port-forward untuk menyambungkannya:
layanan berhasil mendistribusikan lalu lintas antar pod.
Namun, Anda masih tidak dapat menjangkau aplikasi tersebut.
Ini berarti pengontrol Ingress kemungkinan besar tidak dikonfigurasi dengan benar. Karena pengontrol Ingress adalah komponen pihak ketiga dalam cluster, terdapat metode debugging yang berbeda tergantung pada jenisnya.
Namun sebelum Anda menggunakan alat khusus untuk mengonfigurasi Ingress, Anda dapat melakukan sesuatu yang sangat sederhana. Penggunaan masuknya serviceName ΠΈ servicePort untuk terhubung ke layanan. Anda perlu memeriksa apakah sudah dikonfigurasi dengan benar. Anda dapat melakukannya dengan menggunakan perintah:
kubectl describe ingress <ingress-name>
Jika kolom Backend kosong, kemungkinan besar terjadi kesalahan konfigurasi. Jika backend sudah terpasang, namun aplikasi masih tidak dapat diakses, masalahnya mungkin terkait dengan:
Pengaturan aksesibilitas masuknya dari Internet publik;
pengaturan aksesibilitas cluster dari Internet publik.
Anda dapat mengidentifikasi masalah pada infrastruktur dengan menghubungkan langsung ke pod Ingress. Untuk melakukan ini, pertama-tama temukan pod Ingress Controller (mungkin dalam namespace yang berbeda):
Sekarang semua permintaan ke port 3000 di komputer akan dialihkan ke port 80 pada pod.
Apakah ini berhasil sekarang?
Jika ya, maka masalahnya ada pada infrastruktur. Penting untuk mengetahui dengan tepat bagaimana lalu lintas diarahkan ke cluster.
Jika tidak, maka masalahnya ada pada pengontrol Ingress.
Jika Anda tidak dapat membuat pengontrol Ingress berfungsi, Anda harus melakukan debug.
Ada banyak jenis pengontrol Ingress. Yang paling populer adalah Nginx, HAProxy, Traefik, dll. (untuk informasi lebih lanjut tentang solusi yang ada, lihat ulasan kami - kira-kira. terjemahkan) Anda harus merujuk ke panduan pemecahan masalah dalam dokumentasi pengontrol yang relevan. Karena Masuknya Nginx adalah pengontrol Ingress paling populer, kami telah menyertakan beberapa tip dalam artikel untuk memecahkan masalah terkait dengannya.
Men-debug pengontrol Ingress Nginx
Proyek Ingress-nginx memiliki seorang pejabat plugin untuk kubectl. Tim kubectl ingress-nginx dapat digunakan untuk:
analisis log, backend, sertifikat, dll.;
koneksi ke Ingress;
mempelajari konfigurasi saat ini.
Tiga perintah berikut akan membantu Anda dalam hal ini:
Perhatikan bahwa dalam beberapa kasus, Anda mungkin perlu menentukan namespace yang benar untuk pengontrol Ingress menggunakan flag --namespace <name>.
Ringkasan
Memecahkan masalah Kubernetes bisa menjadi tantangan jika Anda tidak tahu harus mulai dari mana. Anda harus selalu menangani masalah dari bawah ke atas: mulai dengan pod, lalu beralih ke layanan dan Ingress. Teknik debugging yang dijelaskan dalam artikel ini dapat diterapkan ke objek lain, seperti: