Notu. transl.: Ĉi tiu artikolo estas parto de la projektmaterialoj publikigitaj en la publika domeno lernik8s, trejnado de kompanioj kaj individuaj administrantoj por labori kun Kubernetes. En ĝi, Daniele Polencic, projektestro, dividas vidajn instrukciojn pri kiaj paŝoj fari en kazo de ĝeneralaj problemoj kun aplikaĵoj kurantaj sur la K8s-areo.
TL;DR: jen diagramo, kiu helpos vin sencimigi deplojon en Kubernetes:
Fluodiagramo por trovi kaj ripari erarojn en areto. La originalo (en la angla) haveblas ĉe PDF и kiel bildo.
Dum deplojado de aplikaĵo al Kubernetes, estas kutime tri komponantoj, kiujn vi devas difini:
deplojo - ĉi tio estas speco de recepto por krei kopiojn de la aplikaĵo, nomataj guŝoj;
servo — interna ŝarĝbalancilo, kiu distribuas trafikon inter podoj;
Ingreso — priskribo de kiel trafiko venos de la ekstera mondo al la Servo.
Jen rapida grafika resumo:
1) En Kubernetes, aplikoj ricevas trafikon de la ekstera mondo per du tavoloj de ŝarĝbalanciloj: interna kaj ekstera.
2) La interna ekvilibro nomiĝas Servo, la ekstera nomiĝas Eniro.
3) Deplojo kreas podojn kaj kontrolas ilin (ili ne estas kreitaj permane).
Ni diru, ke vi volas disfaldi simplan aplikaĵon Saluton mondo. La YAML-agordo por ĝi aspektos jene:
Kio pri la etikedo track: canary ĉe la supro de la sekcio Deployment? Ĉu ĝi devus kongrui?
Ĉi tiu etikedo estas deploj-specifa kaj ne estas uzata de la servo por direkti trafikon. Alivorte, ĝi povas esti forigita aŭ asignita malsama valoro.
Kio pri la elektilo matchLabels?
Ĝi ĉiam devas kongrui kun la etikedoj de la Pod, ĉar ĝi estas uzata de Deployment por spuri podojn.
Ni supozu, ke vi faris la ĝustajn redaktojn. Kiel kontroli ilin?
Vi povas kontroli la pod-etikedon per la sekva komando:
kubectl get pods --show-labels
Aŭ, se balgoj apartenas al pluraj aplikoj:
kubectl get pods --selector any-name=my-app --show-labels
Kie any-name=my-app estas etikedo any-name: my-app.
Ĉu restas malfacilaĵoj?
Vi povas konektiĝi al la pod! Por fari tion, vi devas uzi la komandon port-forward en kubectl. Ĝi permesas vin konekti al la servo kaj kontroli la konekton.
service/<service name> — servonomo; en nia kazo estas my-service;
3000 estas la haveno, kiu devas esti malfermita en la komputilo;
80 - haveno specifita en la kampo port servo.
Se la konekto estis establita, tiam la agordoj estas ĝustaj.
Se la konekto malsukcesas, estas problemo kun la etikedoj aŭ la havenoj ne kongruas.
Rilato inter Servo kaj Eniro
La sekva paŝo en havigi aliron al la aplikaĵo implikas agordi Ingress. Ingress devas scii kiel trovi servon, poste trovi podojn kaj direkti trafikon al ili. Ingress trovas la postulatan servon laŭ nomo kaj malferma haveno.
En la priskribo de Eniro kaj Servo du parametroj devas kongrui:
servicePort en Eniro devas kongrui kun la parametro port en Servo;
serviceName en Ingress devas kongrui kun la kampo name en Servo.
La sekva diagramo resumas la havenkonektoj:
1) Kiel vi jam scias, Servo aŭskultas certan port:
2) Eniro havas parametron nomitan servicePort:
3) Ĉi tiu parametro (servicePort) ĉiam devas kongrui port en la Difino de Servo:
4) Se haveno 80 estas specifita en Servo, tiam necesas tion servicePort estis ankaŭ egala al 80:
En la praktiko, vi devas atenti la jenajn liniojn:
Nun ĉiufoje kiam vi sendas peton al la haveno 3000 en via komputilo, ĝi estos plusendita al la haveno 80 de la pod kun la Ingress-regilo. Irante al http://localhost:3000, vi devus vidi la paĝon generitan de la aplikaĵo.
Resumo de havenoj
Ni rememoru denove, kiuj havenoj kaj etikedoj devas kongrui:
La elektilo en la Servodifino devas kongrui kun la etikedo de la pod;
targetPort en la difino Servo devas kongrui containerPort ujo ene de balgo;
port en la difino Servo povas esti io ajn. Malsamaj servoj povas uzi la saman havenon ĉar ili havas malsamajn IP-adresojn;
servicePort Eniro devas kongrui port en la difino de Servo;
La servonomo devas kongrui kun la kampo serviceName en Eniro.
Bedaŭrinde, ne sufiĉas scii kiel ĝuste strukturi YAML-agordon.
Kio okazas kiam aferoj misfunkcias?
La pod eble ne komenciĝas aŭ ĝi povas kraŝi.
3 Paŝoj por Diagnozi Aplikajn Problemojn en Kubernetes
Antaŭ ol vi komencas sencimigi vian deplojon, vi devas bone kompreni kiel funkcias Kubernetes.
Ĉar ĉiu aplikaĵo elŝutita en K8s havas tri komponentojn, ili devus esti elpurigitaj en certa ordo, komencante de la malsupro.
Unue vi devas certigi, ke la guŝoj funkcias, poste...
Kontrolu ĉu la servo provizas trafikon al la podoj, kaj tiam...
Kontrolu ĉu Ingress estas agordita ĝuste.
Vida reprezentado:
1) Vi devus komenci serĉi problemojn de la fundo. Unue kontrolu, ke balgoj havas statusojn Ready и Running:
2) Se la balgoj estas pretaj (Ready), vi devus ekscii ĉu la servo distribuas trafikon inter podoj:
3) Fine, vi devas analizi la rilaton inter la servo kaj la Eniro:
1. Diagnozo de podoj
Plejofte la problemo rilatas al la pod. Certigu, ke balgoj estas listigitaj kiel Ready и Running. Vi povas kontroli ĉi tion per la komando:
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
En la komanda eligo supre, la lasta pod estas listigita kiel Running и Ready, tamen, ĉi tio ne estas la kazo por la aliaj du.
Kiel kompreni kio misfunkciis?
Estas kvar utilaj komandoj por diagnozi podojn:
kubectl logs <имя pod'а> permesas al vi ĉerpi ŝtipojn el ujoj en balgo;
kubectl describe pod <имя pod'а> permesas al vi vidi liston de eventoj asociitaj kun la pod;
kubectl get pod <имя pod'а> permesas vin akiri la YAML-agordon de pod stokita en Kubernetes;
kubectl exec -ti <имя pod'а> bash permesas al vi lanĉi interagan komandan ŝelon en unu el la podujoj
Kiun vi elektu?
La fakto estas, ke ne ekzistas universala komando. Kombinaĵo de ĉi tiuj devus esti uzata.
Tipaj podproblemoj
Estas du ĉefaj specoj de pod-eraroj: lanĉaj eraroj kaj rultempaj eraroj.
Komencaj eraroj:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Rultempaj eraroj:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Iuj eraroj estas pli oftaj ol aliaj. Jen kelkaj el la plej oftaj eraroj kaj kiel ripari ilin.
ImagePullBackOff
Ĉi tiu eraro okazas kiam Kubernetes ne povas akiri bildon por unu el la podujoj. Jen la tri plej oftaj kialoj por ĉi tio:
La nomo de la bildo estas malĝusta - ekzemple, vi faris eraron en ĝi, aŭ la bildo ne ekzistas;
Neekzistanta etikedo estis specifita por la bildo;
La bildo estas konservita en privata registro kaj Kubernetes ne havas permeson aliri ĝin.
La unuaj du kialoj estas facile elimineblaj - nur korektu la bildonomon kaj etikedon. En la kazo de ĉi-lasta, vi devas enigi akreditaĵojn por la fermita registro en Sekreta kaj aldoni ligilojn al ĝi en podoj. En la dokumentado de Kubernetes estas ekzemplo kiel tio povas esti farita.
Kraŝa Buklo Malŝaltita
Kubenetes ĵetas eraron CrashLoopBackOff, se la ujo ne povas komenci. Ĉi tio kutime okazas kiam:
Estas cimo en la aplikaĵo, kiu malhelpas ĝin lanĉi;
Vi devas provi atingi la ŝtipojn de la ujo por ekscii la kialon de ĝia malsukceso. Se estas malfacile aliri la protokolojn ĉar la ujo rekomencas tro rapide, vi povas uzi la jenan komandon:
kubectl logs <pod-name> --previous
Ĝi montras erarmesaĝojn de la antaŭa enkarniĝo de la ujo.
RunContainerError
Ĉi tiu eraro okazas kiam la ujo ne komenciĝas. Ĝi respondas al la momento antaŭ ol la aplikaĵo estas lanĉita. Ĝi estas kutime kaŭzita de malĝustaj agordoj, ekzemple:
provante munti neekzistantan volumenon kiel ConfigMap aŭ Sekretoj;
provo munti nurlegeblan volumon kiel lego-skribi.
La teamo taŭgas por analizi tiajn erarojn kubectl describe pod <pod-name>.
Pods estas en Pritraktata stato
Fojo kreita, la balgo restas en la ŝtato Pending.
Kial ĉi tio okazas?
Jen la eblaj kialoj (mi supozas, ke la planilo funkcias bone):
La areto ne havas sufiĉajn rimedojn, kiel pretigpovon kaj memoron, por funkcii la pod.
La objekto estas instalita en la taŭga nomspaco ResourceQuota kaj kreado de pod kaŭzos la nomspacon preterpasi la kvoton.
Pod estas ligita al Pritraktata PersistentVolumeClaim.
En ĉi tiu kazo, oni rekomendas uzi la komandon kubectl describe kaj kontrolu la sekcion Events:
kubectl describe pod <pod name>
En kazo de eraroj rilataj al ResourceQuotas, oni rekomendas vidi la grapolprotokolojn uzante la komandon
kubectl get events --sort-by=.metadata.creationTimestamp
Pods ne estas Pretaj
Se pod estas listigita kiel Running, sed ne estas en stato Ready, signifas kontroli ĝian pretecon (preteca sondo) malsukcesas.
Kiam tio okazas, la pod ne konektas al la servo kaj neniu trafiko fluas al ĝi. La fiasko de la preteca testo estas kaŭzita de problemoj en la aplikaĵo. En ĉi tiu kazo, por trovi la eraron, vi devas analizi la sekcion Events en la komanda eligo kubectl describe.
2. Servaj diagnozoj
Se balgoj estas listigitaj kiel Running и Ready, sed ankoraŭ ne estas respondo de la aplikaĵo, vi devus kontroli la servo-agordojn.
Servoj respondecas pri direktado de trafiko al podoj depende de siaj etikedoj. Tial, la unua afero, kiun vi devas fari, estas kontroli kiom da podoj funkcias kun la servo. Por fari tion, vi povas kontroli la finpunktojn en la servo:
kubectl describe service <service-name> | grep Endpoints
Finpunkto estas paro de valoroj de la formo <IP-адрес:порт>, kaj almenaŭ unu tia paro devas ĉeesti en la eligo (tio estas, almenaŭ unu pod funkcias kun la servo).
Se sekcio Endpoins malplena, du opcioj estas eblaj:
ne ekzistas podoj kun la ĝusta etikedo (sugesto: kontrolu ĉu la nomspaco estas ĝuste elektita);
Estas eraro en la servaj etikedoj en la elektilo.
Se vi vidas liston de finpunktoj sed ankoraŭ ne povas aliri la aplikaĵon, tiam la verŝajna kulpulo estas cimo en targetPort en la priskribo de la servo.
Kiel kontroli la funkciojn de la servo?
Sendepende de la speco de servo, vi povas uzi la komandon kubectl port-forward por konekti al ĝi:
3000 estas la haveno, kiun vi malfermas en la komputilo;
80 - haveno ĉe la servoflanko.
3. Diagnozo de eniro
Se vi legis ĉi tien, tiam:
balgoj estas listigitaj kiel Running и Ready;
la servo sukcese distribuas trafikon inter podoj.
Tamen, vi ankoraŭ ne povas "atingi" la aplikaĵon.
Ĉi tio signifas, ke la Ingress-regilo plej verŝajne ne estas agordita ĝuste. Ĉar la Ingress-regilo estas triaparta komponento en la areto, ekzistas malsamaj sencimigaj metodoj depende de ĝia tipo.
Sed antaŭ ol vi uzas specialajn ilojn por agordi Ingress, vi povas fari ion tre simplan. Enir-uzoj serviceName и servicePort por konekti al la servo. Vi devas kontroli ĉu ili estas ĝuste agorditaj. Vi povas fari tion uzante la komandon:
kubectl describe ingress <ingress-name>
Se kolumno Backend malplena, estas alta probablo de agorda eraro. Se la backends estas en loko, sed la aplikaĵo ankoraŭ ne estas alirebla, tiam la problemo eble rilatas al:
Eniri alireblajn agordojn de la publika Interreto;
agordoj de alirebleco de cluster de la publika Interreto.
Vi povas identigi problemojn kun la infrastrukturo konektante rekte al la Ingress-podo. Por fari tion, unue trovu la Ingress Controller pod (ĝi povas esti en malsama nomspaco):
Nun ĉiuj petoj al haveno 3000 en la komputilo estos redirektitaj al haveno 80 de la pod.
Ĉu ĝi funkcias nun?
Se jes, tiam la problemo estas kun la infrastrukturo. Necesas ekscii ĝuste kiel trafiko estas direktita al la areto.
Se ne, tiam la problemo estas kun la Ingress-regilo.
Se vi ne povas funkcii la Ingress-regilon, vi devos sencimigi ĝin.
Estas multaj varioj de Ingress-regiloj. La plej popularaj estas Nginx, HAProxy, Traefik, ktp. (por pliaj informoj pri ekzistantaj solvoj, vidu nia recenzo - ĉ. traduk.) Vi devus raporti al la gvidilo pri solvo de problemoj en la koncerna dokumentaro pri regilo. Ĉar la Eniro Nginx estas la plej populara Ingress-regilo, ni inkluzivis kelkajn konsiletojn en la artikolo por solvi problemojn rilatajn al ĝi.
Sencimigi la Ingress Nginx-regilon
La projekto Ingress-nginx havas oficialulon kromaĵo por kubectl. Teamo kubectl ingress-nginx povas esti uzata por:
analizo de protokoloj, backends, atestiloj, ktp.;
ligoj al Ingress;
studante la nunan agordon.
La sekvaj tri komandoj helpos vin pri tio:
kubectl ingress-nginx lint - ĉekoj nginx.conf;
kubectl ingress-nginx backend — esploras la malantaŭon (simila al kubectl describe ingress <ingress-name>);
kubectl ingress-nginx logs — kontrolas la protokolojn.
Notu, ke en iuj kazoj vi eble bezonos specifi la ĝustan nomspacon por la Ingress-regilo uzante la flagon --namespace <name>.
Resumo
Solvi Kubernetes povas esti malfacila se vi ne scias kie komenci. Vi ĉiam devas alproksimiĝi al la problemo de malsupre supren: komencu per podoj, kaj poste transiru al la servo kaj Eniro. La sencimigaj teknikoj priskribitaj en ĉi tiu artikolo povas esti aplikitaj al aliaj objektoj, kiel ekzemple: