Megjegyzés fordítás.: Ez a cikk a Kubernetes-tel kapcsolatos anyagok ingyenes elérhetőségű részét képezi. , amely a Kubernetes-szel való munkát tanítja a cégek és a független adminisztrátorok számára. Daniele Polencic, a projekt vezetője, egy áttekinthető útmutatót oszt meg arról, hogy milyen lépéseket érdemes tenni általános problémák felmerülésekor a K8s klaszterében futó alkalmazásokkal kapcsolatban.

TL;DR: itt egy séma, amely segít a Kubernetes telepítésének hibakeresésében:
Hibakeresési folyamatábra a klaszterben felmerülő problémákhoz. Az eredeti (angol nyelvű) elérhető itt: és .
Alkalmazás telepítésekor a Kubernetesben általában három komponenst kell definiálni:
- Deployment — ez egy recept az alkalmazás példányainak, úgynevezett pod-ok létrehozásához;
- Service — egy belső terheléselosztó, amely a forgalmat a pod-ok között osztja el;
- Ingress — annak leírása, hogy a forgalom hogyan jut el a külső világból a Szolgáltatáshoz.
Íme egy rövid grafikus összefoglaló:
1) A Kubernetesben az alkalmazások a külső világból két rétegű terheléselosztón keresztül kapják a forgalmat: belső és külső.

2) A belső terheléselosztót Szolgáltatásnak, a külsőt pedig Ingressnek hívják.

3) A telepítés létrehozza a pod-okat és figyelemmel kíséri azokat (azokat nem kézzel hozzák létre).

Tegyük fel, hogy szeretnél telepíteni egy egyszerű alkalmazást, például Hello World. A YAML konfigurációja a következőképpen néz ki:
apiVersion: apps/v1
kind: Deployment # <<<
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels:
any-name: my-app
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service # <<<
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
name: app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress # <<<
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: app
servicePort: 80
path: /A meghatározás meglehetősen hosszú, és könnyű összezavarodni abban, hogyan kapcsolódnak a komponensek egymáshoz.
Például:
- Mikor használjuk a 80-as portot, és mikor a 8080-asat?
- Minden szolgáltatás számára új portot kellene létrehozni, hogy elkerüljük a konfliktusokat?
- Fontosak a címkék nevei? Mindenhol azonosak kellene legyenek?
Mielőtt a hibakeresésre összpontosítanánk, emlékezzünk vissza, hogyan kapcsolódik a három komponens egymáshoz. Kezdjük a Telepítéssel és a Szolgáltatással.
A Telepítés és a Szolgáltatás kapcsolata
Meg fogsz lepődni, de a Telepítések és a Szolgáltatások nincsenek közvetlen kapcsolatban egymással. Ehelyett a Szolgáltatás közvetlenül a Pod-okhoz mutat, megkerülve a Telepítést.
Ezért az érdekel minket, hogy a Podok és Service-ek hogyan kapcsolódnak egymáshoz. Három dolgot érdemes megjegyezni:
- A szelektor (
selector) a Service esetében legalább egy Pod címkéjével meg kell egyezzen. -
targetPortmeg kell egyeznie acontainerPortértékével a Podon belüli konténerben. -
portA Service bármilyen portot használhat. Különböző szolgáltatások ugyanazt a portot használhatják, mivel különböző IP-címekkel rendelkeznek.
A következő ábra szemlélteti a fentiek mindegyikét grafikus formában:
1) Tegyük fel, hogy a szerviz forgalmat irányít egy Pod felé:

2) A pod létrehozásakor meg kell határozni containerPort minden konténerhez a podokban:

3) A szolgáltatás létrehozásakor meg kell adni port és targetPort. De melyiken keresztül csatlakozik a konténerhez?

4) A targetPortkapcsolaton keresztül. Ennek meg kell egyeznie a containerPort.

5) Tegyük fel, hogy a konténeren nyitva van a 3000-es port. Akkor az értéke targetPort ugyanannak kell lennie.

A YAML fájlban a címkéknek és a portok / targetPort szükséges, hogy egyezzenek:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels: # <<<
any-name: my-app # <<<
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080 # <<<
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080 # <<<
selector: # <<<
any-name: my-app # <<< Mi a helyzet a címkével track: canary a Deployment szekció felső részén? Egyeznie kell?
Ez a címke a telepítéshez tartozik, és a szerviz nem használja a forgalom irányítására. Más szavakkal, eltávolítható vagy más értéket rendelhetünk hozzá.
De mi a helyzet a szelektorral? matchLabels?
Mindig meg kell egyeznie a Pod címkéivel, mivel ezt a Deployment használja a Podok nyomon követésére.
Tegyük fel, hogy helyes módosításokat hajtott végre. Hogyan ellenőrizheti őket?
A Podok címkéjét a következő parancs segítségével ellenőrizheti:
kubectl get pods --show-labelsVagy ha a Podok több alkalmazás részei:
kubectl get pods --selector any-name=my-app --show-labels Ahol any-name=my-app — ez a címke any-name: my-app.
Maradt kérdése?
Csatlakozhat a Podhoz! Ehhez használja a parancsot port-forward a kubectl parancssorban. Ez lehetővé teszi a szolgáltatáshoz való csatlakozást és a kapcsolat ellenőrzését.
kubectl port-forward service/ 3000:80Itt:
-
service/— a szolgáltatás neve; ebben az esetben ezmy-service; - 3000 — az a port, amelyet meg kell nyitni a számítógépen;
- 80 — a szolgáltatás mezőjében megadott port.
portHa sikerült a kapcsolatot létrehozni, a beállítások helyesek.
Ha sikerült a kapcsolatot létrehozni, a beállítások helyesek.
Ha a kapcsolatot nem sikerült létrehozni, akkor a probléma a címkékben vagy a portok eltérésében rejlik.
A Service és az Ingress közötti kapcsolat
A következő lépés az alkalmazás elérhetőségének biztosításában az Ingress konfigurálásával kapcsolatos. Az Ingress-nek tudnia kell, hogyan található meg a szolgáltatás, majd meg kell találnia a pod-okat és forgalmat kell irányítania hozzájuk. Az Ingress a nevén és a nyitott portján keresztül találja meg a megfelelő szolgáltatást.
Az Ingress és a Service leírásában két paraméternek meg kell egyeznie:
-
servicePortaz Ingress-ben egyeznie kell a paraméterrelporta Service-ben; -
serviceNameaz Ingress-ben egyeznie kell a mezővelnamea Service-ben.
A következő ábra összefoglalja a portok csatlakoztatását:
1) Amint azt már tudod, a Service egy adott porton figyel. port:

2) Az Ingress-nek van egy paramétere, amelyet servicePort:

3) E paraméter (servicePort) mindig egyeznie kell a port Service definíciójában:

4) Ha a Service-ben a port 80 van megadva, akkor szükséges, hogy servicePort szintén 80 legyen:

A gyakorlatban figyelni kell a következő sorokra:
apiVersion: v1
kind: Service
metadata:
name: my-service # <<<
spec:
ports:
- port: 80 # <<<
targetPort: 8080
selector:
any-name: my-app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: my-service # <<<
servicePort: 80 # <<<
path: /Hogyan lehet ellenőrizni, hogy működik-e az Ingress?
Használhatjuk a módszert a kubectl port-forward, de a szolgáltatás helyett az Ingress vezérlőjéhez kell csatlakoznunk.
Először meg kell tudnunk az Ingress vezérlő podjának nevét:
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running Keresse meg az Ingress pod-ot (ez más névtérhez is tartozhat) és futtassa a parancsot describe, hogy megtudja a portszámokat:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCPVégül csatlakozzon a podhoz:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemMostantól, amikor kérdést indít a 3000-es porton a gépen, az a pod Ingress vezérlőjének 80-as portjára lesz átirányítva. Ha meglátogatja a , akkor látnia kell az alkalmazás által létrehozott oldalt.
Összefoglalás a portokkal kapcsolatban
Nézzük meg még egyszer, hogy mely portoknak és címkéknek kell egyezniük:
- A Service definíciójában található szelektornak meg kell egyeznie a pod címkéjével;
-
targetPorta Service definíciójának meg kell egyeznie acontainerPortpodon belüli konténerével; -
portA Service can be defined in many ways. Different services can use the same port since they have different IP addresses; -
servicePortThe Ingress must matchportin the Service definition; - The service name must match the field
serviceNamein the Ingress.
Unfortunately, it's not enough to know how to properly structure the YAML configuration.
What happens when something goes wrong?
The pod may not start or it might crash.
3 Steps to Diagnose Application Issues in Kubernetes
Before debugging the deployment, you need to have a good understanding of how Kubernetes works.
Since each application running in K8s contains three components, debugging should be done in a specific order, starting from the bottom.
- First, make sure the pods are running, then…
- Check if the service is delivering traffic to the pods, and then…
- Check if the Ingress is configured correctly.
Visual representation:
1) Start searching for issues from the bottom. First, check that the pods have statuses Kész és Futásban:

2) If the pods are ready (Kész), find out if the service is distributing traffic between the pods:

3) Finally, analyze the relationship between the service and the Ingress:

1. Pod Diagnostics
In most cases, the problem is related to the pod. Make sure the pods are listed as Kész és Futásban. You can check this with the command:
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 In the output of the command above, the last pod is listed as Futásban és Kész, but that's not the case for the other two.
How do you know what went wrong?
There are four useful commands for diagnosing pods:
-
kubectl logsallows you to extract logs from the containers in the pod; -
kubectl describe podlets you see a list of events related to the pod; -
kubectl get podallows you to get the YAML configuration of the pod stored in Kubernetes; -
kubectl exec -ti bashlets you run an interactive command shell in one of the pod's containers
Which one to choose?
The fact is, there is no universal command. You should use a combination of them.
Typical pod issues
There are two main types of pod errors: startup errors and runtime errors.
Startup errors:
-
ImagePullBackoff -
ImageInspectError -
ErrImagePull -
ErrImageNeverPull -
RegistryUnavailable -
Érvénytelen képfájl név
Futtatási hibák:
-
CrashLoopBackOff állapotban van. -
Futtatási konténer hiba -
Konténer leállítási hiba -
Nem gyökér ellenőrzési hiba -
Inicializáló konténer futtatási hiba -
Pod homokozó létrehozási hiba -
Pod homokozó konfigurálási hiba -
Pod homokozó leállítási hiba -
Néhány hiba gyakrabban fordul elő, mint mások. Íme néhány a leggyakoribb hibák közül, és az ezek orvoslására szolgáló módszerek. -
ImagePullBackOff
Ez a hiba akkor fordul elő, amikor a Kubernetes nem tudja letölteni a képet az egyik konténerhez a pod-ban. Íme a három leggyakoribb oka ennek:
Hibásan adtad meg a kép nevét – például hibáztál benne, vagy a kép nem létezik;
Nem létező címkét adtál meg a képhez;
- A kép egy privát tárolóban található, és a Kubernetesnek nincs jogosultsága hozzáférni hozzá.
- Az első két okot könnyű orvosolni – csak javítani kell a kép nevét és a címkét. Az utolsó esetben hozzáférési adatokat kell megadni a privát tárolóhoz a Secretben, és hivatkozásokat kell hozzáadni a podokhoz. A Kubernetes dokumentációjában
- van egy példa
arra, hogyan lehet ezt megtenni. , ha a konténer nem tud elindulni. Ez általában akkor fordul elő, ha:
CrashLoopBackOff állapotban van.
Hiba található az alkalmazásban, amely megakadályozza az elindulását; CrashLoopBackOff állapotban van.helytelenül van beállítva
- A Liveness teszt túl sokszor sikertelenül végződött.
- Konténer ;
- kubectl logs --previous
Ez megjeleníti a hibajelentéseket a konténer korábbi újraélesztéséből.
Ez a hiba akkor fordul elő, amikor a konténer nem képes elindulni. Ez a pillanat az alkalmazás elindítása előtt van. Általában a helytelen beállítás a hibája, például:nem létező kötet csatlakoztatására tett kísérlet, mint például ConfigMap vagy Secrets;
Futtatási konténer hiba
olyan kötetet próbálsz meg csatlakoztatni, amely read-only módban van, mint read-write.
- Az ilyen hibák elemzéséhez jól illeszkedik a parancs
- kubectl describe pod
A podok Pending állapotban vannak A létrehozás után a pod állapotban marad.
Miért történik ez?
Íme a lehetséges okok (azzal a feltevéssel élek, hogy az ütemező normálisan működik): Várakozik.
Nincs elegendő erőforrás, például számítási kapacitás és memória a pod elindításához a klaszterben.
Egy ResourceQuota objektumot állítottak be a megfelelő névtérben
- ResourceQuota
- В соответствующем пространстве имен установлен объект
ResourceQuotaés a pod létrehozása azt fogja eredményezni, hogy a névtér túllépi a kvótát. - A pod függőben van
PersistentVolumeClaim.
Ebben az esetben javasolt a következő parancs használata kubectl describe és ellenőrizni a szakaszt Események:
kubectl describe pod Hibák esetén, amelyek kapcsolódnak a ResourceQuotas, érdemes áttekinteni a klaszter naplóit a következő parancs segítségével
kubectl get events --sort-by=.metadata.creationTimestampA podok nem állnak Ready állapotban
Ha a pod úgy szerepel, mint Futásban, de nincs Ready állapotban Kész, akkor a készenléti ellenőrzés (készenléti próba) sikertelen.
Amikor ez megtörténik, a pod nem csatlakozik a szolgáltatáshoz, és nem érkezik rá forgalom. A készenléti teszt hibája az alkalmazásban rejlő problémákra utal. Ilyen esetben az hiba kereséséhez analizálni kell a szakaszt Események a parancs kimenetében kubectl describe.
2. Szolgáltatások diagnosztizálása
Ha a podok úgy szerepelnek, mint Futásban és Kész, de az alkalmazás válasza továbbra sincs, ellenőrizni kell a szolgáltatás beállításait.
A szolgáltatások a forgalmat a podokhoz irányítják a címkéik alapján. Ezért az első dolog, amit ellenőrizni kell, hogy hány pod működik a szolgáltatással. Ehhez ellenőrizheti a szolgáltatás végpontjait:
kubectl describe service | grep Endpoints A végpont egy típusú értékpár. <IP-адрес:порт>, és a kimenetben legalább egy ilyen párnak szerepelnie kell (azaz legalább egy pod működik a szolgáltatással).
Ha a szakasz Endpoins üres, két lehetőség van:
- nincs egyetlen pod sem, amely megfelelő címkével rendelkezik (tipp: ellenőrizze, hogy a névtér helyesen van-e megadva);
- hibás címkék vannak a szolgáltatás szelektorában.
Ha lát egy végpontok listáját, de továbbra sem tud hozzáférni az alkalmazáshoz, akkor valószínűleg a szolgáltatás leírásában van hiba. targetPort Hogyan ellenőrizheti a szolgáltatás működését?
A szolgáltatás típusától függetlenül az alábbi parancsot használhatja a csatlakozáshoz:
kubectl port-forward service/ 3000:80 kubectl port-forward для подключения к нему:
— a szolgáltatás neve;Itt:
-
3000 — a port, amelyet megnyit a számítógépen;80 — a port a szolgáltatás oldalán. - 3. Ingress diagnosztizálása
- Ha eddig eljutott, akkor:
a podok úgy szerepelnek, mint
a szolgáltatás sikeresen osztja el a forgalmat a podok között.
- Mindazonáltal továbbra sem tud hozzáférni az alkalmazáshoz.
FutásbanésKész; - Ez azt jelenti, hogy valószínűleg a Ingress vezérlő nincs megfelelően beállítva. Mivel a Ingress vezérlő külső összetevő a klaszterben, a hibakeresési módszerek típusa szerint eltérőek.
Однако вы по-прежнему не можете «достучаться» до приложения.
Это означает, что, скорее всего, неправильно настроен контроллер Ingress. Поскольку контроллер Ingress является сторонним компонентом в кластере, существуют различные методы отладки в зависимости от его типа.
De mielőtt speciális eszközökhöz folyamodnánk az Ingress konfigurálásához, lehet tenni valami nagyon egyszerűt. Az Ingress a következőhöz használható serviceName és servicePort szolgáltatáshoz való csatlakozáshoz. Ellenőrizni kell, hogy helyesen vannak-e beállítva. Ezt a következő parancs segítségével teheti meg:
kubectl describe ingress Ha az oszlop Backend üres, akkor nagy a valószínűsége a konfigurációs hibának. Ha a háttérszolgáltatások rendben vannak, de a művelethez továbbra sincs hozzáférés, akkor a probléma lehet:
- az Ingress nyilvános internetből elérhetőségének beállításaival;
- a klaszter nyilvános internetből való elérhetőségével.
Az infrastruktúrával kapcsolatos problémák az Ingress podhoz való közvetlen kapcsolódással is azonosíthatók. Ehhez először is meg kell találni az Ingress-vezérlő podot (ez lehet egy másik névtérben):
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running Használja a következő parancsot describe, hogy beállítsa a portot:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep PortsVégül csatlakozzon a podhoz:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemMostantól az összes 3000 portos kérés az eszközön a pod 80 portjára irányul.
Működik most?
- Ha igen, akkor az infrastruktúrával van probléma. Meg kell tudni, hogyan irányul a forgalom a klaszterbe.
- Ha nem, akkor a probléma az Ingress vezérlővel van.
Ha nem sikerül működésre bírni az Ingress vezérlőt, akkor azt hibakeresni kell.
Sokféle Ingress vezérlő létezik. A legnépszerűbbek a Nginx, HAProxy, Traefik stb. (további információ az elérhető megoldásokról lásd a — a fordító megjegyzése) Használja a megfelelő vezérlők dokumentációjában található hibakeresési útmutatót. Mivel a legnépszerűbb Ingress vezérlő, cikkünkhöz néhány tippet is hozzáadtunk a vele kapcsolatos problémák megoldásához.
Az Nginx Ingress vezérlő hibakeresése
Az Ingress-nginx projekthez van egy hivatalos A parancs kubectl ingress-nginx a következőkre használható:
- naplózás, háttérszolgáltatások, tanúsítványok stb. elemzése;
- csatlakozás az Ingress-hez;
- a jelenlegi konfiguráció megismerése.
Ehhez a következő három parancs segít:
-
kubectl ingress-nginx lint— ellenőrzinginx.conf; -
kubectl ingress-nginx backend— megvizsgálja a háttérszolgáltatást (analóg módon, mintkubectl describe ingress); -
kubectl ingress-nginx logs— ellenőrzi a naplókat.
Figyelem: egyes esetekben szükség lehet a megfelelő névtér megadására az Ingress vezérlő számára a --namespace zászló használatával.
Összefoglaló
A Kubernetes hibaelhárítás nem egyszerű feladat, ha nem tudjuk, hol kezdjük. A problémát mindig az „alulról felfelé” elv alapján kell megközelíteni: kezdje a pod-okkal, majd lépjen át a szolgáltatásra és az Ingress-re. A cikkben leírt hibakeresési módszerek más objektumokra is alkalmazhatók, mint például:
- nem működő Job-ok és CronJob-ok;
- StatefulSet-ek és DaemonSet-ek.
Köszönetet mondok , és a hasznos megjegyzésekért és kiegészítésekért.
Fejlesztési eszközök, amelyek Kubernetesben futnak
Olvasson további információkat a blogunkban:
- «»;
- «»;
- «»;
- «».
Forrás: habr.com
