Una guia visual per resoldre problemes de Kubernetes
Nota. transl.: Aquest article forma part dels materials del projecte disponibles gratuïtament aprendre8sque ensenya a empreses i administradors individuals a treballar amb Kubernetes. En ell, Daniele Polencic, líder del projecte, comparteix una guia visual sobre quins passos cal seguir si hi ha problemes generals amb les aplicacions que s'executen en un clúster K8s.
TL;DR: Aquí teniu un diagrama que us ajudarà a depurar el vostre desplegament de Kubernetes:
Diagrama de flux per trobar i corregir errors en un clúster. L'original (en anglès) està disponible a PDF и com a imatge.
Quan es desplega una aplicació a Kubernetes, normalment hi ha tres components que cal definir:
Desplegament - aquesta és una recepta per crear còpies de l'aplicació, anomenada pods;
servei - un equilibrador de càrrega intern que distribueix el trànsit entre pods;
Ingrés - una descripció de com arribarà el trànsit del món exterior al Servei.
Aquí teniu un breu resum gràfic:
1) A Kubernetes, les aplicacions reben trànsit del món exterior mitjançant dues capes d'equilibradors de càrrega: intern i extern.
2) L'equilibrador intern s'anomena Servei, l'extern és Ingress.
3) El desplegament crea pods i els supervisa (no es creen manualment).
Suposem que voleu desplegar una aplicació senzilla al mateix temps Hola món. La configuració de YAML serà així:
La definició és força llarga i és fàcil confondre's sobre com es relacionen els components entre si.
Per exemple:
Quan he d'utilitzar el port 80 i quan he d'utilitzar 8080?
S'ha de crear un port nou per a cada servei perquè no entren en conflicte?
Importen els noms de les etiquetes? Haurien de ser iguals a tot arreu?
Abans de centrar-nos en la depuració, repassem com es relacionen els tres components. Comencem amb el desplegament i el servei.
Relació entre el desplegament i el servei
Us sorprendrà, però els desplegaments i els serveis no estan connectats de cap manera. En lloc d'això, el Servei apunta directament als Pods, sense passar pel desplegament.
Per tant, ens interessa com es relacionen els Pods i els Serveis. Tres coses a recordar:
Selector (selector) per a un Servei ha de coincidir com a mínim amb una etiqueta Pod.
targetPort ha de coincidir amb containerPort contenidor dins del Pod.
port El servei pot ser qualsevol cosa. Diferents serveis poden utilitzar el mateix port perquè tenen diferents adreces IP.
El diagrama següent representa tot allò anterior en forma gràfica:
1) Imagineu que el servei envia trànsit a un pod determinat:
2) Quan creeu un pod, heu de configurar containerPort per a cada recipient en beines:
3) Quan creeu un servei, heu d'especificar port и targetPort. Però per quin d'ells passa la connexió amb el contenidor?
4) A través targetPort. Ha de coincidir amb containerPort.
5) Suposem que el port 3000 està obert al contenidor, llavors el valor targetPort hauria de ser el mateix.
Al fitxer YAML, les etiquetes i ports / targetPort ha de coincidir amb:
Què passa amb l'etiqueta track: canary a la part superior de la secció de Desplegament? Hauria de coincidir?
Aquesta etiqueta és específica del desplegament i el servei no l'utilitza per encaminar el trànsit. En altres paraules, es pot eliminar o assignar un valor diferent.
Què passa amb el selector matchLabels?
Sempre ha de coincidir amb les etiquetes del pod, ja que Deployment l'utilitza per fer un seguiment dels pods.
Suposem que heu fet les edicions correctes. Com comprovar-los?
Podeu comprovar l'etiqueta dels pods amb l'ordre següent:
kubectl get pods --show-labels
O, si els pods són propietat de diverses aplicacions:
kubectl get pods --selector any-name=my-app --show-labels
On any-name=my-app és una etiqueta any-name: my-app.
Queden dificultats?
Pots connectar-te a un pod! Per a això cal utilitzar l'ordre port-forward en kubectl. Permet connectar-se al servei i comprovar la connexió.
service/<service name> - nom del servei; en el nostre cas ho és my-service;
3000 és el port que voleu obrir a l'ordinador;
80 - port especificat al camp port servei.
Si la connexió s'ha establert correctament, la configuració és correcta.
Si no s'ha pogut establir la connexió, hi ha un problema amb les etiquetes o els ports no coincideixen.
Relació entre Servei i Ingress
El següent pas per proporcionar accés a l'aplicació està relacionat amb la configuració de l'Ingress. Ingress ha de saber com trobar el servei, després trobar els pods i enviar-hi trànsit. Ingress troba el servei desitjat pel nom i el port obert.
A la descripció d'Ingress i Service, dos paràmetres han de coincidir:
servicePort a Ingress ha de coincidir amb el paràmetre port en servei;
serviceName a Ingress ha de coincidir amb el camp name en servei.
El diagrama següent resumeix les connexions del port:
1) Com ja sabeu, Servei escolta alguns port:
2) Ingress té un paràmetre anomenat servicePort:
3) Aquest paràmetre (servicePort) sempre ha de coincidir port a la definició de servei:
4) Si s'especifica el port 80 al servei, és necessari que això servicePort també era igual a 80:
A la pràctica, cal parar atenció a les línies següents:
Ara, cada vegada que envieu una sol·licitud al port 3000 de la màquina, es redirigirà al port 80 del pod Ingress. Anar a http://localhost:3000, hauríeu de veure la pàgina generada per l'aplicació.
Resum per ports
Recordem de nou quins ports i etiquetes han de coincidir:
El selector de la definició del servei ha de coincidir amb l'etiqueta del pod;
targetPort a la definició del servei ha de coincidir containerPort un recipient dins d'una beina;
port a la definició del servei pot ser qualsevol cosa. Diferents serveis poden utilitzar el mateix port perquè tenen diferents adreces IP;
servicePort L'entrada ha de coincidir port en la definició del servei;
El nom del servei ha de coincidir amb el camp serviceName a Ingress.
Per desgràcia, no n'hi ha prou amb saber estructurar correctament una configuració YAML.
Què passa quan alguna cosa va malament?
És possible que el pod no s'iniciï o que s'estigui bloquejant.
3 passos per resoldre problemes d'aplicacions a Kubernetes
Abans de començar a depurar la vostra implementació, heu de tenir una bona comprensió de com funciona Kubernetes.
Com que hi ha tres components a cada aplicació baixada a K8s, depureu-los en un ordre determinat, començant per la part inferior.
Primer heu d'assegurar-vos que les beines funcionen, després...
Comproveu si el servei està enviant trànsit als pods i, a continuació...
Comproveu si Ingress està configurat correctament.
Representació visual:
1) Comenceu a buscar problemes des de baix. Primer comproveu que les beines tenen estats Ready и Running:
2) Si les beines estan a punt (Ready), hauríeu d'esbrinar si el servei distribueix el trànsit entre pods:
3) Finalment, cal analitzar la connexió entre el servei i Ingress:
1. Diagnòstic de pods
En la majoria dels casos, el problema està relacionat amb la beina. Assegureu-vos que les beines figuren com a Ready и Running. Podeu comprovar-ho amb l'ordre:
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
A la sortida de l'ordre anterior, l'últim pod apareix com a Running и Ready, però aquest no és el cas dels altres dos.
Com entendre què va fallar?
Hi ha quatre ordres útils per diagnosticar pods:
kubectl logs <имя pod'а> permet extreure registres dels contenidors d'una beina;
kubectl describe pod <имя pod'а> us permet veure la llista d'esdeveniments associats al pod;
kubectl get pod <имя pod'а> us permet obtenir la configuració YAML d'un pod emmagatzemat a Kubernetes;
kubectl exec -ti <имя pod'а> bash us permet executar un intèrpret d'ordres interactiu en un dels contenidors del pod
Quina triar?
El fet és que no hi ha cap comandament universal. S'ha d'utilitzar una combinació d'ells.
Problemes comuns de les beines
Hi ha dos tipus principals d'errors de pod: errors d'inici i errors d'execució.
Errors de llançament:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Errors en temps d'execució:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Alguns errors són més comuns que d'altres. Aquests són alguns dels errors més comuns i com solucionar-los.
ImagePullBackOff
Aquest error es produeix quan Kubernetes no pot obtenir una imatge per a un dels contenidors del pod. Aquests són els tres motius més habituals per a això:
El nom de la imatge és incorrecte; per exemple, us heu equivocat o la imatge no existeix;
S'ha especificat una etiqueta no vàlida per a la imatge;
La imatge s'emmagatzema en un registre privat i Kubernetes no té permís per accedir-hi.
Els dos primers motius són fàcils de solucionar: només cal que arregleu el nom i l'etiqueta de la imatge. En el cas d'aquest últim, cal introduir les credencials del registre privat a Secret i afegir-hi enllaços en pods. A la documentació de Kubernetes hi ha un exemple com es pot fer.
Desactiva el bucle de bloqueig
Kubenetes llança un error CrashLoopBackOffsi el contenidor no pot arrencar. Això sol passar quan:
L'aplicació té un error que impedeix que s'executi;
Cal intentar arribar als registres des del contenidor per esbrinar el motiu del seu fracàs. Si és difícil accedir als registres perquè el contenidor es reinicia massa ràpidament, podeu utilitzar l'ordre següent:
kubectl logs <pod-name> --previous
Imprimeix missatges d'error de la reencarnació anterior del contenidor.
RunContainerError
Aquest error es produeix quan el contenidor no es pot iniciar. Correspon al moment anterior a l'inici de la sol·licitud. Normalment es deu a una configuració incorrecta, com ara:
intentant muntar un volum inexistent com ara ConfigMap o Secrets;
intentant muntar un volum de només lectura com a lectura-escriptura.
L'ordre és molt adequat per analitzar aquests errors. kubectl describe pod <pod-name>.
Beines a l'estat Pendent
Després de la creació, la beina roman a l'estat Pending.
Per què passa això?
Aquestes són les possibles causes (suposo que el programador funciona bé):
El clúster no té prou recursos, com ara la potència de processament i la memòria, per executar el pod.
S'estableix un objecte a l'espai de noms adequat ResourceQuota i crear un pod farà que l'espai de noms surti de la quota.
Pod lligat a Pendent PersistentVolumeClaim.
En aquest cas, es recomana utilitzar l'ordre kubectl describe i la secció de comprovació Events:
kubectl describe pod <pod name>
En cas d'errors relacionats amb ResourceQuotas, es recomana veure els registres del clúster mitjançant l'ordre
kubectl get events --sort-by=.metadata.creationTimestamp
Les beines no estan a punt
Si pod apareix com a Running, però no és a l'estat Ready, significa comprovar la seva disposició (sonda de preparació) falla.
Quan això passa, el pod no es connecta al servei i no s'hi envia trànsit. El fracàs de la prova de preparació és causat per problemes en l'aplicació. En aquest cas, per trobar l'error, cal analitzar la secció Events a la sortida d'ordres kubectl describe.
2. Diagnòstic del servei
Si les beines apareixen com a Running и Ready, però encara no hi ha resposta de l'aplicació, hauríeu de comprovar la configuració del servei.
Els serveis es dediquen a dirigir el trànsit als pods en funció de les seves etiquetes. Per tant, el primer que cal fer és comprovar quants pods funcionen amb el servei. Per fer-ho, podeu comprovar els punts finals del servei:
kubectl describe service <service-name> | grep Endpoints
El punt final és un parell de valors del formulari <IP-адрес:порт>, i almenys un d'aquests parells ha d'estar present a la sortida (és a dir, almenys un pod està treballant amb el servei).
Si secció Endpoins buit, hi ha dues opcions:
no hi ha pods amb l'etiqueta correcta (suggeriment: comproveu si l'espai de noms és correcte);
hi ha un error a les etiquetes del servei del selector.
Si veieu una llista de punts finals però encara no podeu accedir a l'aplicació, el culpable probable és un error targetPort a la descripció del servei.
Com comprovar si el servei funciona?
Independentment del tipus de servei, podeu utilitzar l'ordre kubectl port-forward per connectar-hi:
el servei distribueix amb èxit el trànsit entre pods.
Tanmateix, encara no podeu "accedir" a l'aplicació.
Això vol dir que el controlador Ingress probablement està mal configurat. Com que el controlador Ingress és un component de tercers del clúster, hi ha diferents mètodes de depuració segons el seu tipus.
Però abans de recórrer a l'ajuda d'eines especials per configurar Ingress'a, podeu fer una cosa molt senzilla. Usos d'entrada serviceName и servicePort per connectar-se al servei. Cal comprovar si estan configurats correctament. Podeu fer-ho amb l'ordre:
kubectl describe ingress <ingress-name>
Si columna Backend està buit, hi ha una alta probabilitat d'error de configuració. Si els backend estan al seu lloc, però l'aplicació encara no és accessible, el problema pot estar relacionat amb:
Entra a la configuració d'accessibilitat des d'Internet pública;
Configuració d'accessibilitat del clúster des d'Internet pública.
Podeu identificar problemes amb la infraestructura connectant-vos directament al pod Ingress. Per fer-ho, primer cerqueu el pod del controlador Ingress (pot estar en un espai de noms diferent):
Ara totes les sol·licituds del port 3000 de l'ordinador es redirigiran al port 80 del pod.
Funciona ara?
Si és així, el problema és la infraestructura. Cal esbrinar exactament com s'encamina el trànsit al clúster.
Si no, el problema és amb el controlador d'entrada.
Si no podeu fer que el controlador Ingress funcioni, haureu de depurar-lo.
Hi ha moltes varietats de controladors d'entrada. Els més populars són Nginx, HAProxy, Traefik, etc. (per obtenir més informació sobre les solucions existents, vegeu la nostra ressenya -aprox. trad.) Consulteu la guia de resolució de problemes a la documentació del controlador adequat. Perquè el Entrada Nginx és el controlador d'entrada més popular, hem inclòs alguns consells sobre com tractar-lo en aquest article.
Depuració d'un controlador d'entrada Nginx
El projecte Ingress-nginx té un oficial connector per a kubectl. equip kubectl ingress-nginx es pot utilitzar per a:
anàlisi de registres, backends, certificats, etc.;
connexió amb Ingress'u;
examinant la configuració actual.
Les tres ordres següents us ajudaran amb això:
kubectl ingress-nginx lint - xecs nginx.conf;
kubectl ingress-nginx backend - explora el backend (similar a kubectl describe ingress <ingress-name>);
kubectl ingress-nginx logs - Comprova els registres.
Tingueu en compte que, en alguns casos, pot ser necessari especificar l'espai de noms correcte per al controlador Ingress mitjançant el senyalador --namespace <name>.
Resum
La resolució de problemes de Kubernetes pot ser complicat si no sabeu per on començar. El problema sempre s'ha d'abordar des de baix cap amunt: començar amb pods, i després passar al servei i Ingress. Els mètodes de depuració descrits a l'article es poden aplicar a altres objectes, com ara: