Kuberenetes debuggen
Debuggen adhv logs
Het analyseren van logs in Kubernetes is essentieel voor het debuggen van applicaties, het bewaken van de prestaties, en het oplossen van problemen. Kubernetes biedt verschillende manieren om logs te verzamelen en te analyseren, van individuele pods tot gedistribueerde systemen. In Kubernetes draaien containers binnen pods. Elk container genereert logs die je kunt raadplegen om te zien wat er gebeurt binnen die container. Kubernetes biedt kubectl-commando's om logs van containers te bekijken.
Pod logs
Met het kubectl logs commando kun je de logs van een specifieke pod ophalen. Dit is handig als je wilt weten wat er binnen de containers die op deze pod draaien gebeurt.
Als je bijvoorbeeld de logs van een pod genaamd nginx-pod wilt bekijken:
kubectl logs nginx-pod
Herinner je dat je met kubectl get pods altijd een overzicht krijgt van de pods die binnen de cluster draaien. Hier vindt je ook de naam terug van al je pods.
Container logs
Een pod kan meerdere containers bevatten. Om de logs van een specifieke container binnen een pod te bekijken, kun je de naam van de container meegeven.
Voorbeeld:
kubectl logs <pod-naam> -c <container-naam>
Als een pod nginx-pod meerdere containers draait, onder andere een container met de naam nginx, kun je de logs van de nginx container bekijken met het volgende commando:
kubectl logs nginx-pod -c nginx
Meerdere pods
Als je logs wilt bekijken van meerdere pods die dezelfde labels hebben (bijvoorbeeld alle pods van een bepaalde applicatie), kun je een label-selector gebruiken.
Voorbeeld:
kubectl logs -l app=nginx
Dit toont de logs van alle pods die het label app=nginx hebben. Dit label kan ingesteld worden in de configuratie file.
Beperkt aantal log regels
Gebruik de --tail vlag om alleen de laatste X regels van de logs te zien:
Voorbeeld:
kubectl logs nginx-pod --tail=100
Dit toont de laatste 100 regels van de logs van de nginx-pod.
Real-time logs volgen
Je kunt logs in real-time volgen met de -f (follow) vlag. Dit is handig wanneer je de pod in de gaten wilt houden terwijl er bepaalde acties worden uitgevoerd. Bijvoorbeeld, stel dat er in je pod een webserver draait en je wilt debuggen wat er gebeurt wanneer bepaalde REST calls binnenkomen op de server.
Voorbeeld:
kubectl logs -f nginx-pod
Dit toont de logs van de nginx-pod en blijft doorgaan met het volgen van nieuwe logregels die binnenkomen.
Logs van eerdere pods bekijken
Als een pod opnieuw is opgestart (bijvoorbeeld na een crash), kun je de logs van de vorige containerinstantie bekijken door de --previous vlag te gebruiken.
Voorbeeld:
kubectl logs nginx-pod --previous
Dit toont de logs van de vorige container in de nginx-pod, als die er is.
Logs van Alle Pods in een Namespace
Als je de logs van alle pods in een specifieke namespace wilt bekijken, kun je het volgende commando gebruiken:
kubectl logs -n <namespace> --all-containers=true
Dit toont de logs van alle containers in de opgegeven namespace. De --all-containers=true vlag toont logs van alle containers binnen elke pod.
Kubernetes Logs Opslag en Aggregatie
In productieomgevingen kunnen logs van meerdere pods en containers snel een aanzienlijke hoeveelheid data genereren. Daarom is het vaak handig om logs te centraliseren en te aggregeren. Er zijn verschillende manieren om logs op te slaan en te analyseren in Kubernetes:
Gebruik van loggers zoals Fluentd, Logstash en Filebeat
Fluentd, Logstash, en Filebeat zijn veelgebruikte log-collectoren die je kunt integreren in Kubernetes. Ze verzamelen logs van verschillende pods en sturen deze naar een centraal systeem voor opslag en analyse (bijvoorbeeld Elasticsearch, Kibana, Splunk, enz.).
De ELK Stack
De ELK Stack (Elasticsearch, Logstash, Kibana) wordt vaak gebruikt voor logaggregatie. Logstash verzamelt de logs van verschillende bronnen, Elasticsearch slaat ze op en Kibana biedt een krachtige interface om ze te doorzoeken en te visualiseren.
Gebruik van een cloud-gebaseerde logoplossing
Veel cloudproviders bieden logverwerkingsservices aan, zoals:
- AWS CloudWatch Logs
- Google Cloud Logging
- Azure Monitor Logs
Deze diensten kunnen logs van je Kubernetes-cluster verzamelen, opslaan en doorzoeken zonder dat je een eigen loggingsysteem hoeft in te stellen.
Kubernetes Events Bekijken
Naast containerlogs kun je ook Kubernetes Events bekijken. Events zijn berichten die aangeven wat er in je cluster gebeurt, zoals wanneer een pod wordt gemaakt, wanneer een container crasht, of wanneer een pod uit een node wordt verwijderd.
Voorbeeld:
kubectl get events
Je kunt ook meer gedetailleerde informatie verkrijgen door specifieke velden toe te voegen aan je zoekopdracht, zoals:
kubectl get events --sort-by='.lastTimestamp'
Dit sorteert de evenementen op basis van de laatst geregistreerde gebeurtenis.
Kubernetes Audit Logs
Audit logs bieden gedetailleerde informatie over welke acties gebruikers en systeemcomponenten in het Kubernetes-cluster hebben uitgevoerd. Deze logs bevatten informatie over wie wat heeft gedaan (bijvoorbeeld welke API-aanroepen zijn gedaan).
Audit logs kunnen worden geconfigureerd en opgeslagen in een bestand of naar een externe logverwerker worden gestuurd voor analyse. Je kunt audit logging inschakelen in Kubernetes door de --audit-log-path vlag in de kube-apiserver-configuratie te gebruiken.
Troubleshooting van Pods
Wanneer je problemen ondervindt met een Pod in Kubernetes, zijn er verschillende troubleshooting-tools en -commando's die je kunt gebruiken om de oorzaak van het probleem te achterhalen. Twee van de belangrijkste commando's voor het oplossen van problemen zijn kubectl describe pod en kubectl exec. Hieronder geef ik uitleg over hoe je deze commando's kunt gebruiken voor het oplossen van problemen.
kubectl describe pod
Het kubectl describe commando geeft gedetailleerde informatie over de status van een Pod en de bijbehorende resources. Het helpt je om snel inzicht te krijgen in de pod, zoals foutmeldingen, containerspecificaties, events, en meer.
kubectl describe pod <pod-naam> -n <namespace>
<pod-naam>: De naam van de Pod die je wilt onderzoeken.-n <namespace>: De namespace waarin de Pod zich bevindt (optioneel, je gebruikt namespace als de Pod niet in de standaard namespace staat).
Dit commando toont gedetailleerde informatie, waaronder:
- Pod-informatie: zoals naam, namespace, labels, en annotaties.
- Status van containers: of de containers running, waiting of terminated zijn, samen met foutcodes als een container faalt.
- Events: Systematische berichten over de status van de Pod, zoals pod-migraties, foutsituaties of crashes.
Wat kun je hieruit halen:
- De status van de container (bijvoorbeeld
Running,Ready: True). - De events die kunnen aangeven waarom een container misschien niet goed werkt (bijvoorbeeld
Failed,CrashLoopBackOff, etc.). - Volume-informatie, die je kan helpen als de pod afhankelijk is van volumes die mogelijk niet goed zijn gekoppeld.
- Foutcodes en exit status van containers kunnen je helpen om de reden voor een crash of probleem te vinden.
Typische foutmeldingen die je kunt zien in de output van kubectl describe pod:
- CrashLoopBackOff: Dit betekent dat de container herhaaldelijk is gestopt en opnieuw is opgestart vanwege een fout.
- ImagePullBackOff: Kubernetes kan het Docker-image niet ophalen.
- ErrImagePull: Er is een probleem bij het ophalen van het containerimage.
- OOMKilled: De container is beëindigd omdat deze te veel geheugen heeft verbruikt (Out of Memory).
kubectl exec
kubectl exec is een krachtig commando waarmee je interactie kunt hebben met een container binnen een pod, bijvoorbeeld door toegang te krijgen tot een shell (zoals bash of sh) om de container van binnenuit te inspecteren.
kubectl exec -it <pod-naam> -n <namespace> -- <commando>
-it: Dit geeft aan dat je interactieve toegang wilt krijgen tot de container (voor bijvoorbeeld een shell).<pod-naam>: De naam van de pod waarmee je verbinding wilt maken.<namespace>: De namespace waarin de pod zich bevindt (optioneel).<commando>: Het commando dat je binnen de container wilt uitvoeren. Bijvoorbeeld een shell (bashofsh),lsom bestanden te bekijken, ofpsom de processen te inspecteren.
Praktijkvoorbeelden
Probleem met de container die niet opstart (CrashLoopBackOff):
- Oplossing: Bekijk de logs van de container met
kubectl logs <pod-naam>om te zien wat er misgaat. Gebruik vervolgenskubectl describe pod <pod-naam>om meer te weten te komen over de foutstatus of mogelijke configuratieproblemen. - Je kunt ook
kubectl execgebruiken om de container te inspecteren en de configuratie of bestanden te controleren.
Probleem met het ophalen van een image (ImagePullBackOff):
- Oplossing: Controleer of de containerimage beschikbaar is en dat de juiste toegangsmachtigingen en credentials voor private registries correct zijn ingesteld. Je kunt dit controleren met
kubectl describe pod <pod-naam>om te zien waarom het image niet kan worden opgehaald.
Netwerkproblemen:
- Oplossing: Gebruik
kubectl exec -it <pod-naam> -- ping <ip-adres>om netwerkverbindingen binnen de container te testen en te verifiëren of de Pod het netwerk bereikt.
Problemen met volume-mounts:
- Oplossing: Gebruik
kubectl describe podom te controleren of de juiste volumes en mounts correct zijn toegewezen. Als je toegang hebt tot de container viakubectl exec, kun je controleren of de bestanden op het volume juist beschikbaar zijn.
Monitoren van containergezondheid met Liveness en Readiness Probes
Het monitoren van de gezondheid van containers is een essentieel onderdeel van het beheer van applicaties in een Kubernetes-cluster. Kubernetes biedt mechanismen om automatisch te controleren of containers goed functioneren. Dit gebeurt via Liveness Probes en Readiness Probes. Deze probes helpen Kubernetes te begrijpen wanneer een container opnieuw gestart moet worden of wanneer deze klaar is om verkeer te ontvangen.
Liveness Probe
De Liveness Probe controleert of een container nog steeds actief en gezond is. Als de Liveness Probe faalt, betekent dit dat de container mogelijk vastzit in een onherstelbare toestand (bijvoorbeeld door een deadlock) en moet worden herstart. Kubernetes zal dan de container opnieuw starten om het probleem op te lossen.
Voorbeeld:
Je kunt een Liveness Probe instellen met een HTTP GET, TCP Socket of een exec-commando.
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 5
failureThreshold: 3
In dit voorbeeld:
- De Liveness Probe maakt elke 5 seconden een HTTP GET verzoek naar
/healthzop poort 8080 van de container. - Als de container 3 keer achter elkaar faalt (failureThreshold), wordt de container opnieuw gestart.
initialDelaySecondsbepaalt hoe lang Kubernetes moet wachten nadat de container is gestart voordat de eerste controle wordt uitgevoerd.
Readiness Probe
De Readiness Probe controleert of een container klaar is om verkeer te ontvangen. Als de container niet "klaar" is, betekent dit dat de container bijvoorbeeld bezig is met initialisatie of dat er een tijdelijke fout is. Kubernetes zal dan voorkomen dat er verkeer naar de container wordt geleid totdat de Readiness Probe slaagt.
Voorbeeld:
Een Readiness Probe kan ook een HTTP GET, TCP Socket of exec commando zijn.
readinessProbe:
httpGet:
path: /readiness
port: 8080
initialDelaySeconds: 5 # Wacht 5 seconden na containerstart
periodSeconds: 10 # Voer elke 10 seconden de check uit
failureThreshold: 3 # Na 3 mislukte pogingen, beschouwen als niet klaar
In dit voorbeeld:
- De Readiness Probe maakt een HTTP GET verzoek naar
/readinessop poort 8080. - De container wordt als niet klaar beschouwd totdat de probe succesvol is.
initialDelaySecondsenfailureThresholdzijn vergelijkbaar met de Liveness Probe.
Verschil tussen Liveness en Readiness Probes
| Eigenschap | Liveness Probe | Readiness Probe |
|---|---|---|
| Doel | Detecteert vastgelopen containers en forceert herstart. | Controleert of een container klaar is om verkeer te ontvangen. |
| Herstart bij mislukking | Ja, herstart de container bij mislukking. | Nee, voorkomt dat verkeer naar de container wordt gestuurd. |
| Gebruik | Gebruik voor containers die vast kunnen lopen (bijvoorbeeld door deadlocks). | Gebruik wanneer de container tijd nodig heeft om op te starten of externe afhankelijkheden heeft. |
| Foutgedrag | Container wordt herstart als probe faalt. | Verkeer wordt niet naar de container gestuurd totdat de probe slaagt. |
Type Probes: HTTP, TCP, Exec
Kubernetes ondersteunt drie typen probes:
HTTP GET Probe
Deze probe maakt een HTTP GET-verzoek naar een opgegeven pad en poort van de container. Als de HTTP-statuscode van het antwoord tussen 200 en 399 ligt, wordt de probe als geslaagd beschouwd.
Voorbeeld:
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
TCP Socket Probe
De probe maakt verbinding via een TCP-socket naar de opgegeven poort. Als de verbinding kan worden gemaakt, wordt de probe als geslaagd beschouwd.
Voorbeeld:
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
Exec Probe
Deze probe voert een commando uit binnen de container. Als het commando succesvol is (exit-status 0), wordt de probe als geslaagd beschouwd.
Voorbeeld:
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
In dit voorbeeld controleert Kubernetes of het bestand /tmp/healthy bestaat.
Best Practices voor Probes
- Gebruik een
/healthzendpoint: Voor HTTP GET probes kun je een dedicated healthcheck-endpoint zoals/healthzgebruiken, zodat het niet afhankelijk is van de eigenlijke applicatielogica. - Stel een
initialDelaySecondsin: Vermijd dat de probes onmiddellijk worden uitgevoerd bij de eerste containerstart. Stel een korte vertraging in om te voorkomen dat je probe faalt voordat de applicatie klaar is. - Gebruik verschillende endpoints voor liveness en readiness: Een container kan bijvoorbeeld klaar zijn om verkeer te ontvangen, maar nog niet in staat zijn om dat verkeer goed te verwerken. Zorg ervoor dat je verschillende endpoints hebt voor liveness en readiness om duidelijk het verschil aan te geven.
Voorbeeld van een Pod-configuratie met Probes
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
containers:
- name: my-app-container
image: my-app-image
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
Problemen met containers oplossen
Bij het werken met containers in Kubernetes kunnen zich verschillende veelvoorkomende problemen voordoen. Het is belangrijk om te begrijpen hoe je deze kunt diagnosticeren en oplossen. Hieronder bespreken we enkele van de meest voorkomende problemen, zoals image pull errors, resource limits en andere veelvoorkomende fouten, en hoe je ze kunt oplossen.
Image Pull Errors
Een veelvoorkomend probleem is wanneer Kubernetes een containerimage niet kan ophalen, wat kan leiden tot ImagePullBackOff of ErrImagePull foutmeldingen.
Oorzaken van Image Pull Errors:
- Verkeerde image naam of tag: De opgegeven image naam of tag is onjuist.
- Image is niet beschikbaar in de registry: De image bestaat niet in de opgegeven registry.
- Authenticatieproblemen bij private registries: Kubernetes heeft geen toegang tot de private container registry.
- Problemen met netwerkverbindingen: Het netwerk heeft geen toegang tot de container registry.
Diagnose:
-
Controleer de foutmelding: Gebruik het
kubectl describe podcommando om de foutmelding te inspecteren. Bijvoorbeeld:kubectl describe pod <pod-naam>Je zult waarschijnlijk een foutmelding zien zoals:
Failed to pull image "myrepo/myimage:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for myrepo/myimage, repository does not exist or may require 'docker login' -
Controleer of de image beschikbaar is: Zorg ervoor dat de image bestaat en dat je de juiste naam en tag gebruikt. Als je gebruik maakt van een private registry, controleer dan of de juiste authenticatiegegevens zijn geconfigureerd.
kubectl get secretsAls je de juiste Docker registry credentials nog niet hebt toegevoegd, kun je dit doen door een secret toe te voegen:
kubectl create secret docker-registry my-registry-secret \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<email> -
Controleer netwerkconnectiviteit: Zorg ervoor dat de Kubernetes nodes toegang hebben tot de container registry, vooral als je een externe registry gebruikt.
Oplossingen:
- Corrigeer de image naam of tag: Zorg ervoor dat de naam van de containerimage correct is en dat de juiste versie wordt gebruikt.
- Zorg voor toegang tot private registries: Voeg de juiste Docker-registry credentials toe aan Kubernetes via een secret, zoals hierboven beschreven.
- Controleer de netwerkverbinding: Zorg ervoor dat de Kubernetes-cluster toegang heeft tot de registry via internet of binnen je bedrijfsnetwerk.
Resource Limit Errors (Resource Requests & Limits)
Als een pod of container meer bronnen nodig heeft dan beschikbaar zijn, kunnen er verschillende problemen optreden, zoals OOMKilled (Out Of Memory) of insufficient resources fouten. Dit gebeurt wanneer een container meer geheugen of CPU nodig heeft dan er beschikbaar is in de node.
Oorzaken van Resource Issues:
- Niet genoeg resources op de node: De node heeft niet genoeg CPU of geheugen om de pod te draaien.
- Te strikte resource requests/limits: De opgegeven resource requests of limits kunnen te streng zijn voor de beschikbare resources in het cluster.
- Container heeft te veel resources nodig: De container verbruikt onterecht te veel geheugen of CPU.
Diagnose:
-
Inspecteer de Pod-status: Gebruik het
kubectl describe podcommando om te controleren op resource gerelateerde foutmeldingen.kubectl describe pod <pod-naam>Zoek naar meldingen zoals:
- OOMKilled: Dit geeft aan dat de container is gestopt omdat het meer geheugen gebruikte dan opgegeven in de limieten.
- Insufficient CPU/Memory: Dit betekent dat er niet genoeg resources beschikbaar zijn om de pod te draaien.
-
Controleer de Pod logs: Als de pod crasht door een OOMKilled fout, controleer dan de logs om te zien wat er gebeurde voordat de container werd beëindigd.
kubectl logs <pod-naam>Je kunt ook logs per container opvragen als er meerdere containers binnen een pod draaien:
kubectl logs <pod-naam> -c <container-naam> -
Controleer de requests en limits: Bekijk de
resourcessectie in de pod-configuratie om te zien wat de requests en limits voor CPU en geheugen zijn.resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Oplossingen:
-
Verhoog de resource limieten: Als je merkt dat de container meer geheugen of CPU nodig heeft, verhoog dan de limits en requests in de configuratie.
resources:
requests:
memory: "128Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "1" -
Verlaag de resource limieten: Als je merkt dat de container meer resources vraagt dan de node kan leveren, probeer dan de limieten te verlagen en kijk of de applicatie nog steeds goed functioneert.
-
Controleer node capaciteit: Als er te weinig resources zijn op de nodes, kun je proberen extra nodes toe te voegen of de pod te schedulen naar een node met voldoende resources. Dit kan met node affinities of taints and tolerations.
CrashLoopBackOff
Een andere veelvoorkomende fout is CrashLoopBackOff, wat betekent dat de container niet goed opstart en herhaaldelijk crasht.
Oorzaken van CrashLoopBackOff:
- Fout in de applicatie: De applicatie in de container kan crashen bij opstarten, bijvoorbeeld door misconfiguraties of afhankelijkheden die ontbreken.
- Onjuiste omgeving: De container mist de benodigde configuraties of secrets.
- Te snelle herstartpogingen: Kubernetes probeert de container herhaaldelijk opnieuw te starten, maar het lukt niet.
Diagnose:
-
Bekijk de logs van de container: Gebruik
kubectl logsom de logoutput van de container te bekijken:kubectl logs <pod-naam> -c <container-naam> -
Controleer de liveness en readiness probes: Als je Liveness of Readiness Probes hebt geconfigureerd, controleer dan of deze correct zijn ingesteld. Als de probe verkeerd is ingesteld, kan het leiden tot herhaalde herstartpogingen.
-
Inspecteer de Pod-events: Bekijk de events van de pod om te zien waarom de container crasht:
kubectl describe pod <pod-naam>
Oplossingen:
- Controleer applicatiefouten: Zorg ervoor dat de applicatie goed geconfigureerd is en geen kritieke fouten bevat die de container doen crashen.
- Controleer environment variables of secrets: Als de container afhankelijk is van omgevingsvariabelen of secrets, zorg er dan voor dat deze correct zijn geconfigureerd.
- Herstartbeleid aanpassen: Als de herstartpogingen te snel plaatsvinden, kun je de
restartPolicyaanpassen in de pod-configuratie om Kubernetes de tijd te geven om het probleem op te lossen.
No resources available
Dit probleem doet zich voor wanneer een pod niet kan starten omdat er onvoldoende resources (CPU/geheugen) beschikbaar zijn op de nodes in je cluster.
Oorzaken:
- Te veel resourceverbruik in het cluster, waardoor er geen capaciteit is voor nieuwe pods.
- Onvoldoende geconfigureerde requests voor de pod.
Diagnose
-
Controleer beschikbare resources op de nodes: Gebruik het
kubectl describe nodescommando om te zien hoeveel resources elke node beschikbaar heeft.kubectl describe nodes
Oplossingen:
-
Zorg voor voldoende resources: Verhoog de capaciteit van de cluster of verlaag de resourceverbruik van andere pods.
-
Verhoog de requests en limits voor je pod om Kubernetes te dwingen de pod op een node te plaatsen met voldoende resources.