Panduan Visual untuk Menyelesaikan Masalah Kubernetes
Catatan. terjemah: Artikel ini adalah sebahagian daripada bahan projek yang diterbitkan dalam domain awam learnk8s, melatih syarikat dan pentadbir individu untuk bekerjasama dengan Kubernetes. Di dalamnya, Daniele Polencic, pengurus projek, berkongsi arahan visual tentang langkah-langkah yang perlu diambil sekiranya berlaku masalah umum dengan aplikasi yang dijalankan pada kluster K8s.
TL; DR: berikut ialah gambar rajah yang akan membantu anda nyahpepijat penggunaan dalam Kubernetes:
Carta alir untuk mencari dan membetulkan ralat dalam kelompok. Yang asal (dalam bahasa Inggeris) boleh didapati di PDF ΠΈ seperti gambar.
Apabila menggunakan aplikasi ke Kubernetes, biasanya terdapat tiga komponen yang anda perlu tentukan:
Deployment - ini adalah sejenis resipi untuk membuat salinan aplikasi, dipanggil pod;
Servis β pengimbang beban dalaman yang mengagihkan trafik antara pod;
Ingress β penerangan tentang bagaimana trafik akan dihantar dari dunia luar ke Perkhidmatan.
Berikut ialah ringkasan grafik pantas:
1) Dalam Kubernetes, aplikasi menerima trafik dari dunia luar melalui dua lapisan pengimbang beban: dalaman dan luaran.
2) Pengimbang dalaman dipanggil Perkhidmatan, yang luaran dipanggil Ingress.
3) Deployment mencipta pod dan memantaunya (ia tidak dibuat secara manual).
Katakan anda mahu menggunakan aplikasi mudah ala Hello World. Konfigurasi YAML untuknya akan kelihatan seperti ini:
Takrifannya agak panjang dan mudah untuk dikelirukan tentang bagaimana komponen berkaitan antara satu sama lain.
Sebagai contoh:
Bilakah anda harus menggunakan port 80 dan bilakah anda harus menggunakan 8080?
Sekiranya saya membuat port baharu untuk setiap perkhidmatan supaya ia tidak bercanggah?
Adakah nama label penting? Adakah mereka harus sama di mana-mana?
Sebelum memfokuskan pada penyahpepijatan, mari kita ingat bagaimana ketiga-tiga komponen itu berkait antara satu sama lain. Mari mulakan dengan Deployment dan Service.
Hubungan antara Deployment dan Service
Anda akan terkejut, tetapi Penggunaan dan Perkhidmatan sama sekali tidak berkaitan. Sebaliknya, Perkhidmatan menghala terus ke Pod, memintas Deployment.
Oleh itu, kami berminat dengan cara Pod dan Perkhidmatan berkaitan antara satu sama lain. Tiga perkara yang perlu diingat:
Pemilih (selector) untuk Perkhidmatan mesti sepadan dengan sekurang-kurangnya satu label Pod.
targetPort mesti sepadan containerPort bekas di dalam Pod.
port Perkhidmatan boleh apa sahaja. Perkhidmatan yang berbeza boleh menggunakan port yang sama kerana mereka mempunyai alamat IP yang berbeza.
Rajah berikut mewakili semua perkara di atas dalam bentuk grafik:
1) Bayangkan bahawa perkhidmatan mengarahkan trafik ke pod tertentu:
2) Apabila membuat pod, anda mesti nyatakan containerPort untuk setiap bekas dalam pod:
3) Apabila membuat perkhidmatan, anda mesti nyatakan port ΠΈ targetPort. Tetapi yang manakah digunakan untuk menyambung ke bekas?
4) Melalui targetPort. Ia mesti sepadan containerPort.
5) Katakan port 3000 dibuka dalam bekas. Kemudian nilainya targetPort sepatutnya sama.
Dalam fail YAML, label dan ports / targetPort mesti sepadan:
Bagaimana pula dengan label track: canary di bahagian atas bahagian Deployment? Patutkah ia sepadan?
Label ini khusus penggunaan dan tidak digunakan oleh perkhidmatan untuk menghalakan trafik. Dalam erti kata lain, ia boleh dialih keluar atau diberikan nilai yang berbeza.
Bagaimana dengan pemilih matchLabels?
Ia mesti sentiasa sepadan dengan label Pod, kerana ia digunakan oleh Deployment untuk menjejak pod.
Katakan anda membuat pengeditan yang betul. Bagaimana untuk menyemak mereka?
Anda boleh menyemak label pod dengan arahan berikut:
kubectl get pods --show-labels
Atau, jika pod tergolong dalam beberapa aplikasi:
kubectl get pods --selector any-name=my-app --show-labels
ΠΠ΄Π΅ any-name=my-app ialah label any-name: my-app.
Adakah terdapat sebarang kesulitan yang tinggal?
Anda boleh menyambung ke pod! Untuk melakukan ini, anda perlu menggunakan arahan port-forward dalam kubectl. Ia membolehkan anda menyambung ke perkhidmatan dan menyemak sambungan.
service/<service name> - nama perkhidmatan; dalam kes kami ia adalah my-service;
3000 ialah port yang perlu dibuka pada komputer;
80 - port yang dinyatakan dalam medan port perkhidmatan.
Jika sambungan telah diwujudkan, maka tetapan adalah betul.
Jika sambungan gagal, terdapat masalah dengan label atau port tidak sepadan.
Hubungan antara Perkhidmatan dan Ingress
Langkah seterusnya dalam menyediakan akses kepada aplikasi melibatkan penyediaan Ingress. Ingress perlu mengetahui cara mencari perkhidmatan, kemudian mencari pod dan mengarahkan trafik kepada mereka. Ingress mencari perkhidmatan yang diperlukan mengikut nama dan port terbuka.
Dalam perihalan Ingress dan Perkhidmatan dua parameter mesti sepadan:
servicePort dalam Ingress mesti sepadan dengan parameter port dalam Perkhidmatan;
serviceName dalam Ingress mesti sepadan dengan medan name dalam Perkhidmatan.
Rajah berikut meringkaskan sambungan port:
1) Seperti yang anda sedia maklum, Perkhidmatan mendengar sesuatu port:
2) Ingress mempunyai parameter yang dipanggil servicePort:
3) Parameter ini (servicePort) mesti sentiasa sepadan port dalam definisi Perkhidmatan:
4) Jika port 80 dinyatakan dalam Perkhidmatan, maka ia adalah perlu servicePort juga sama dengan 80:
Dalam amalan, anda perlu memberi perhatian kepada baris berikut:
Kini setiap kali anda menghantar permintaan ke port 3000 pada komputer anda, ia akan dimajukan ke port 80 pod dengan pengawal Ingress. Dengan pergi ke http://localhost:3000, anda seharusnya melihat halaman yang dijana oleh aplikasi.
Ringkasan pelabuhan
Mari kita ingat sekali lagi port dan label mana yang mesti sepadan:
Pemilih dalam definisi Perkhidmatan mesti sepadan dengan label pod;
targetPort dalam definisi Perkhidmatan mesti sepadan containerPort bekas di dalam pod;
port dalam definisi Perkhidmatan boleh menjadi apa sahaja. Perkhidmatan yang berbeza boleh menggunakan port yang sama kerana mereka mempunyai alamat IP yang berbeza;
servicePort Kemasukan mesti sepadan port dalam takrifan Perkhidmatan;
Nama perkhidmatan mesti sepadan dengan medan serviceName dalam Ingress.
Malangnya, ia tidak mencukupi untuk mengetahui cara menyusun konfigurasi YAML dengan betul.
Apa yang berlaku apabila berlaku masalah?
Pod mungkin tidak bermula atau mungkin ranap.
3 Langkah untuk Mendiagnosis Masalah Aplikasi dalam Kubernetes
Sebelum anda mula menyahpepijat penggunaan anda, anda perlu mempunyai pemahaman yang baik tentang cara Kubernetes berfungsi.
Memandangkan setiap aplikasi yang dimuat turun dalam K8s mempunyai tiga komponen, ia harus dinyahpepijat dalam susunan tertentu, bermula dari bahagian paling bawah.
Mula-mula anda perlu memastikan bahawa pod berfungsi, kemudian...
Semak sama ada perkhidmatan membekalkan trafik ke pod, dan kemudian...
Semak sama ada Ingress dikonfigurasikan dengan betul.
Perwakilan visual:
1) Anda harus mula mencari masalah dari bawah. Mula-mula semak bahawa pod mempunyai status Ready ΠΈ Running:
2) Jika buah sudah siap (Ready), anda harus mengetahui sama ada perkhidmatan mengedarkan trafik antara pod:
3) Akhir sekali, anda perlu menganalisis sambungan antara perkhidmatan dan Ingress:
1. Diagnostik pod
Dalam kebanyakan kes masalahnya berkaitan dengan pod. Pastikan pod disenaraikan sebagai Ready ΠΈ Running. Anda boleh menyemak ini menggunakan arahan:
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
Dalam output arahan di atas, pod terakhir disenaraikan sebagai Running ΠΈ Ready, bagaimanapun, ini tidak berlaku untuk dua yang lain.
Bagaimana untuk memahami apa yang salah?
Terdapat empat arahan berguna untuk mendiagnosis pod:
kubectl logs <ΠΈΠΌΡ pod'Π°> membolehkan anda mengekstrak log daripada bekas dalam pod;
kubectl describe pod <ΠΈΠΌΡ pod'Π°> membolehkan anda melihat senarai acara yang dikaitkan dengan pod;
kubectl get pod <ΠΈΠΌΡ pod'Π°> membolehkan anda mendapatkan konfigurasi YAML pod yang disimpan dalam Kubernetes;
kubectl exec -ti <ΠΈΠΌΡ pod'Π°> bash membolehkan anda melancarkan shell arahan interaktif dalam salah satu bekas pod
Mana satu patut anda pilih?
Hakikatnya tidak ada perintah universal. Gabungan ini harus digunakan.
Masalah pod biasa
Terdapat dua jenis utama ralat pod: ralat permulaan dan ralat masa jalan.
Ralat permulaan:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Ralat masa jalan:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Beberapa ralat adalah lebih biasa daripada yang lain. Berikut ialah beberapa ralat yang paling biasa dan cara membetulkannya.
ImagePullBackOff
Ralat ini berlaku apabila Kubernetes tidak dapat mendapatkan imej untuk salah satu bekas pod. Berikut ialah tiga sebab yang paling biasa untuk ini:
Nama imej tidak betul - sebagai contoh, anda membuat kesilapan di dalamnya, atau imej itu tidak wujud;
Teg yang tidak wujud telah ditentukan untuk imej;
Imej itu disimpan dalam daftar peribadi dan Kubernetes tidak mempunyai kebenaran untuk mengaksesnya.
Dua sebab pertama adalah mudah untuk dihapuskan - hanya betulkan nama imej dan teg. Dalam kes yang terakhir, anda perlu memasukkan bukti kelayakan untuk pendaftaran tertutup dalam Rahsia dan menambah pautan kepadanya dalam pod. Dalam dokumentasi Kubernetes ada contoh bagaimana ini boleh dilakukan.
Gelung Ranap Belakang
Kubenetes melemparkan ralat CrashLoopBackOff, jika bekas tidak boleh dimulakan. Ini biasanya berlaku apabila:
Terdapat pepijat dalam aplikasi yang menghalangnya daripada dilancarkan;
Anda mesti cuba mendapatkan log dari bekas untuk mengetahui sebab kegagalannya. Jika sukar untuk mengakses log kerana bekas dimulakan semula terlalu cepat, anda boleh menggunakan arahan berikut:
kubectl logs <pod-name> --previous
Ia memaparkan mesej ralat daripada penjelmaan bekas sebelumnya.
RunContainerError
Ralat ini berlaku apabila bekas gagal dimulakan. Ia sepadan dengan saat sebelum aplikasi dilancarkan. Ia biasanya disebabkan oleh tetapan yang salah, contohnya:
cuba melekapkan volum yang tidak wujud seperti ConfigMap atau Secrets;
percubaan untuk melekapkan volum baca sahaja sebagai baca-tulis.
Pasukan ini sangat sesuai untuk menganalisis ralat tersebut kubectl describe pod <pod-name>.
Pod berada dalam keadaan Menunggu
Setelah dibuat, pod kekal dalam keadaan Pending.
Kenapa ini berlaku?
Berikut ialah sebab yang mungkin (saya mengandaikan penjadual berfungsi dengan baik):
Kelompok tidak mempunyai sumber yang mencukupi, seperti kuasa pemprosesan dan memori, untuk menjalankan pod.
Objek dipasang dalam ruang nama yang sesuai ResourceQuota dan mencipta pod akan menyebabkan ruang nama melebihi kuota.
Pod terikat kepada Pending PersistentVolumeClaim.
Dalam kes ini, disyorkan untuk menggunakan arahan kubectl describe dan semak bahagian Events:
kubectl describe pod <pod name>
Sekiranya berlaku kesilapan yang berkaitan dengan ResourceQuotas, adalah disyorkan untuk melihat log kelompok menggunakan arahan
kubectl get events --sort-by=.metadata.creationTimestamp
Pod belum Sedia
Jika pod disenaraikan sebagai Running, tetapi tidak dalam keadaan Ready, bermakna menyemak kesediaannya (siasat kesediaan) gagal.
Apabila ini berlaku, pod tidak bersambung ke perkhidmatan dan tiada trafik mengalir kepadanya. Kegagalan ujian kesediaan disebabkan oleh masalah dalam aplikasi. Dalam kes ini, untuk mencari ralat, anda perlu menganalisis bahagian tersebut Events dalam output arahan kubectl describe.
2. Diagnostik perkhidmatan
Jika pod disenaraikan sebagai Running ΠΈ Ready, tetapi masih tiada jawapan daripada aplikasi, anda harus menyemak tetapan perkhidmatan.
Perkhidmatan bertanggungjawab untuk menghalakan trafik ke pod bergantung pada labelnya. Oleh itu, perkara pertama yang perlu anda lakukan ialah menyemak bilangan pod yang berfungsi dengan perkhidmatan tersebut. Untuk melakukan ini, anda boleh menyemak titik akhir dalam perkhidmatan:
kubectl describe service <service-name> | grep Endpoints
Titik akhir ialah sepasang nilai bentuk <IP-Π°Π΄ΡΠ΅Ρ:ΠΏΠΎΡΡ>, dan sekurang-kurangnya satu pasangan sedemikian mesti ada dalam output (iaitu, sekurang-kurangnya satu pod berfungsi dengan perkhidmatan).
Jika bahagian Endpoins kosong, dua pilihan mungkin:
tiada pod dengan label yang betul (petunjuk: semak jika ruang nama dipilih dengan betul);
Terdapat ralat dalam label perkhidmatan dalam pemilih.
Jika anda melihat senarai titik akhir tetapi masih tidak dapat mengakses aplikasi, kemungkinan penyebabnya ialah pepijat masuk targetPort dalam penerangan perkhidmatan.
Bagaimana untuk menyemak kefungsian perkhidmatan?
Tidak kira jenis perkhidmatan, anda boleh menggunakan arahan kubectl port-forward untuk menyambung kepadanya:
perkhidmatan ini berjaya mengagihkan trafik antara pod.
Walau bagaimanapun, anda masih tidak dapat mencapai apl tersebut.
Ini bermakna pengawal Ingress berkemungkinan besar tidak dikonfigurasikan dengan betul. Memandangkan pengawal Ingress ialah komponen pihak ketiga dalam kluster, terdapat kaedah penyahpepijatan yang berbeza bergantung pada jenisnya.
Tetapi sebelum anda menggunakan alat khas untuk mengkonfigurasi Ingress, anda boleh melakukan sesuatu yang sangat mudah. Kegunaan Ingress serviceName ΠΈ servicePort untuk menyambung ke perkhidmatan. Anda perlu menyemak sama ada ia dikonfigurasikan dengan betul. Anda boleh melakukan ini menggunakan arahan:
kubectl describe ingress <ingress-name>
Jika lajur Backend kosong, terdapat kebarangkalian tinggi ralat konfigurasi. Jika bahagian belakang telah disediakan, tetapi aplikasi masih tidak boleh diakses, maka masalah itu mungkin berkaitan dengan:
Tetapan kebolehcapaian masuk daripada Internet awam;
tetapan kebolehcapaian kelompok daripada Internet awam.
Anda boleh mengenal pasti masalah dengan infrastruktur dengan menyambung terus ke pod Ingress. Untuk melakukan ini, mula-mula cari pod Ingress Controller (ia mungkin dalam ruang nama yang berbeza):
Sekarang semua permintaan untuk port 3000 pada komputer akan diubah hala ke port 80 pod.
Adakah ia berfungsi sekarang?
Jika ya, maka masalahnya adalah dengan infrastruktur. Ia adalah perlu untuk mengetahui dengan tepat cara lalu lintas dihalakan ke kluster.
Jika tidak, maka masalahnya ialah dengan pengawal Ingress.
Jika anda tidak boleh membuat pengawal Ingress berfungsi, anda perlu menyahpepijatnya.
Terdapat banyak jenis pengawal Ingress. Yang paling popular ialah Nginx, HAProxy, Traefik, dll. (untuk maklumat lanjut tentang penyelesaian sedia ada, lihat kajian kami - lebih kurang terjemah.) Anda harus merujuk kepada panduan penyelesaian masalah dalam dokumentasi pengawal yang berkaitan. Kerana ia Ingress Nginx adalah pengawal Ingress yang paling popular, kami telah memasukkan beberapa petua dalam artikel untuk menyelesaikan masalah yang berkaitan dengannya.
Menyahpepijat pengawal Ingress Nginx
Projek Ingress-nginx mempunyai rasmi pemalam untuk kubectl. Pasukan kubectl ingress-nginx boleh digunakan untuk:
analisis log, bahagian belakang, sijil, dsb.;
sambungan ke Ingress;
mengkaji konfigurasi semasa.
Tiga arahan berikut akan membantu anda dengan ini:
kubectl ingress-nginx lint - cek nginx.conf;
kubectl ingress-nginx backend β meneroka bahagian belakang (serupa dengan kubectl describe ingress <ingress-name>);
kubectl ingress-nginx logs - menyemak log.
Ambil perhatian bahawa dalam beberapa kes anda mungkin perlu menentukan ruang nama yang betul untuk pengawal Ingress menggunakan bendera --namespace <name>.
Ringkasan
Menyelesaikan masalah Kubernetes boleh mencabar jika anda tidak tahu dari mana hendak bermula. Anda harus sentiasa mendekati masalah dari bawah ke atas: mulakan dengan pod, dan kemudian beralih ke perkhidmatan dan Ingress. Teknik penyahpepijatan yang diterangkan dalam artikel ini boleh digunakan pada objek lain, seperti: