CKA · Módulo 10 K8s v1.34 Troubleshooting 30%

Cuando lo roto es el cluster, no la app

When what is broken is the cluster, not the app

Quando il rotto è il cluster, non l'app

Acá se acaba kubectl. Un nodo NotReady o un control plane caído se arregla por SSH, mirando systemd, los manifiestos estáticos y el runtime de containers. Es el módulo más "Linux" de todo el CKA.

This is where kubectl runs out. A NotReady node or a downed control plane is fixed over SSH, looking at systemd, the static manifests and the container runtime. It is the most "Linux" module in the whole CKA.

Qui finisce kubectl. Un nodo NotReady o un control plane caduto si sistema via SSH, guardando systemd, i manifest statici e il runtime dei container. È il modulo più "Linux" di tutto il CKA.

Duración75 min
Duration75 min
Durata75 min
DominioTroubleshooting
DomainTroubleshooting
DominioTroubleshooting
Peso30% (2 de 3)
Weight30% (2 of 3)
Peso30% (2 di 3)
RequiereM1 (kubeadm) · M9
RequiresM1 (kubeadm) · M9
RichiedeM1 (kubeadm) · M9
El M9 asumía un cluster sano con una app rota. Acá se invierte: el cluster es el paciente. Y el cambio de escenario trae un cambio de herramientas — si el kube-apiserver está caído, kubectl no responde y te quedan systemctl, journalctl y crictl. Lo bueno es que las causas son pocas y muy repetidas: el kubelet parado, un manifiesto estático mal editado, un certificado vencido, etcd sin espacio. En el examen esto se ve como "el nodo X está NotReady, arreglalo" — y hay una secuencia fija que resuelve casi todos los casos.
M9 assumed a healthy cluster with a broken app. Here it flips: the cluster is the patient. And the change of scene brings a change of tools — if the kube-apiserver is down, kubectl does not answer and you are left with systemctl, journalctl and crictl. The good news is the causes are few and highly repetitive: a stopped kubelet, a badly edited static manifest, an expired certificate, etcd out of space. In the exam this shows up as "node X is NotReady, fix it" — and there is a fixed sequence that solves almost every case.
Il M9 dava per scontato un cluster sano con un'app rotta. Qui si ribalta: il cluster è il paziente. E il cambio di scenario porta un cambio di strumenti — se il kube-apiserver è caduto, kubectl non risponde e ti restano systemctl, journalctl e crictl. Il bello è che le cause sono poche e molto ripetitive: il kubelet fermo, un manifest statico modificato male, un certificato scaduto, etcd senza spazio. All'esame appare come "il nodo X è NotReady, sistemalo" — e c'è una sequenza fissa che risolve quasi tutti i casi.
Modelo mental del módulo
Module's mental model
Modello mentale del modulo
¿Responde kubectl?  NO → control plane  ·  SÍ → kubelet del nodo
Does kubectl answer?  NO → control plane  ·  YES → that node's kubelet
Risponde kubectl?  NO → control plane  ·  SÌ → kubelet del nodo
Esa es la primera bifurcación y la que ordena todo el módulo. Si la API no contesta, el problema está en el control plane y se diagnostica en el master con crictl y los manifiestos de /etc/kubernetes/manifests/. Si la API contesta pero un nodo figura NotReady, el problema está en ese nodo: kubelet, runtime o CNI. Nunca empieces sin responder esa pregunta.
That is the first fork and the one that orders the whole module. If the API does not answer, the problem is in the control plane and is diagnosed on the master with crictl and the manifests in /etc/kubernetes/manifests/. If the API answers but a node shows NotReady, the problem is on that node: kubelet, runtime or CNI. Never start without answering that question.
Questa è la prima biforcazione e quella che ordina tutto il modulo. Se l'API non risponde, il problema è nel control plane e si diagnostica sul master con crictl e i manifest di /etc/kubernetes/manifests/. Se l'API risponde ma un nodo risulta NotReady, il problema è su quel nodo: kubelet, runtime o CNI. Non iniziare mai senza rispondere a quella domanda.
10.1
Nodos NotReady
NotReady nodes
Nodi NotReady
kubelet, systemctl, las causas de siempre.
kubelet, systemctl, the usual causes.
kubelet, systemctl, le solite cause.
10.2
Control plane caído
Downed control plane
Control plane caduto
Static pods, /etc/kubernetes/manifests, apiserver mudo.
Static pods, /etc/kubernetes/manifests, a mute apiserver.
Static pod, /etc/kubernetes/manifests, apiserver muto.
10.3
crictl
Ver containers cuando no hay API que preguntar.
Seeing containers when there is no API to ask.
Vedere i container quando non c'è API a cui chiedere.
10.4
journalctl y logs
journalctl and logs
journalctl e log
Dónde vive el log de cada componente.
Where each component's log lives.
Dove vive il log di ogni componente.
10.5
Certificados y etcd
Certificates and etcd
Certificati ed etcd
Lo que rompe el cluster entero y no se ve.
What breaks the whole cluster and cannot be seen.
Ciò che rompe l'intero cluster e non si vede.
★
Práctica
Practice
Pratica
8 ejercicios sobre el cluster real. Cronómetro: 5 min cada uno.
8 exercises on the real cluster. Timer: 5 min each.
8 esercizi sul cluster reale. Cronometro: 5 min ciascuno.
10.1
El caso más frecuente · 20 min
The most frequent case · 20 min
Il caso più frequente · 20 min

Nodos NotReady

NotReady nodes

Nodi NotReady

Casi siempre es el kubelet. Casi siempre son tres comandos.
It is almost always the kubelet. It is almost always three commands.
È quasi sempre il kubelet. Sono quasi sempre tre comandi.
Práctica · La secuencia
Practice · The sequence
Pratica · La sequenza

Paso 1 — desde el control plane

Step 1 — from the control plane

Passo 1 — dal control plane

k get nodes
# worker1   NotReady   <none>   10d   v1.34.0

k describe node worker1
# Conditions:  Ready=False
# Message: kubelet stopped posting node status
# o: container runtime network not ready: cni not initialized# or: container runtime network not ready: cni not initialized# oppure: container runtime network not ready: cni not initialized

Paso 2 — SSH al nodo y mirar el kubelet

Step 2 — SSH to the node and look at the kubelet

Passo 2 — SSH al nodo e guardare il kubelet

ssh worker1

sudo systemctl status kubelet          # ¿active (running)?
sudo systemctl restart kubelet
sudo systemctl enable --now kubelet   # que arranque al bootear# so it starts at boot# perché parta al boot

sudo journalctl -u kubelet -n 50 --no-pager
sudo journalctl -u kubelet -f            # en vivo# live# dal vivo

Paso 3 — si el kubelet no levanta, el runtime

Step 3 — if the kubelet will not come up, the runtime

Passo 3 — se il kubelet non si alza, il runtime

sudo systemctl status containerd
sudo systemctl restart containerd

# Y verificar que el kubelet le pega bien al socket# And check the kubelet is hitting the right socket# E verificare che il kubelet colpisca il socket giusto
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps

Los archivos que mira el kubelet

The files the kubelet looks at

I file che guarda il kubelet

/var/lib/kubelet/config.yaml        # su configuración# its configuration# la sua configurazione
/etc/kubernetes/kubelet.conf        # su kubeconfig (cómo habla con la API)# its kubeconfig (how it talks to the API)# il suo kubeconfig (come parla con l'API)
/var/lib/kubelet/pki/               # sus certificados# its certificates# i suoi certificati
/etc/kubernetes/manifests/          # static pods (solo en el master)# static pods (master only)# static pod (solo sul master)

# ¿A qué apiserver cree que tiene que hablarle?# Which apiserver does it think it should talk to?# A quale apiserver crede di dover parlare?
sudo cat /etc/kubernetes/kubelet.conf | grep server:

Las causas, en orden de frecuencia

The causes, in order of frequency

Le cause, in ordine di frequenza

# 1. kubelet parado o deshabilitado# 1. kubelet stopped or disabled# 1. kubelet fermo o disabilitato
sudo systemctl status kubelet

# 2. swap activo (el kubelet se niega a arrancar)# 2. swap on (the kubelet refuses to start)# 2. swap attivo (il kubelet si rifiuta di partire)
sudo swapoff -a
free -h

# 3. disco lleno → DiskPressure# 3. disk full → DiskPressure# 3. disco pieno → DiskPressure
df -h /var/lib

# 4. CNI no inicializado# 4. CNI not initialised# 4. CNI non inizializzato
ls /etc/cni/net.d/

# 5. certificado del kubelet vencido# 5. expired kubelet certificate# 5. certificato del kubelet scaduto
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
★
Rutina de examen para "nodo NotReady", en este orden y sin pensar: systemctl status kubelet → journalctl -u kubelet -n 50 → leer el error → arreglar → systemctl restart kubelet → volver al master y confirmar con k get nodes. No sigas al comando 6 sin haber leído el log del 2.
Exam routine for "NotReady node", in this order and without thinking: systemctl status kubelet → journalctl -u kubelet -n 50 → read the error → fix → systemctl restart kubelet → back to the master and confirm with k get nodes. Do not move on to command 6 without having read the log from command 2.
Routine d'esame per "nodo NotReady", in quest'ordine e senza pensarci: systemctl status kubelet → journalctl -u kubelet -n 50 → leggere l'errore → sistemare → systemctl restart kubelet → tornare al master e confermare con k get nodes. Non passare al comando 6 senza aver letto il log del 2.
Teoría · Quién declara Ready
Theory · Who declares Ready
Teoria · Chi dichiara Ready

Quién dice que un nodo está Ready

Who says a node is Ready

Chi dice che un nodo è Ready

El kubelet, y nadie más. Cada pocos segundos actualiza el estado del objeto Node contra la API. Si deja de hacerlo, a los ~40 segundos el nodo pasa a NotReady y después de un rato (5 min por defecto) el controller empieza a evictar sus pods a otros nodos.

The kubelet, and nobody else. Every few seconds it updates the Node object's status against the API. If it stops, after ~40 seconds the node turns NotReady and after a while (5 min by default) the controller starts evicting its pods to other nodes.

Il kubelet, e nessun altro. Ogni pochi secondi aggiorna lo stato dell'oggetto Node contro l'API. Se smette, dopo ~40 secondi il nodo passa a NotReady e dopo un po' (5 min di default) il controller inizia a fare evict dei suoi pod su altri nodi.

Las cuatro condiciones del Node

The Node's four conditions

Le quattro condition del Node

ConditionTrue significa
ConditionTrue means
ConditionTrue significa
ReadySano (esta es la única que querés en True)Healthy (the only one you want True)Sano (l'unica che vuoi True)
MemoryPressurePoca memoria → evictionsLow memory → evictionsPoca memoria → eviction
DiskPressurePoco disco → evictions + no pullLow disk → evictions + no pullPoco disco → eviction + niente pull
PIDPressureDemasiados procesosToo many processesTroppi processi

El kubelet no es un pod

The kubelet is not a pod

Il kubelet non è un pod

Es un servicio de systemd que corre directo en el host — por eso se maneja con systemctl y se lee con journalctl, no con kubectl logs. Es la única pieza de Kubernetes que no puede estar containerizada: alguien tiene que arrancar los containers.

It is a systemd service running directly on the host — hence systemctl to manage it and journalctl to read it, not kubectl logs. It is the one piece of Kubernetes that cannot be containerised: somebody has to start the containers.

È un servizio systemd che gira direttamente sull'host — per questo si gestisce con systemctl e si legge con journalctl, non con kubectl logs. È l'unico pezzo di Kubernetes che non può essere containerizzato: qualcuno deve pur avviare i container.

Swap

Históricamente el kubelet se negaba a arrancar con swap activo. Desde v1.28 hay soporte configurable (failSwapOn: false + memorySwap), pero la instalación estándar de kubeadm sigue esperando swap desactivado. Si un nodo quedó raro después de un reboot, revisá que el swapoff haya sido permanente en /etc/fstab.

Historically the kubelet refused to start with swap on. Since v1.28 there is configurable support (failSwapOn: false + memorySwap), but a standard kubeadm install still expects swap off. If a node went odd after a reboot, check that the swapoff was made permanent in /etc/fstab.

Storicamente il kubelet si rifiutava di partire con lo swap attivo. Da v1.28 c'è un supporto configurabile (failSwapOn: false + memorySwap), ma l'installazione standard di kubeadm si aspetta ancora swap disattivato. Se un nodo è rimasto strano dopo un reboot, verifica che lo swapoff sia stato reso permanente in /etc/fstab.

Nodo Ready pero los pods no arrancan

Node Ready but pods will not start

Nodo Ready ma i pod non partono

Si el nodo está Ready y los pods quedan en ContainerCreating, mirá el CNI (M7) y los volúmenes (M8). Ready significa "el kubelet responde", no "todo funciona".

If the node is Ready and pods sit in ContainerCreating, look at the CNI (M7) and the volumes (M8). Ready means "the kubelet answers", not "everything works".

Se il nodo è Ready e i pod restano in ContainerCreating, guarda il CNI (M7) e i volumi (M8). Ready significa "il kubelet risponde", non "tutto funziona".

★
Antes de tocar nada, k describe node te ahorra el SSH la mitad de las veces: el campo Message de la condition Ready suele decir textualmente qué falta (CNI, kubelet mudo, disco). Es gratis y son dos segundos.
Before touching anything, k describe node saves you the SSH half the time: the Ready condition's Message field usually says verbatim what is missing (CNI, mute kubelet, disk). It is free and takes two seconds.
Prima di toccare qualsiasi cosa, k describe node ti risparmia l'SSH metà delle volte: il campo Message della condition Ready di solito dice testualmente cosa manca (CNI, kubelet muto, disco). È gratis e sono due secondi.
10.2
El cluster mudo · 20 min
The mute cluster · 20 min
Il cluster muto · 20 min

Control plane caído y static pods

Downed control plane and static pods

Control plane caduto e static pod

Cuando kubectl no contesta, el diagnóstico es un ls.
When kubectl does not answer, the diagnosis is an ls.
Quando kubectl non risponde, la diagnosi è un ls.
Práctica · El master
Practice · The master
Pratica · Il master

El síntoma

The symptom

Il sintomo

k get nodes
# The connection to the server 192.168.64.10:6443 was refused
# - did you specify the right host or port?

Paso 1 — ¿están corriendo los containers?

Step 1 — are the containers running?

Passo 1 — i container stanno girando?

ssh master
sudo crictl ps -a | grep -E 'apiserver|etcd|scheduler|controller'

# Si el apiserver aparece Exited → mirar SU log# If the apiserver shows Exited → look at ITS log# Se l'apiserver risulta Exited → guardare il SUO log
sudo crictl ps -a --name kube-apiserver
sudo crictl logs --tail 50 <CONTAINER-ID>

Paso 2 — los manifiestos estáticos

Step 2 — the static manifests

Passo 2 — i manifest statici

ls -l /etc/kubernetes/manifests/
# etcd.yaml
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml

# SIEMPRE hacer backup antes de editar# ALWAYS back up before editing# SEMPRE fare backup prima di modificare
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /root/apiserver.bak
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml

# Guardar el archivo YA reinicia el pod: no hace falta nada más# Saving the file ALREADY restarts the pod: nothing else needed# Salvare il file GIÀ riavvia il pod: non serve altro
sudo crictl ps --name kube-apiserver   # esperar 30-60s# wait 30-60s# aspettare 30-60s

El truco del "sacar y poner"

The "take it out and put it back" trick

Il trucco del "togli e rimetti"

# Mover el manifiesto FUERA del directorio mata el pod# Moving the manifest OUT of the directory kills the pod# Spostare il manifest FUORI dalla directory uccide il pod
sudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/

# Devolverlo lo vuelve a crear# Putting it back re-creates it# Rimetterlo lo ricrea
sudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/

# Sirve para forzar un recreado limpio de un componente# Useful to force a clean re-creation of a component# Serve a forzare una ricreazione pulita di un componente

Los errores típicos del manifiesto

The manifest's typical errors

Gli errori tipici del manifest

# 1. YAML mal indentado → el kubelet lo rechaza SIN CREAR NADA# 1. badly indented YAML → the kubelet rejects it CREATING NOTHING# 1. YAML mal indentato → il kubelet lo rifiuta SENZA CREARE NULLA
sudo journalctl -u kubelet -n 30 | grep -i manifest

# 2. Flag mal escrito → el container arranca y muere# 2. misspelled flag → the container starts and dies# 2. flag scritto male → il container parte e muore
sudo crictl logs <ID> | tail -20
# unknown flag: --etcd-servrs

# 3. Puerto/host de etcd mal → apiserver no levanta# 3. wrong etcd host/port → the apiserver never comes up# 3. host/porta di etcd sbagliati → l'apiserver non si alza
grep etcd-servers /etc/kubernetes/manifests/kube-apiserver.yaml

# 4. hostPath de certificados que no existe# 4. a certificates hostPath that does not exist# 4. un hostPath dei certificati inesistente
ls /etc/kubernetes/pki/
⚠
Si rompés el YAML del apiserver con un error de sintaxis, el pod desaparece por completo — ni siquiera arranca para fallar. Y como el apiserver está caído, no tenés kubectl para investigar. La única pista está en journalctl -u kubelet. Por eso el backup antes de editar no es opcional.
If you break the apiserver's YAML with a syntax error, the pod disappears entirely — it does not even start in order to fail. And since the apiserver is down, you have no kubectl to investigate with. The only clue is in journalctl -u kubelet. That is why the backup before editing is not optional.
Se rompi lo YAML dell'apiserver con un errore di sintassi, il pod sparisce del tutto — non parte nemmeno per fallire. E poiché l'apiserver è caduto, non hai kubectl per indagare. L'unica traccia è in journalctl -u kubelet. Per questo il backup prima di modificare non è opzionale.
Teoría · Static pods
Theory · Static pods
Teoria · Static pod

Qué es un static pod

What a static pod is

Cos'è un static pod

Un pod que gestiona el kubelet directamente, leyendo un archivo YAML de un directorio del disco, sin pasar por la API. El kubelet vigila /etc/kubernetes/manifests/ y crea, actualiza o borra pods según lo que encuentre ahí. No hay Deployment, no hay ReplicaSet, no hay scheduler involucrado.

A pod managed directly by the kubelet, reading a YAML file from a directory on disk, without going through the API. The kubelet watches /etc/kubernetes/manifests/ and creates, updates or deletes pods according to what it finds there. No Deployment, no ReplicaSet, no scheduler involved.

Un pod gestito direttamente dal kubelet, leggendo un file YAML da una directory su disco, senza passare per l'API. Il kubelet sorveglia /etc/kubernetes/manifests/ e crea, aggiorna o cancella pod secondo ciò che trova lì. Nessun Deployment, nessun ReplicaSet, nessuno scheduler coinvolto.

Por qué el control plane funciona así

Why the control plane works this way

Perché il control plane funziona così

Es la solución al problema del huevo y la gallina: el apiserver no puede ser un pod normal, porque para crear pods normales hace falta… el apiserver. El kubelet lo arranca solo, desde el disco, sin depender de nada.

It is the answer to the chicken-and-egg problem: the apiserver cannot be a normal pod, because creating normal pods requires… the apiserver. The kubelet starts it on its own, from disk, depending on nothing.

È la soluzione al problema dell'uovo e della gallina: l'apiserver non può essere un pod normale, perché per creare pod normali serve… l'apiserver. Il kubelet lo avvia da solo, dal disco, senza dipendere da nulla.

Los mirror pods

Mirror pods

I mirror pod

El kubelet crea en la API un reflejo de cada static pod para que puedas verlo con kubectl get pods -n kube-system. Ese reflejo es de solo lectura: si lo borrás con kubectl, el kubelet lo vuelve a crear en segundos, porque la fuente de verdad es el archivo. Se reconocen por el sufijo con el nombre del nodo: kube-apiserver-master.

The kubelet creates a mirror of each static pod in the API so you can see it with kubectl get pods -n kube-system. That mirror is read-only: if you delete it with kubectl, the kubelet re-creates it within seconds, because the source of truth is the file. You recognise them by the node-name suffix: kube-apiserver-master.

Il kubelet crea nell'API un riflesso di ogni static pod perché tu possa vederlo con kubectl get pods -n kube-system. Quel riflesso è di sola lettura: se lo cancelli con kubectl, il kubelet lo ricrea in pochi secondi, perché la fonte di verità è il file. Si riconoscono dal suffisso col nome del nodo: kube-apiserver-master.

Editar = reiniciar

Editing = restarting

Modificare = riavviare

No existe systemctl restart kube-apiserver: no es un servicio. El ciclo es editás el archivo y el kubelet detecta el cambio (tarda entre 20 y 60 segundos). Tocar el archivo sin cambiar nada también dispara el recreado.

There is no systemctl restart kube-apiserver: it is not a service. The cycle is you edit the file and the kubelet notices the change (it takes 20 to 60 seconds). Touching the file without changing anything also triggers the re-creation.

Non esiste systemctl restart kube-apiserver: non è un servizio. Il ciclo è modifichi il file e il kubelet rileva il cambiamento (impiega tra 20 e 60 secondi). Anche un semplice touch sul file, senza cambiare nulla, innesca la ricreazione.

Quién es servicio y quién es pod

Who is a service and who is a pod

Chi è servizio e chi è pod

ComponenteCómo correSe toca con
ComponentHow it runsTouched with
ComponenteCome giraSi tocca con
kubeletsystemdsystemctl
containerdsystemdsystemctl
kube-apiserverstatic podeditar el manifiestoedit the manifestmodificare il manifest
etcdstatic podeditar el manifiestoedit the manifestmodificare il manifest
scheduler / c-managerstatic podeditar el manifiestoedit the manifestmodificare il manifest
kube-proxy / CNIDaemonSetkubectl
★
Memorizá esta tabla. La mitad del tiempo perdido en estos ejercicios es intentar systemctl restart kube-apiserver (no existe) o kubectl delete pod sobre un mirror pod (vuelve solo). Cada componente se toca de una única manera.
Memorise this table. Half the time wasted in these exercises is trying systemctl restart kube-apiserver (does not exist) or kubectl delete pod on a mirror pod (it comes back on its own). Each component is touched in exactly one way.
Memorizza questa tabella. Metà del tempo perso in questi esercizi è tentare systemctl restart kube-apiserver (non esiste) o kubectl delete pod su un mirror pod (torna da solo). Ogni componente si tocca in un unico modo.
Visor · hacé clic en un componente para ver cómo se inspecciona y se reinicia· click a component to see how it is inspected and restarted· clicca un componente per vedere come si ispeziona e si riavvia

Tres formas de correr, tres formas de tocarlo. Confundirlas es la pérdida de tiempo más común de este dominio.

Three ways of running, three ways of touching it. Mixing them up is the most common time sink in this domain.

Tre modi di girare, tre modi di toccarlo. Confonderli è la perdita di tempo più comune di questo dominio.

10.3
Sin API · 15 min
No API · 15 min
Senza API · 15 min

crictl: hablarle al runtime directo

crictl: talking to the runtime directly

crictl: parlare direttamente al runtime

El kubectl de emergencia, un nivel más abajo.
The emergency kubectl, one level lower.
Il kubectl d'emergenza, un livello più in basso.
Práctica · Los comandos
Practice · The commands
Pratica · I comandi

Configurarlo una vez (evita el warning)

Configure it once (avoids the warning)

Configurarlo una volta (evita il warning)

sudo tee /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
EOF

Containers

sudo crictl ps                  # corriendo# running# in esecuzione
sudo crictl ps -a               # TODOS (los muertos también)# ALL (the dead ones too)# TUTTI (anche i morti)
sudo crictl ps -a --name kube-apiserver

sudo crictl logs <ID>
sudo crictl logs --tail 50 <ID>
sudo crictl logs -f <ID>

sudo crictl inspect <ID> | less
sudo crictl exec -it <ID> sh

Pods e imágenes

Pods and images

Pod e immagini

sudo crictl pods                 # sandboxes
sudo crictl pods --name etcd

sudo crictl images
sudo crictl pull nginx:1.27
sudo crictl rmi --prune          # liberar disco# free up disk# liberare disco

El flujo real cuando el apiserver no responde

The real flow when the apiserver does not answer

Il flusso reale quando l'apiserver non risponde

# 1. ¿Está el container y en qué estado?# 1. Is the container there, and in what state?# 1. Il container c'è, e in che stato?
sudo crictl ps -a | grep apiserver
#   Exited (1)  <- arrancó y murió#   Exited (1)  <- it started and died#   Exited (1)  <- è partito ed è morto
#   (nada)      <- ni se creó: el manifiesto está roto#   (nothing)   <- never created: the manifest is broken#   (niente)    <- mai creato: il manifest è rotto

# 2. Si existe: su log tiene la causa exacta# 2. If it exists: its log has the exact cause# 2. Se esiste: il suo log ha la causa esatta
sudo crictl logs --tail 40 <ID>

# 3. Si no existe: el kubelet ni lo intentó# 3. If it does not exist: the kubelet did not even try# 3. Se non esiste: il kubelet non ci ha nemmeno provato
sudo journalctl -u kubelet -n 40 | grep -i 'manifest\|apiserver'
⚠
Casi todos los comandos de crictl necesitan sudo: el socket del runtime es de root. Un «connection refused» o un «permission denied» al usarlo suele ser eso y no un runtime caído.
Nearly every crictl command needs sudo: the runtime socket is root's. A "connection refused" or "permission denied" while using it is usually that, not a downed runtime.
Quasi tutti i comandi di crictl richiedono sudo: il socket del runtime è di root. Un «connection refused» o un «permission denied» usandolo di solito è quello, non un runtime caduto.
Teoría · Qué nivel es cada uno
Theory · Which level is which
Teoria · Quale livello è quale

Las tres capas

The three layers

I tre strati

HerramientaHabla conVe
ToolTalks toSees
StrumentoParla conVede
kubectlkube-apiserverTodo el clusterThe whole clusterTutto il cluster
crictlcontainerd (CRI)Solo ESE nodoTHAT node onlySolo QUEL nodo
ctr / nerdctlcontainerd directocontainerd directlycontainerd direttamenteNamespaces del runtimeThe runtime's namespacesI namespace del runtime

Cuando el apiserver se cae perdés el primer nivel, pero el segundo sigue intacto: los containers están corriendo igual en el nodo. Por eso crictl es la herramienta de rescate.

When the apiserver goes down you lose the first level, but the second is untouched: the containers are running on the node all the same. That is why crictl is the rescue tool.

Quando l'apiserver cade perdi il primo livello, ma il secondo resta intatto: i container stanno girando lo stesso sul nodo. Per questo crictl è lo strumento di soccorso.

Es parte de Kubernetes, no de Docker

It is part of Kubernetes, not Docker

Fa parte di Kubernetes, non di Docker

crictl implementa la CRI (Container Runtime Interface), la interfaz que Kubernetes usa para hablar con cualquier runtime. Funciona igual con containerd o CRI-O. La sintaxis se parece a la de Docker a propósito, pero docker ya no aplica: desde v1.24 no hay dockershim.

crictl implements the CRI (Container Runtime Interface), the interface Kubernetes uses to talk to any runtime. It works the same with containerd or CRI-O. The syntax resembles Docker's on purpose, but docker no longer applies: since v1.24 there is no dockershim.

crictl implementa la CRI (Container Runtime Interface), l'interfaccia che Kubernetes usa per parlare con qualsiasi runtime. Funziona uguale con containerd o CRI-O. La sintassi assomiglia a quella di Docker di proposito, ma docker non si applica più: da v1.24 non c'è dockershim.

La diferencia que confunde

The confusing difference

La differenza che confonde

crictl ve containers y sandboxes, no pods de Kubernetes. Cada pod tiene un container de pausa (el sandbox, que sostiene los namespaces de red) más sus containers reales. Por eso crictl ps muestra más cosas de las que esperas.

crictl sees containers and sandboxes, not Kubernetes pods. Each pod has a pause container (the sandbox, which holds the network namespaces) plus its real containers. That is why crictl ps shows more things than you expect.

crictl vede container e sandbox, non pod di Kubernetes. Ogni pod ha un container di pausa (la sandbox, che regge i namespace di rete) più i suoi container reali. Per questo crictl ps mostra più cose di quante te ne aspetti.

★
Regla práctica: crictl ps -a es el primer comando en el master cuando kubectl no contesta. La respuesta ya es diagnóstico: el container existe y murió (→ hay log, hay causa) o no existe (→ el kubelet no pudo ni leer el manifiesto).
Rule of thumb: crictl ps -a is the first command on the master when kubectl does not answer. The answer is already the diagnosis: the container exists and died (→ there is a log, there is a cause) or it does not exist (→ the kubelet could not even read the manifest).
Regola pratica: crictl ps -a è il primo comando sul master quando kubectl non risponde. La risposta è già diagnosi: il container esiste ed è morto (→ c'è un log, c'è una causa) oppure non esiste (→ il kubelet non è riuscito nemmeno a leggere il manifest).
10.4
Los logs · 20 min
The logs · 20 min
I log · 20 min

journalctl y dónde vive cada log

journalctl and where each log lives

journalctl e dove vive ogni log

Un mapa: quién loguea en systemd y quién en un archivo.
A map: who logs to systemd and who to a file.
Una mappa: chi logga su systemd e chi su un file.
Práctica · Buscar
Practice · Searching
Pratica · Cercare

Servicios de systemd

systemd services

Servizi systemd

sudo journalctl -u kubelet -n 50 --no-pager
sudo journalctl -u kubelet -f
sudo journalctl -u containerd -n 50

# Por tiempo (buenísimo cuando sabés cuándo se rompió)# By time (excellent when you know when it broke)# Per tempo (ottimo quando sai quando si è rotto)
sudo journalctl -u kubelet --since "10 min ago"
sudo journalctl -u kubelet --since "2026-08-25 09:00"

# Solo errores# Errors only# Solo errori
sudo journalctl -u kubelet -p err -n 30
sudo journalctl -u kubelet | grep -i error | tail -20

# Desde el último boot / todo el sistema# Since the last boot / the whole system# Dall'ultimo boot / tutto il sistema
sudo journalctl -b
sudo journalctl -xe

Componentes del control plane (son pods)

Control-plane components (they are pods)

Componenti del control plane (sono pod)

# Si la API responde: kubectl# If the API answers: kubectl# Se l'API risponde: kubectl
k logs -n kube-system kube-apiserver-master
k logs -n kube-system kube-scheduler-master --tail=50
k logs -n kube-system etcd-master

# Si NO responde: crictl# If it does NOT: crictl# Se NON risponde: crictl
sudo crictl logs --tail 50 <ID>

# Y siempre queda el disco: el kubelet los escribe ahí# And there is always the disk: the kubelet writes them there# E resta sempre il disco: il kubelet li scrive lì
sudo ls /var/log/pods/
sudo ls /var/log/containers/
sudo tail -50 /var/log/containers/kube-apiserver-master_kube-system_*.log

El mapa completo

The complete map

La mappa completa

/var/log/pods/                  # logs de todos los pods, por nodo# logs of every pod, per node# log di tutti i pod, per nodo
/var/log/containers/            # symlinks cómodos a lo anterior# handy symlinks to the above# comodi symlink ai precedenti
/etc/kubernetes/manifests/      # static pods
/etc/kubernetes/pki/            # certificados del cluster# the cluster's certificates# i certificati del cluster
/etc/kubernetes/admin.conf      # kubeconfig de admin# the admin kubeconfig# il kubeconfig di admin
/var/lib/kubelet/               # estado y config del kubelet# the kubelet's state and config# stato e config del kubelet
/var/lib/etcd/                  # los datos de etcd (M1)# etcd's data (M1)# i dati di etcd (M1)
/etc/cni/net.d/                 # config del CNI (M7)# the CNI's config (M7)# config del CNI (M7)
★
Usá siempre --no-pager o -n N en el examen: sin eso journalctl abre less y perdés segundos saliendo. Y -p err filtra el ruido de INFO, que en el kubelet es muchísimo.
Always use --no-pager or -n N in the exam: without it journalctl opens less and you lose seconds getting out. And -p err filters the INFO noise, which in the kubelet is enormous.
Usa sempre --no-pager o -n N all'esame: senza, journalctl apre less e perdi secondi per uscirne. E -p err filtra il rumore di INFO, che nel kubelet è enorme.
Teoría · Dónde mirar
Theory · Where to look
Teoria · Dove guardare

Dos sistemas de logging

Two logging systems

Due sistemi di logging

Corre comoLoguea enSe lee con
Runs asLogs toRead with
Gira comeLogga suSi legge con
Servicio systemdsystemd serviceServizio systemdEl journalThe journalIl journaljournalctl -u
Pod (incl. static)Pod (incl. static)Pod (anche static)/var/log/podskubectl logs / crictl logs

Confundir los dos es la pérdida de tiempo clásica: buscar el apiserver en journalctl (no está: es un pod) o el kubelet con kubectl logs (no está: es un servicio).

Confusing the two is the classic time sink: looking for the apiserver in journalctl (not there: it is a pod) or for the kubelet with kubectl logs (not there: it is a service).

Confondere i due è la classica perdita di tempo: cercare l'apiserver in journalctl (non c'è: è un pod) o il kubelet con kubectl logs (non c'è: è un servizio).

El disco siempre te salva

The disk always saves you

Il disco ti salva sempre

Aunque el apiserver esté muerto y no sepas el ID del container, el kubelet escribe los logs en /var/log/containers/ con nombres predecibles: <pod>_<namespace>_<container>-<id>.log. Un ls y un tail resuelven sin depender de ninguna herramienta.

Even with the apiserver dead and no container ID to hand, the kubelet writes the logs to /var/log/containers/ with predictable names: <pod>_<namespace>_<container>-<id>.log. An ls and a tail solve it without depending on any tool.

Anche con l'apiserver morto e senza l'ID del container, il kubelet scrive i log in /var/log/containers/ con nomi prevedibili: <pod>_<namespace>_<container>-<id>.log. Un ls e un tail risolvono senza dipendere da alcuno strumento.

Niveles de prioridad

Priority levels

Livelli di priorità

-p acepta emerg, alert, crit, err, warning, notice, info, debug. Con -p err ves ese nivel y todos los más graves. En un kubelet ruidoso, es la diferencia entre 3000 líneas y 5.

-p accepts emerg, alert, crit, err, warning, notice, info, debug. With -p err you see that level and every more severe one. On a noisy kubelet, it is the difference between 3000 lines and 5.

-p accetta emerg, alert, crit, err, warning, notice, info, debug. Con -p err vedi quel livello e tutti i più gravi. Su un kubelet rumoroso, è la differenza tra 3000 righe e 5.

Cuando el log no dice nada

When the log says nothing

Quando il log non dice nulla

Silencio total también es información: significa que el proceso ni siquiera arrancó. Ahí el problema es anterior — un manifiesto que no parsea, un binario ausente, un permiso — y se busca un nivel más arriba, en quien debía lanzarlo.

Total silence is information too: it means the process never even started. There the problem is upstream — a manifest that will not parse, a missing binary, a permission — and you look one level up, at whoever was supposed to launch it.

Il silenzio totale è anch'esso informazione: significa che il processo non è nemmeno partito. Lì il problema è a monte — un manifest che non parsa, un binario assente, un permesso — e si cerca un livello più su, in chi doveva lanciarlo.

★
Cadena de responsabilidad para memorizar: systemd arranca al kubelet, el kubelet arranca los static pods, los static pods son el control plane. Cuando algo no aparece, subí un eslabón y preguntále a quién tenía que arrancarlo.
Chain of responsibility to memorise: systemd starts the kubelet, the kubelet starts the static pods, the static pods are the control plane. When something does not show up, go one link up and ask whoever was supposed to start it.
Catena di responsabilità da memorizzare: systemd avvia il kubelet, il kubelet avvia gli static pod, gli static pod sono il control plane. Quando qualcosa non compare, sali di un anello e chiedi a chi doveva avviarlo.
10.5
Las causas invisibles · 10 min
The invisible causes · 10 min
Le cause invisibili · 10 min

Certificados vencidos y etcd

Expired certificates and etcd

Certificati scaduti ed etcd

Dos fallas que tiran el cluster entero sin dejar rastro obvio.
Two failures that take the whole cluster down without leaving an obvious trace.
Due guasti che buttano giù l'intero cluster senza lasciare tracce ovvie.
Práctica · Verificar
Practice · Verifying
Pratica · Verificare

Certificados (duran 1 año)

Certificates (they last 1 year)

Certificati (durano 1 anno)

sudo kubeadm certs check-expiration
# CERTIFICATE            EXPIRES               RESIDUAL TIME
# apiserver              Aug 25, 2026 10:00    364d

# Renovar todo (M1)# Renew everything (M1)# Rinnovare tutto (M1)
sudo kubeadm certs renew all
# y después reiniciar los static pods: mover los manifiestos# then restart the static pods: move the manifests# poi riavviare gli static pod: spostare i manifest
sudo mv /etc/kubernetes/manifests/*.yaml /tmp/ && sleep 20
sudo mv /tmp/*.yaml /etc/kubernetes/manifests/

# Ver un certificado puntual# Inspect one particular certificate# Ispezionare un certificato specifico
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | \
  grep -A2 Validity

Síntoma de certificado vencido

Symptom of an expired certificate

Sintomo di un certificato scaduto

k get nodes
# Unable to connect to the server: x509: certificate has expired
# or is not yet valid

# Si además venció el de admin.conf, regeneralo:# If admin.conf's also expired, regenerate it:# Se è scaduto anche quello di admin.conf, rigeneralo:
sudo kubeadm init phase kubeconfig admin
sudo cp /etc/kubernetes/admin.conf ~/.kube/config

etcd

# ¿Está sano?# Is it healthy?# È sano?
sudo ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health

# Espacio en disco: si se llena, el cluster pasa a SOLO LECTURA# Disk space: if it fills up, the cluster goes READ-ONLY# Spazio su disco: se si riempie, il cluster passa in SOLA LETTURA
df -h /var/lib/etcd
sudo crictl logs <ID-ETCD> | grep -i 'space\|quota'
# mvcc: database space exceeded

Chequeo rápido de kubeconfig

Quick kubeconfig check

Controllo rapido del kubeconfig

k config view --minify
k config current-context
k cluster-info

# ¿Le estás hablando al server correcto?# Are you talking to the right server?# Stai parlando col server giusto?
k config view -o jsonpath='{.clusters[*].cluster.server}'
⚠
Antes de asumir que el cluster se rompió, descartá lo trivial: un kubeconfig equivocado o un contexto mal seleccionado dan exactamente el mismo «connection refused». En un examen con varios clusters, este es un error carísimo — y se descarta en cinco segundos con k config current-context.
Before assuming the cluster broke, rule out the trivial: a wrong kubeconfig or a badly picked context give exactly the same "connection refused". In an exam with several clusters this is a very expensive mistake — and it is ruled out in five seconds with k config current-context.
Prima di dare per scontato che il cluster si sia rotto, escludi il banale: un kubeconfig sbagliato o un contesto mal selezionato danno esattamente lo stesso «connection refused». In un esame con più cluster questo è un errore carissimo — e si esclude in cinque secondi con k config current-context.
Teoría · Por qué duelen
Theory · Why they hurt
Teoria · Perché fanno male

Todo el cluster habla por TLS

The whole cluster speaks TLS

Tutto il cluster parla in TLS

Cada componente se autentica contra el apiserver con un certificado emitido por la CA del cluster (/etc/kubernetes/pki/ca.crt). Los que emite kubeadm duran un año, y se renuevan solos en cada kubeadm upgrade — por eso los clusters que nadie actualiza mueren exactamente a los doce meses.

Every component authenticates against the apiserver with a certificate issued by the cluster's CA (/etc/kubernetes/pki/ca.crt). The ones kubeadm issues last one year, and renew themselves on every kubeadm upgrade — which is why clusters nobody updates die at exactly twelve months.

Ogni componente si autentica contro l'apiserver con un certificato emesso dalla CA del cluster (/etc/kubernetes/pki/ca.crt). Quelli emessi da kubeadm durano un anno, e si rinnovano da soli a ogni kubeadm upgrade — ecco perché i cluster che nessuno aggiorna muoiono esattamente a dodici mesi.

La excepción del kubelet

The kubelet's exception

L'eccezione del kubelet

El certificado de cliente del kubelet sí se rota automáticamente (rotateCertificates), a diferencia de los del control plane. Cuando falla esa rotación, el síntoma es un nodo NotReady con errores x509 en journalctl -u kubelet — y cierra el círculo con la sección 10.1.

The kubelet's client certificate does rotate automatically (rotateCertificates), unlike the control plane's. When that rotation fails, the symptom is a NotReady node with x509 errors in journalctl -u kubelet — closing the circle with section 10.1.

Il certificato client del kubelet ruota automaticamente (rotateCertificates), a differenza di quelli del control plane. Quando quella rotazione fallisce, il sintomo è un nodo NotReady con errori x509 in journalctl -u kubelet — e chiude il cerchio con la sezione 10.1.

etcd es el punto único de falla

etcd is the single point of failure

etcd è il punto singolo di guasto

Si etcd no responde, el apiserver arranca pero no sirve nada: todo el estado del cluster vive ahí. Las dos fallas clásicas son disco lleno (etcd se protege pasando a solo lectura) y certificados de etcd vencidos, que están en su propio subdirectorio, /etc/kubernetes/pki/etcd/.

If etcd does not answer, the apiserver starts but serves nothing: all the cluster's state lives there. The two classic failures are a full disk (etcd protects itself by going read-only) and expired etcd certificates, which live in their own subdirectory, /etc/kubernetes/pki/etcd/.

Se etcd non risponde, l'apiserver parte ma non serve nulla: tutto lo stato del cluster vive lì. I due guasti classici sono disco pieno (etcd si protegge passando in sola lettura) e certificati di etcd scaduti, che stanno nella loro sottodirectory, /etc/kubernetes/pki/etcd/.

El orden de arranque

The startup order

L'ordine di avvio

etcd → apiserver → (scheduler, controller-manager). Si etcd tarda, verás al apiserver reiniciarse en loop: no es él el problema, es su dependencia. Diagnosticá siempre de abajo hacia arriba.

etcd → apiserver → (scheduler, controller-manager). If etcd is slow, you will see the apiserver restarting in a loop: it is not the problem, its dependency is. Always diagnose from the bottom up.

etcd → apiserver → (scheduler, controller-manager). Se etcd è lento, vedrai l'apiserver riavviarsi in loop: non è lui il problema, è la sua dipendenza. Diagnostica sempre dal basso verso l'alto.

★
Los tres «no se ve pero rompe todo»: certificados vencidos, disco lleno (en /var/lib/etcd o /var/lib/containerd) y swap prendido después de un reboot. Un df -h y un kubeadm certs check-expiration al principio te ahorran diez minutos de búsqueda a ciegas.
The three "you cannot see it but it breaks everything": expired certificates, a full disk (on /var/lib/etcd or /var/lib/containerd) and swap turned on after a reboot. A df -h and a kubeadm certs check-expiration up front save you ten minutes of blind searching.
I tre «non si vede ma rompe tutto»: certificati scaduti, disco pieno (su /var/lib/etcd o /var/lib/containerd) e swap acceso dopo un reboot. Un df -h e un kubeadm certs check-expiration all'inizio ti risparmiano dieci minuti di ricerca alla cieca.
★
Cierre del módulo
Module wrap-up
Chiusura del modulo

Lo que te llevás del Módulo 10

What you take away from Module 10

Cosa ti porti dal Modulo 10

Resumen · Comandos clave
Summary · Key commands
Riepilogo · Comandi chiave

Para tu agenda

For your notebook

Per la tua agenda

# Diagnóstico desde el master# Diagnosis from the master# Diagnosi dal master
k get nodes
k describe node worker1 | grep -A10 Conditions
k get pods -n kube-system

# En el nodo: el kubelet# On the node: the kubelet# Sul nodo: il kubelet
sudo systemctl status kubelet
sudo systemctl restart kubelet
sudo journalctl -u kubelet -n 50 --no-pager
sudo journalctl -u kubelet -p err --since "10 min ago"

# Control plane (static pods)# Control plane (static pods)# Control plane (static pod)
ls /etc/kubernetes/manifests/
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /root/bak.yaml
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml

# Runtime
sudo crictl ps -a
sudo crictl logs --tail 50 <ID>
sudo crictl pods
sudo systemctl status containerd

# Logs en disco (cuando no hay API ni ID)# Logs on disk (when there is neither API nor ID)# Log su disco (quando non c'è né API né ID)
sudo ls /var/log/containers/
sudo tail -50 /var/log/containers/kube-apiserver-*.log

# Certificados y espacio# Certificates and space# Certificati e spazio
sudo kubeadm certs check-expiration
df -h /var/lib
free -h   # swap

# Contexto (descartar lo tonto primero)# Context (rule out the silly first)# Contesto (escludere prima la sciocchezza)
k config current-context
Teoría · Lo esencial
Theory · The essentials
Teoria · L'essenziale

Las 6 ideas que no se negocian

The 6 non-negotiable ideas

Le 6 idee non negoziabili

  • ¿Responde kubectl? No → control plane, al master con crictl. Sí, pero un nodo NotReady → kubelet de ese nodo.
  • El kubelet es systemd (systemctl + journalctl); el control plane son static pods (editar el manifiesto). Nunca al revés.
  • Guardar un archivo en /etc/kubernetes/manifests/ es el reinicio. Sacarlo del directorio mata el pod; devolverlo lo recrea.
  • Un mirror pod borrado con kubectl vuelve solo: la fuente de verdad es el archivo en disco.
  • crictl ps -a es el primer comando cuando la API no contesta: existe-y-murió (hay log) vs no-existe (manifiesto roto).
  • Las causas silenciosas: certificados vencidos, disco lleno, swap prendido. Se descartan en tres comandos.
  • Does kubectl answer? No → control plane, to the master with crictl. Yes, but a node is NotReady → that node's kubelet.
  • The kubelet is systemd (systemctl + journalctl); the control plane are static pods (edit the manifest). Never the other way round.
  • Saving a file in /etc/kubernetes/manifests/ is the restart. Taking it out of the directory kills the pod; putting it back re-creates it.
  • A mirror pod deleted with kubectl comes back on its own: the source of truth is the file on disk.
  • crictl ps -a is the first command when the API does not answer: exists-and-died (there is a log) vs does-not-exist (broken manifest).
  • The silent causes: expired certificates, full disk, swap turned on. Ruled out in three commands.
  • Risponde kubectl? No → control plane, al master con crictl. Sì, ma un nodo è NotReady → kubelet di quel nodo.
  • Il kubelet è systemd (systemctl + journalctl); il control plane sono static pod (modificare il manifest). Mai il contrario.
  • Salvare un file in /etc/kubernetes/manifests/ è il riavvio. Toglierlo dalla directory uccide il pod; rimetterlo lo ricrea.
  • Un mirror pod cancellato con kubectl torna da solo: la fonte di verità è il file su disco.
  • crictl ps -a è il primo comando quando l'API non risponde: esiste-ed-è-morto (c'è un log) vs non-esiste (manifest rotto).
  • Le cause silenziose: certificati scaduti, disco pieno, swap acceso. Si escludono in tre comandi.
★
El hilo del módulo: cada capa depende de la de abajo — systemd → kubelet → static pods → API → todo lo demás. Cuando algo falla, bajá una capa y preguntá ahí. Es el mismo método del M9 (describe→logs) trasladado al plano del sistema operativo.
The module's thread: each layer depends on the one below — systemd → kubelet → static pods → API → everything else. When something fails, go one layer down and ask there. It is M9's method (describe→logs) moved onto the operating-system plane.
Il filo del modulo: ogni strato dipende da quello sotto — systemd → kubelet → static pod → API → tutto il resto. Quando qualcosa fallisce, scendi di uno strato e chiedi lì. È lo stesso metodo del M9 (describe→logs) trasportato sul piano del sistema operativo.
Checkpoint Módulo 10: nodos NotReady y el kubelet, static pods y el control plane, crictl como kubectl de emergencia, el mapa de logs (journal vs /var/log/pods) y las fallas invisibles (certificados, disco, swap). Segundo tercio de Troubleshooting (30%). Siguiente: Módulo 11 — troubleshooting de networking.
Module 10 checkpoint: NotReady nodes and the kubelet, static pods and the control plane, crictl as the emergency kubectl, the log map (journal vs /var/log/pods) and the invisible failures (certificates, disk, swap). Second third of Troubleshooting (30%). Next: Module 11 — networking troubleshooting.
Checkpoint Modulo 10: nodi NotReady e il kubelet, static pod e il control plane, crictl come kubectl d'emergenza, la mappa dei log (journal vs /var/log/pods) e i guasti invisibili (certificati, disco, swap). Secondo terzo di Troubleshooting (30%). Prossimo: Modulo 11 — troubleshooting di networking.
★
Fase 2 · resolver en vivo
Phase 2 · solve it live
Fase 2 · risolvere dal vivo

Práctica — 8 ejercicios

Practice — 8 exercises

Pratica — 8 esercizi

Acá se rompe el cluster de verdad. Cronometrate: 5 min cada uno.
Here you genuinely break the cluster. Time yourself: 5 min each.
Qui il cluster si rompe davvero. Cronometrati: 5 min ciascuno.
0 / 8
🧠
Modelo mental. ¿Responde kubectl? NO → control plane. SÍ → el kubelet de ese nodo. Cada ejercicio empieza respondiendo esa pregunta, y la respuesta ya decide con qué herramienta seguís: crictl y los manifiestos, o systemctl y journalctl.
Mental model. Does kubectl answer? NO → control plane. YES → that node's kubelet. Every exercise starts by answering that question, and the answer already decides which tool you continue with: crictl and the manifests, or systemctl and journalctl.
Modello mentale. Risponde kubectl? NO → control plane. SÌ → il kubelet di quel nodo. Ogni esercizio inizia rispondendo a quella domanda, e la risposta decide già con quale strumento prosegui: crictl e i manifest, oppure systemctl e journalctl.
⚠
Antes de empezar. Estos ejercicios rompen el cluster a propósito. Hacelos solo en tu lab (cka-18), nunca en algo que te importe, y sacá un snapshot de las VMs antes — es tu botón de deshacer. Y la regla de oro que vas a repetir ocho veces: sudo cp <manifiesto> /root/ antes de tocarlo.
Before you start. These exercises break the cluster on purpose. Do them only in your lab (cka-18), never on anything you care about, and take a VM snapshot first — it is your undo button. And the golden rule you will repeat eight times: sudo cp <manifest> /root/ before touching it.
Prima di iniziare. Questi esercizi rompono il cluster di proposito. Falli solo nel tuo lab (cka-18), mai su qualcosa a cui tieni, e fai prima uno snapshot delle VM — è il tuo pulsante annulla. E la regola d'oro che ripeterai otto volte: sudo cp <manifest> /root/ prima di toccarlo.
E1

Nodo NotReady: la secuencia de tres comandos

NotReady node: the three-command sequence

Nodo NotReady: la sequenza di tre comandi

~5 min

Pará el kubelet de un worker y recuperalo sin mirar cómo lo rompiste. Cronometrá cuánto tarda el nodo en pasar a NotReady y cuánto tardan sus pods en ser evictados.

Para plantarlo: ssh worker1 'sudo systemctl stop kubelet'

Stop a worker's kubelet and recover it without looking at how you broke it. Time how long the node takes to go NotReady, and how long its pods take to be evicted.

To plant it: ssh worker1 'sudo systemctl stop kubelet'

Ferma il kubelet di un worker e recuperalo senza guardare come l'hai rotto. Cronometra quanto ci mette il nodo a passare NotReady, e quanto ci mettono i suoi pod a essere evictati.

Per prepararlo: ssh worker1 'sudo systemctl stop kubelet'

Ver soluciónShow solutionMostra soluzione
k get nodes -w                    # NotReady a los ~40s# NotReady after ~40s# NotReady dopo ~40s
k describe node worker1 | grep -A8 Conditions
# Ready  False  kubelet stopped posting node status

ssh worker1
sudo systemctl status kubelet             # inactive (dead)
sudo journalctl -u kubelet -n 20 --no-pager
sudo systemctl start kubelet
sudo systemctl enable kubelet          # que no vuelva a pasar# so it does not happen again# perché non ricapiti

exit
k get nodes                       # Ready en segundos# Ready within seconds# Ready in pochi secondi
Claves
Key points
Punti chiave
  • Los tiempos importan: ~40 s para NotReady, 5 minutos para que empiecen las evictions. Si arreglás rápido, los pods no se mueven.
  • El Message de la condition Ready ya te dice cuál de las dos familias es: "kubelet stopped posting" (el kubelet) vs "cni not initialized" (la red).
  • start lo levanta ahora; enable hace que sobreviva al reboot. En el examen pedí las dos: es gratis y es la diferencia entre "arreglado" y "arreglado hasta el próximo reinicio".
  • The timings matter: ~40 s to NotReady, 5 minutes before evictions begin. Fix it quickly and the pods never move.
  • The Ready condition's Message already tells you which of the two families it is: "kubelet stopped posting" (the kubelet) vs "cni not initialized" (the network).
  • start brings it up now; enable makes it survive a reboot. In the exam do both: it is free, and it is the difference between "fixed" and "fixed until the next restart".
  • I tempi contano: ~40 s per NotReady, 5 minuti prima che inizino le eviction. Se sistemi in fretta, i pod non si spostano.
  • Il Message della condition Ready ti dice già quale delle due famiglie è: "kubelet stopped posting" (il kubelet) vs "cni not initialized" (la rete).
  • start lo alza ora; enable lo fa sopravvivere al reboot. All'esame fai entrambi: è gratis, ed è la differenza tra "sistemato" e "sistemato fino al prossimo riavvio".
E2

El kubelet que no arranca: leer el journal

The kubelet that will not start: reading the journal

Il kubelet che non parte: leggere il journal

~6 min

Ahora el restart no alcanza: el kubelet arranca y se muere. Encontrá la causa en el journal, no adivinando, y arreglala.

Para plantarlo (elegí una): sudo swapon -a · o romper una línea de /var/lib/kubelet/config.yaml · o apuntar staticPodPath a un directorio inexistente.

Now a restart is not enough: the kubelet starts and dies. Find the cause in the journal, not by guessing, and fix it.

To plant it (pick one): sudo swapon -a · or break a line in /var/lib/kubelet/config.yaml · or point staticPodPath at a non-existent directory.

Ora il restart non basta: il kubelet parte e muore. Trova la causa nel journal, non indovinando, e sistemala.

Per prepararlo (scegline una): sudo swapon -a · o rompi una riga di /var/lib/kubelet/config.yaml · o punta staticPodPath a una directory inesistente.

Ver soluciónShow solutionMostra soluzione
sudo systemctl status kubelet
#   Active: activating (auto-restart) (Result: exit-code)

sudo journalctl -u kubelet -p err -n 30 --no-pager
#   "failed to run Kubelet: running with swap on is not supported"
#   o: "failed to parse kubelet flag" / "no such file or directory"

# según la causa:# depending on the cause:# a seconda della causa:
sudo swapoff -a
sudo sed -i '/ swap /s/^/#/' /etc/fstab   # permanente# make it permanent# renderlo permanente
sudo vi /var/lib/kubelet/config.yaml

sudo systemctl restart kubelet
sudo journalctl -u kubelet -n 10 --no-pager
Claves
Key points
Punti chiave
  • activating (auto-restart) es la firma del crash loop de systemd: no está parado, está muriendo una y otra vez. Es el equivalente del CrashLoopBackOff del M9.
  • -p err es lo que hace legible el journal del kubelet: sin él son miles de líneas de INFO.
  • El swap se arregla dos veces: swapoff -a para ahora y /etc/fstab para el próximo reboot. Arreglar solo la primera es el clásico "volvió a romperse solo".
  • activating (auto-restart) is systemd's crash-loop signature: it is not stopped, it is dying over and over. It is M9's CrashLoopBackOff equivalent.
  • -p err is what makes the kubelet's journal readable: without it there are thousands of INFO lines.
  • Swap gets fixed twice: swapoff -a for now and /etc/fstab for the next reboot. Fixing only the first is the classic "it broke again by itself".
  • activating (auto-restart) è la firma del crash loop di systemd: non è fermo, sta morendo in continuazione. È l'equivalente del CrashLoopBackOff del M9.
  • -p err è ciò che rende leggibile il journal del kubelet: senza, sono migliaia di righe di INFO.
  • Lo swap si sistema due volte: swapoff -a per adesso e /etc/fstab per il prossimo reboot. Sistemare solo il primo è il classico "si è rotto di nuovo da solo".
E3

El apiserver mudo: manifiesto roto

The mute apiserver: a broken manifest

L'apiserver muto: manifest rotto

~8 min

El ejercicio central del módulo. Meté un flag inexistente en kube-apiserver.yaml, perdé kubectl, y recuperá el cluster usando solo crictl y el journal. Hacé el backup primero.

Para plantarlo: agregá - --etcd-servrs=https://127.0.0.1:2379 a los args del container.

The module's central exercise. Put a non-existent flag into kube-apiserver.yaml, lose kubectl, and recover the cluster using only crictl and the journal. Make the backup first.

To plant it: add - --etcd-servrs=https://127.0.0.1:2379 to the container's args.

L'esercizio centrale del modulo. Metti un flag inesistente in kube-apiserver.yaml, perdi kubectl, e recupera il cluster usando solo crictl e il journal. Fai prima il backup.

Per prepararlo: aggiungi - --etcd-servrs=https://127.0.0.1:2379 agli args del container.

Ver soluciónShow solutionMostra soluzione
sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /root/api.bak   # PRIMERO# FIRST# PRIMA

k get nodes
# The connection to the server ...:6443 was refused

sudo crictl ps -a | grep apiserver
#   Exited (1)  <- existe: hay log
sudo crictl logs --tail 20 <ID>
#   unknown flag: --etcd-servrs

sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml   # sacar el flag# remove the flag# togliere il flag
# o volver al backup:# or go back to the backup:# oppure tornare al backup:
sudo cp /root/api.bak /etc/kubernetes/manifests/kube-apiserver.yaml

sudo crictl ps --name kube-apiserver    # esperar 30-60s# wait 30-60s# aspettare 30-60s
k get nodes
Claves
Key points
Punti chiave
  • La bifurcación de crictl ps -a: existe y murió → hay log con la causa exacta. No existe → el kubelet ni lo intentó, y la pista está en journalctl -u kubelet. Dos caminos, ninguna adivinanza.
  • Guardar el archivo es el reinicio. No hay systemctl restart kube-apiserver y no hace falta.
  • Tené paciencia: el kubelet tarda entre 20 y 60 segundos en recrear el pod. Volver a editar porque "no anduvo" a los 10 segundos es cómo se pierden los puntos.
  • El backup en /root/ convierte un desastre en un cp. Nunca edites un manifiesto sin él.
  • crictl ps -a's fork: exists and died → there is a log with the exact cause. Does not exist → the kubelet never tried, and the clue is in journalctl -u kubelet. Two paths, no guessing.
  • Saving the file is the restart. There is no systemctl restart kube-apiserver and none is needed.
  • Be patient: the kubelet takes 20 to 60 seconds to re-create the pod. Re-editing because "it did not work" after 10 seconds is how points are lost.
  • The backup in /root/ turns a disaster into a cp. Never edit a manifest without it.
  • La biforcazione di crictl ps -a: esiste ed è morto → c'è un log con la causa esatta. Non esiste → il kubelet non ci ha nemmeno provato, e la traccia è in journalctl -u kubelet. Due strade, nessun indovinello.
  • Salvare il file è il riavvio. Non esiste systemctl restart kube-apiserver e non serve.
  • Abbi pazienza: il kubelet impiega tra 20 e 60 secondi a ricreare il pod. Rimodificare perché "non ha funzionato" dopo 10 secondi è il modo in cui si perdono i punti.
  • Il backup in /root/ trasforma un disastro in un cp. Non modificare mai un manifest senza.
E4

Existe vs no existe: el YAML que no parsea

Exists vs does not exist: the YAML that will not parse

Esiste vs non esiste: lo YAML che non parsa

~6 min

Mismo archivo que E3, otro tipo de rotura: ahora indentá mal una línea. Compará los dos síntomas y explicá por qué esta vez no hay log de container. Recuperalo.

Same file as E3, a different kind of breakage: this time indent a line wrongly. Compare the two symptoms and explain why this time there is no container log. Recover it.

Stesso file di E3, un altro tipo di rottura: stavolta indenta male una riga. Confronta i due sintomi e spiega perché stavolta non c'è alcun log di container. Recuperalo.

Ver soluciónShow solutionMostra soluzione
sudo crictl ps -a | grep apiserver
#   (nada) <- el container NUNCA se creó#   (nothing) <- the container was NEVER created#   (niente) <- il container NON è mai stato creato

sudo journalctl -u kubelet -n 30 --no-pager | grep -i 'manifest\|yaml\|parse'
#   "Could not process manifest file" ... yaml: line 24: did not find expected key

sudo cp /root/api.bak /etc/kubernetes/manifests/kube-apiserver.yaml
# o validar antes de guardar:# or validate before saving:# o validare prima di salvare:
python3 -c 'import yaml,sys; yaml.safe_load(open(sys.argv[1]))' \
  /etc/kubernetes/manifests/kube-apiserver.yaml
Claves
Key points
Punti chiave
  • Sin container no hay crictl logs: el error ocurrió antes, cuando el kubelet intentó leer el archivo. Por eso la única pista está en el journal del kubelet.
  • Es exactamente la misma lógica del M9: el CreateContainerConfigError tampoco deja logs, porque el container nunca existió. Un escalón antes en la cadena.
  • El grep por manifest en el journal te lleva directo: el kubelet loguea el nombre del archivo y el número de línea.
  • No container means no crictl logs: the error happened earlier, when the kubelet tried to read the file. That is why the only clue is in the kubelet's journal.
  • It is exactly M9's logic: CreateContainerConfigError leaves no logs either, because the container never existed. One rung earlier in the chain.
  • Grepping the journal for manifest takes you straight there: the kubelet logs the file name and the line number.
  • Senza container non c'è crictl logs: l'errore è avvenuto prima, quando il kubelet ha tentato di leggere il file. Per questo l'unica traccia è nel journal del kubelet.
  • È esattamente la logica del M9: anche il CreateContainerConfigError non lascia log, perché il container non è mai esistito. Un gradino prima nella catena.
  • Il grep di manifest nel journal ti porta dritto: il kubelet logga il nome del file e il numero di riga.
E5

El mirror pod que vuelve solo

The mirror pod that comes back on its own

Il mirror pod che torna da solo

~4 min

Borrá kube-scheduler-master con kubectl y observá qué pasa. Después conseguí que desaparezca de verdad durante un minuto, comprobá el efecto (creá un Deployment y mirá sus pods), y devolvelo.

Delete kube-scheduler-master with kubectl and watch what happens. Then get it to actually disappear for a minute, check the effect (create a Deployment and look at its pods), and put it back.

Cancella kube-scheduler-master con kubectl e osserva cosa succede. Poi fai in modo che sparisca davvero per un minuto, verifica l'effetto (crea un Deployment e guarda i suoi pod), e rimettilo.

Ver soluciónShow solutionMostra soluzione
k delete pod -n kube-system kube-scheduler-master
k get pods -n kube-system | grep scheduler
#   volvió en segundos: la fuente de verdad es el archivo#   back within seconds: the source of truth is the file#   tornato in pochi secondi: la fonte di verità è il file

sudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/
k get pods -n kube-system | grep scheduler   # ahora sí, no está# now it really is gone# ora sì, non c'è

k create deploy prueba --image=nginx
k get pods                       # Pending, y SIN eventos# Pending, and with NO events# Pending, e SENZA eventi
k describe pod prueba-xxx | tail -5      # Events: <none>

sudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/
k get pods -w                    # se asigna solo# it gets scheduled on its own# viene assegnato da solo
Claves
Key points
Punti chiave
  • kubectl delete sobre un mirror pod es un gesto vacío: borra el reflejo, no la fuente. Para matar un static pod hay que mover el archivo.
  • Pending SIN ningún evento es la firma del scheduler caído. Es el único Pending que no viene acompañado de un FailedScheduling que explique por qué — porque no hay nadie que lo escriba. Compará con las cuatro causas de Pending del M9.
  • El cluster sigue funcionando sin scheduler: lo que ya está corriendo no se entera. Solo se rompe lo nuevo.
  • kubectl delete on a mirror pod is an empty gesture: it deletes the reflection, not the source. To kill a static pod you must move the file.
  • Pending with NO event at all is the downed scheduler's signature. It is the one Pending not accompanied by a FailedScheduling explaining why — because there is nobody to write it. Compare with M9's four Pending causes.
  • The cluster keeps working without a scheduler: what is already running never notices. Only new things break.
  • kubectl delete su un mirror pod è un gesto vuoto: cancella il riflesso, non la fonte. Per uccidere uno static pod bisogna spostare il file.
  • Pending SENZA alcun evento è la firma dello scheduler caduto. È l'unico Pending non accompagnato da un FailedScheduling che spieghi il perché — perché non c'è nessuno a scriverlo. Confronta con le quattro cause di Pending del M9.
  • Il cluster continua a funzionare senza scheduler: ciò che già gira non se ne accorge. Si rompe solo il nuovo.
E6

crictl a ciegas: el log sin API

crictl in the dark: the log without an API

crictl alla cieca: il log senza API

~5 min

Sin usar kubectl ni una sola vez, conseguí desde el master: (a) el estado de los cinco componentes del control plane; (b) las últimas 20 líneas del log de etcd; (c) un shell dentro del container de CoreDNS; (d) el mismo log de etcd pero leyéndolo del disco.

Without using kubectl even once, get from the master: (a) the state of the five control-plane components; (b) etcd's last 20 log lines; (c) a shell inside the CoreDNS container; (d) that same etcd log, but read from disk.

Senza usare kubectl nemmeno una volta, ottieni dal master: (a) lo stato dei cinque componenti del control plane; (b) le ultime 20 righe del log di etcd; (c) una shell dentro il container di CoreDNS; (d) lo stesso log di etcd, ma leggendolo dal disco.

Ver soluciónShow solutionMostra soluzione
sudo crictl ps -a | grep -E 'apiserver|etcd|scheduler|controller|coredns'

ETCD=$(sudo crictl ps -q --name etcd)
sudo crictl logs --tail 20 $ETCD

DNS=$(sudo crictl ps -q --name coredns | head -1)
sudo crictl exec -it $DNS sh

# el mismo log, del disco# the same log, from disk# lo stesso log, dal disco
sudo ls /var/log/containers/ | grep etcd
sudo tail -20 /var/log/containers/etcd-master_kube-system_etcd-*.log
Claves
Key points
Punti chiave
  • crictl ps -q --name X te da solo el ID, listo para meter en una variable. Sin eso vas a estar copiando hashes a mano, que en el examen es tiempo y errores.
  • Los nombres de /var/log/containers/ son predecibles: <pod>_<ns>_<container>-<id>.log. Es el plan C cuando ni siquiera crictl coopera.
  • crictl exec existe y funciona igual que kubectl exec, pero solo sobre containers de ese nodo.
  • crictl ps -q --name X gives you just the ID, ready to drop into a variable. Without it you will be copying hashes by hand, which in the exam means time and mistakes.
  • The names in /var/log/containers/ are predictable: <pod>_<ns>_<container>-<id>.log. It is plan C for when not even crictl cooperates.
  • crictl exec exists and works just like kubectl exec, but only on that node's containers.
  • crictl ps -q --name X ti dà solo l'ID, pronto da mettere in una variabile. Senza, copierai hash a mano, che all'esame significa tempo ed errori.
  • I nomi in /var/log/containers/ sono prevedibili: <pod>_<ns>_<container>-<id>.log. È il piano C per quando nemmeno crictl collabora.
  • crictl exec esiste e funziona come kubectl exec, ma solo sui container di quel nodo.
T1

Troubleshooting — certificados y kubeconfig

Troubleshooting — certificates and kubeconfig

Troubleshooting — certificati e kubeconfig

~6 min

kubectl falla. Distinguí en menos de un minuto entre las tres causas posibles — contexto equivocado, certificado vencido, apiserver caído — y decí qué comando descarta cada una. Después listá cuánto le queda a cada certificado del cluster y renovalos.

kubectl fails. Tell the three possible causes apart in under a minute — wrong context, expired certificate, downed apiserver — and say which command rules out each. Then list how long each of the cluster's certificates has left, and renew them.

kubectl fallisce. Distingui in meno di un minuto tra le tre cause possibili — contesto sbagliato, certificato scaduto, apiserver caduto — e di' quale comando esclude ciascuna. Poi elenca quanto resta a ogni certificato del cluster e rinnovali.

Ver soluciónShow solutionMostra soluzione
# 1. lo tonto primero (2 segundos)# 1. the silly one first (2 seconds)# 1. prima la sciocchezza (2 secondi)
k config current-context
k config view --minify | grep server:

# 2. leer el error: los tres dicen cosas distintas# 2. read the error: the three say different things# 2. leggere l'errore: i tre dicono cose diverse
#   "connection refused"                 -> apiserver
#   "x509: certificate has expired"      -> certificados
#   "no such host" / context not found   -> kubeconfig

# 3. certificados# 3. certificates# 3. certificati
sudo kubeadm certs check-expiration
sudo kubeadm certs renew all
sudo mv /etc/kubernetes/manifests/*.yaml /tmp/ && sleep 20
sudo mv /tmp/*.yaml /etc/kubernetes/manifests/
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
Claves
Key points
Punti chiave
  • El texto del error ya separa las tres causas. Leerlo entero antes de hacer nada es el gesto que más tiempo ahorra en todo el módulo.
  • k config current-context es gratis y descarta el error más caro del examen: trabajar sobre el cluster equivocado.
  • Renovar los certificados no alcanza: hay que reiniciar los static pods para que los tomen. De ahí el mv de los manifiestos.
  • Si venció el de admin.conf, renovar los del control plane no te devuelve kubectl: hay que recopiar el kubeconfig.
  • The error text already separates the three causes. Reading it in full before doing anything is the single biggest time-saver in the module.
  • k config current-context is free and rules out the exam's costliest mistake: working on the wrong cluster.
  • Renewing the certificates is not enough: the static pods must be restarted to pick them up. Hence the mv of the manifests.
  • If admin.conf's expired, renewing the control plane's does not give you kubectl back: you have to re-copy the kubeconfig.
  • Il testo dell'errore separa già le tre cause. Leggerlo per intero prima di fare qualsiasi cosa è il gesto che fa risparmiare più tempo di tutto il modulo.
  • k config current-context è gratis ed esclude l'errore più costoso dell'esame: lavorare sul cluster sbagliato.
  • Rinnovare i certificati non basta: bisogna riavviare gli static pod perché li prendano. Da cui il mv dei manifest.
  • Se è scaduto quello di admin.conf, rinnovare quelli del control plane non ti ridà kubectl: devi ricopiare il kubeconfig.
T2

Troubleshooting — el nodo Ready cuyos pods no arrancan

Troubleshooting — the Ready node whose pods will not start

Troubleshooting — il nodo Ready i cui pod non partono

~6 min

Un nodo figura Ready, pero todos sus pods quedan en ContainerCreating y CoreDNS está en Pending. Diagnosticá qué capa falló y por qué el nodo miente. Extra: llená /var/lib y observá qué condition aparece y qué le hace a los pods.

A node shows Ready, but all its pods sit in ContainerCreating and CoreDNS is Pending. Diagnose which layer failed and why the node is lying. Extra: fill /var/lib and watch which condition appears and what it does to the pods.

Un nodo risulta Ready, ma tutti i suoi pod restano in ContainerCreating e CoreDNS è in Pending. Diagnostica quale strato ha ceduto e perché il nodo mente. Extra: riempi /var/lib e osserva quale condition compare e cosa fa ai pod.

Ver soluciónShow solutionMostra soluzione
k describe pod x | tail -5
#   failed to setup network for sandbox: plugin not initialized

# la firma del CNI: nodos raros + CoreDNS Pending# the CNI's signature: odd nodes + CoreDNS Pending# la firma del CNI: nodi strani + CoreDNS Pending
ls /etc/cni/net.d/                # ¿vacío?# empty?# vuoto?
k get pods -n kube-system | grep -i calico
k logs -n kube-system -l k8s-app=calico-node --tail=30
k rollout restart ds -n kube-system calico-node

# extra: disco# extra: disk# extra: disco
df -h /var/lib
k describe node worker1 | grep -A6 Conditions      # DiskPressure=True
sudo crictl rmi --prune
Claves
Key points
Punti chiave
  • Ready significa "el kubelet responde", no "todo anda". El kubelet puede reportarse sano y aun así ser incapaz de darle red a un pod.
  • ContainerCreating + CoreDNS Pending es la firma del CNI, no del kubelet. Si atacás el kubelet acá, perdés el ejercicio.
  • DiskPressure=True hace dos cosas distintas: evicta los pods que ya están y bloquea el pull de imágenes nuevas. crictl rmi --prune suele ser el desatasco más rápido.
  • El CNI es un DaemonSet: se toca con kubectl, no con systemctl. Volvé a la tabla del visor si dudaste.
  • Ready means "the kubelet answers", not "everything works". The kubelet can report itself healthy and still be unable to give a pod a network.
  • ContainerCreating + CoreDNS Pending is the CNI's signature, not the kubelet's. Attack the kubelet here and you lose the exercise.
  • DiskPressure=True does two distinct things: it evicts the pods already there and blocks pulling new images. crictl rmi --prune is usually the fastest unblock.
  • The CNI is a DaemonSet: touched with kubectl, not systemctl. Go back to the visualizer's table if you hesitated.
  • Ready significa "il kubelet risponde", non "tutto funziona". Il kubelet può dichiararsi sano ed essere comunque incapace di dare rete a un pod.
  • ContainerCreating + CoreDNS Pending è la firma del CNI, non del kubelet. Se qui attacchi il kubelet, perdi l'esercizio.
  • DiskPressure=True fa due cose distinte: fa evict dei pod già presenti e blocca il pull di nuove immagini. crictl rmi --prune è di solito lo sblocco più rapido.
  • Il CNI è un DaemonSet: si tocca con kubectl, non con systemctl. Torna alla tabella del visore se hai esitato.

Autoevaluación — antes de marcar M10 como ★ dominado

Self-check — before marking M10 as ★ mastered

Autovalutazione — prima di segnare M10 come ★ padroneggiato

  • Decidir en un comando si el problema es del control plane o de un nodo.
  • Recuperar un nodo NotReady con la secuencia status→journal→restart.
  • Leer el journal del kubelet con -p err y encontrar la causa.
  • Recuperar el apiserver sin kubectl, solo con crictl.
  • Distinguir "el container existe y murió" de "el container no existe".
  • Saber, para cada componente, si se toca con systemctl, con el manifiesto o con kubectl.
  • Reconocer Pending-sin-eventos como scheduler caído.
  • Descartar contexto, certificados y disco antes de asumir lo peor.
  • Decide in one command whether the problem is the control plane's or a node's.
  • Recover a NotReady node with the status→journal→restart sequence.
  • Read the kubelet's journal with -p err and find the cause.
  • Recover the apiserver without kubectl, with crictl alone.
  • Tell "the container exists and died" from "the container does not exist".
  • Know, for each component, whether it is touched with systemctl, the manifest, or kubectl.
  • Recognise Pending-with-no-events as a downed scheduler.
  • Rule out context, certificates and disk before assuming the worst.
  • Decidere in un comando se il problema è del control plane o di un nodo.
  • Recuperare un nodo NotReady con la sequenza status→journal→restart.
  • Leggere il journal del kubelet con -p err e trovare la causa.
  • Recuperare l'apiserver senza kubectl, con il solo crictl.
  • Distinguere "il container esiste ed è morto" da "il container non esiste".
  • Sapere, per ogni componente, se si tocca con systemctl, col manifest o con kubectl.
  • Riconoscere Pending-senza-eventi come scheduler caduto.
  • Escludere contesto, certificati e disco prima di temere il peggio.
Módulo 10 completado · Troubleshooting, parte 2 de 3 · Siguiente: DNS roto, services sin endpoints y conectividad pod-to-pod
Module 10 complete · Troubleshooting, part 2 of 3 · Next: broken DNS, services with no endpoints and pod-to-pod connectivity
Modulo 10 completato · Troubleshooting, parte 2 di 3 · Prossimo: DNS rotto, service senza endpoint e connettività pod-to-pod