CKA · Módulo 1CKA · Module 1CKA · Modulo 1K8s v1.3425% del examen25% of the exam25% dell'esame
Cluster Architecture: kubeadm, etcd y el control plane
Cluster Architecture: kubeadm, etcd and the control plane
Cluster Architecture: kubeadm, etcd e il control plane
El módulo más denso de la Fase 1. Cómo está construido un cluster, cómo se arma y se une un nodo, cómo se actualiza sin romperlo, y cómo proteger su corazón: etcd. Buena parte de esto ya lo viviste armando tu cluster.
The densest module of Phase 1. How a cluster is built, how you bootstrap it and join a node, how you upgrade it without breaking it, and how to protect its heart: etcd. You already lived much of this while building your own cluster.
Il modulo più denso della Fase 1. Com'è costruito un cluster, come si crea e si aggiunge un nodo, come si aggiorna senza romperlo, e come proteggerne il cuore: etcd. Buona parte l'hai già vissuta costruendo il tuo cluster.
Duración75 min
Duration75 min
Durata75 min
Peso examen25% (Cluster Arch)
Exam weight25% (Cluster Arch)
Peso d'esame25% (Cluster Arch)
Conecta conTroubleshooting 30%
Feeds intoTroubleshooting 30%
Collegato aTroubleshooting 30%
Snapshot clavepre-upgrade
Key snapshotpre-upgrade
Snapshot chiavepre-upgrade
El núcleo administrativo del CKA. Lo bueno: ya hiciste el 40% sin saberlo cuando armaste el cluster y debuggeaste etcd, el API server y el kubelet. Ahora le ponemos nombre formal a cada pieza y agregamos las dos operaciones que más caen: upgrade de cluster y etcd backup/restore. Ambas son destructivas para practicar — ahí entran tus snapshots.
The administrative core of the CKA. The good news: you already did 40% of it without noticing when you built the cluster and debugged etcd, the API server and the kubelet. Now each piece gets its formal name, plus the two operations that come up most: cluster upgrade and etcd backup/restore. Both are destructive to practise — that is what your snapshots are for.
Il nucleo amministrativo del CKA. La buona notizia: ne hai già fatto il 40% senza saperlo quando hai costruito il cluster e fatto debug di etcd, dell'API server e del kubelet. Ora ogni pezzo prende il suo nome formale, più le due operazioni che cadono di più: upgrade del cluster ed etcd backup/restore. Entrambe sono distruttive da provare — ecco a cosa servono gli snapshot.
1.1
Componentes del control plane
Control plane components
Componenti del control plane
etcd, apiserver, scheduler, controller-manager y kubelet. Qué hace cada uno y dónde vive.
etcd, apiserver, scheduler, controller-manager and kubelet. What each does and where it lives.
etcd, apiserver, scheduler, controller-manager e kubelet. Cosa fa ognuno e dove vive.
1.2
kubeadm init / join
Bootstrap del cluster, unir workers, tokens y certificados.
Bootstrapping the cluster, joining workers, tokens and certificates.
Bootstrap del cluster, aggiungere worker, token e certificati.
1.3
Upgrade del cluster
Cluster upgrade
Upgrade del cluster
drain → upgrade → kubelet → uncordon. El orden correcto, control plane y workers.
drain → upgrade → kubelet → uncordon. The right order, control plane and workers.
drain → upgrade → kubelet → uncordon. L'ordine giusto, control plane e worker.
1.4
etcd backup & restore
snapshot save con etcdctl, restore con etcdutl. El tema estrella del examen.
snapshot save with etcdctl, restore with etcdutl. The exam's headline topic.
snapshot save con etcdctl, restore con etcdutl. Il tema di punta dell'esame.
1.5
Control plane HA
HA control plane
Control plane HA
--control-plane-endpoint, join de control planes, quórum de etcd, stacked contra external.
--control-plane-endpoint, joining control planes, etcd quorum, stacked versus external.
--control-plane-endpoint, join dei control plane, quorum di etcd, stacked contro external.
★
Práctica · 8 ejercicios
Practice · 8 exercises
Pratica · 8 esercizi
Upgrade, etcd y 2 de troubleshooting. Todos destructivos: snapshot primero.
Upgrade, etcd and 2 troubleshooting drills. All destructive: snapshot first.
Upgrade, etcd e 2 di troubleshooting. Tutti distruttivi: prima lo snapshot.
1.1
Fundamento · 15 min
Foundation · 15 min
Fondamenta · 15 min
Componentes del control plane
Control plane components
Componenti del control plane
La base de todo. Sin esto, el resto del módulo flota en el aire.
The base of everything. Without it, the rest of the module floats.
La base di tutto. Senza questo, il resto del modulo galleggia.
Práctica · Verlos en tu cluster
Practice · See them in your cluster
Pratica · Vederli nel tuo cluster
Los static pods del control plane
The control plane's static pods
Gli static pod del control plane
En un cluster kubeadm los 4 componentes corren como static pods: sus manifiestos viven en una carpeta del disco y el kubelet los levanta solo, sin pasar por el scheduler.
In a kubeadm cluster the 4 components run as static pods: their manifests live in a folder on disk and the kubelet brings them up on its own, without going through the scheduler.
In un cluster kubeadm i 4 componenti girano come static pod: i loro manifest stanno in una cartella su disco e il kubelet li avvia da solo, senza passare dallo scheduler.
ls /etc/kubernetes/manifests/
# etcd.yaml kube-apiserver.yaml# kube-controller-manager.yaml kube-scheduler.yamlk get pods -n kube-system
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml
El kubelet no es un static pod
The kubelet is not a static pod
Il kubelet non è uno static pod
Corre en todos los nodos como servicio de systemd. Es quien lee esa carpeta.
It runs on every node as a systemd service. It is the one reading that folder.
Gira su tutti i nodi come servizio systemd. È lui che legge quella cartella.
El kubelet vigila/etc/kubernetes/manifests/. Si editás o movés un manifiesto de ahí, reacciona al instante: recrea o elimina el pod. Es la base de media docena de ejercicios de troubleshooting — y de la forma más rápida de reiniciar un componente del control plane.
The kubelet watches/etc/kubernetes/manifests/. Edit or move a manifest there and it reacts instantly: it recreates or removes the pod. That underpins half a dozen troubleshooting drills — and it is the fastest way to restart a control-plane component.
Il kubelet sorveglia/etc/kubernetes/manifests/. Se modifichi o sposti un manifest lì, reagisce all'istante: ricrea o elimina il pod. È alla base di una mezza dozzina di esercizi di troubleshooting — e del modo più rapido per riavviare un componente del control plane.
Teoría · Quién es quién
Theory · Who is who
Teoria · Chi è chi
El modelo "estado deseado"
The "desired state" model
Il modello "stato desiderato"
Vos declarás QUÉ querés; el cluster trabaja sin parar para que la realidad coincida. Los componentes hacen ese trabajo.
You declare WHAT you want; the cluster works nonstop to make reality match. The components do that work.
Tu dichiari COSA vuoi; il cluster lavora senza sosta perché la realtà coincida. I componenti fanno quel lavoro.
Componente
Función
Component
Role
Componente
Ruolo
etcd
Base de datos. Guarda TODO el estado del cluster
etcd
Database. Holds ALL cluster state
etcd
Database. Contiene TUTTO lo stato del cluster
kube-apiserver
Única puerta de entrada. Todo pasa por él; el único que habla con etcd
kube-apiserver
The single front door. Everything goes through it; the only one that talks to etcd
kube-apiserver
L'unica porta d'ingresso. Tutto passa da lui; l'unico che parla con etcd
kube-scheduler
Decide en qué nodo va cada pod nuevo
kube-scheduler
Decides which node each new pod lands on
kube-scheduler
Decide su quale nodo va ogni pod nuovo
controller-manager
Vigila que realidad = deseado. Recrea pods caídos, etc.
controller-manager
Keeps reality = desired. Recreates dead pods, etc.
controller-manager
Tiene realtà = desiderato. Ricrea i pod caduti, ecc.
kubelet
Agente en cada nodo. Recibe órdenes y arranca containers
kubelet
Agent on every node. Takes orders and starts containers
kubelet
Agente su ogni nodo. Riceve ordini e avvia i container
kube-proxy
Ruteo de red de los Services (Módulo 6)
kube-proxy
Service network routing (Module 6)
kube-proxy
Routing di rete dei Service (Modulo 6)
◆
Verlo en un diagrama: en Arquitectura están todos estos componentes ubicados en cp y en los workers, con quién le habla a quién y por qué puerto, flujos paso a paso (apply, curl a un Service, logs) y qué se rompe cuando cada uno se cae.
See it as a diagram:Architecture places all these components on cp and the workers, with who talks to whom and on which port, step-by-step flows (apply, curl to a Service, logs) and what breaks when each one goes down.
Vederlo in un diagramma: in Architettura ci sono tutti questi componenti su cp e sui worker, con chi parla con chi e su quale porta, flussi passo per passo (apply, curl a un Service, logs) e cosa si rompe quando ognuno cade.
★
etcd ES el cluster. Si lo perdés, perdés todo el estado aunque las VMs estén intactas. Por eso la sección 1.4 es la más importante del módulo.
etcd IS the cluster. Lose it and you lose all state even with the VMs untouched. That is why section 1.4 is the most important one here.
etcd È il cluster. Se lo perdi, perdi tutto lo stato anche con le VM intatte. Per questo la sezione 1.4 è la più importante del modulo.
Lo que ya viviste
What you already lived through
Quello che hai già vissuto
El bind: cannot assign requested address era etcd. El API server que no levantaba dependía de etcd. El kubelet reiniciándose en loop. Ya conocés a los actores; ahora sabés sus nombres.
That bind: cannot assign requested address was etcd. The API server that would not come up depended on etcd. The kubelet restarting in a loop. You already know the cast; now you know their names.
Quel bind: cannot assign requested address era etcd. L'API server che non partiva dipendeva da etcd. Il kubelet che si riavviava in loop. Conosci già gli attori; ora ne sai i nomi.
1.2
Bootstrap · 20 min
Bootstrap · 20 min
Bootstrap · 20 min
kubeadm init / join
Armar el cluster y unir nodos. Ya lo hiciste; acá lo formalizamos.
Build the cluster and join nodes. You have done it; here we formalise it.
Costruire il cluster e aggiungere nodi. L'hai già fatto; qui lo formalizziamo.
Práctica · Comandos
Practice · Commands
Pratica · Comandi
Inicializar el control plane
Initialise the control plane
Inizializzare il control plane
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=<IP-del-cp>
# configurar kubectl para tu usuario# set up kubectl for your user# configurare kubectl per il tuo utentemkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# instalar el CNI: sin él los nodos quedan NotReady# install the CNI: without it nodes stay NotReady# installare il CNI: senza, i nodi restano NotReadyk apply -f <calico.yaml>
Unir un worker
Join a worker
Aggiungere un worker
sudo kubeadm join <IP>:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
# si perdiste el token (dura 24 h), en el control plane:# if you lost the token (24 h lifetime), on the control plane:# se hai perso il token (dura 24 h), sul control plane:kubeadm token create --print-join-command
kubeadm token list
⚠
Los cuatro errores clásicos de armado, todos vividos: IP inexistente (etcd no bindea), containerd caído, el CRI deshabilitado en la config de containerd, y el kubeconfig faltante. Los cuatro caen en el examen. Anotalos.
The four classic bootstrap failures, all lived through: a non-existent IP (etcd cannot bind), containerd down, the CRI disabled in containerd's config, and a missing kubeconfig. All four show up in the exam. Write them down.
I quattro classici fallimenti di bootstrap, tutti vissuti: un IP inesistente (etcd non fa bind), containerd giù, il CRI disabilitato nella config di containerd, e il kubeconfig mancante. Tutti e quattro cadono all'esame. Annotali.
certs: genera i certificati in /etc/kubernetes/pki/.
kubeconfig: genera admin.conf, kubelet.conf, ecc.
control-plane: crea i manifest degli static pod.
etcd: crea lo static pod di etcd.
kubelet-start: avvia il kubelet.
bootstrap-token: crea il token perché i worker si uniscano.
Qué hace join
What join does
Cosa fa join
El worker contacta al API server, se valida con el token y el hash del CA, recibe sus certificados y arranca su kubelet. Por eso join necesita esos dos valores.
The worker contacts the API server, authenticates with the token and the CA hash, receives its certificates and starts its kubelet. That is why join needs both values.
Il worker contatta l'API server, si autentica con il token e l'hash della CA, riceve i suoi certificati e avvia il kubelet. Per questo join ha bisogno di entrambi i valori.
★
El discovery-token-ca-cert-hash es la confianza en el otro sentido: el worker verifica que el control plane es legítimo, no un impostor. El token autentica al worker; el hash autentica al cluster.
The discovery-token-ca-cert-hash is trust in the other direction: the worker verifies the control plane is legitimate, not an impostor. The token authenticates the worker; the hash authenticates the cluster.
Il discovery-token-ca-cert-hash è la fiducia nell'altro verso: il worker verifica che il control plane sia legittimo, non un impostore. Il token autentica il worker; l'hash autentica il cluster.
1.3
Operación crítica · 20 min
Critical operation · 20 min
Operazione critica · 20 min
Upgrade del cluster
Cluster upgrade
Upgrade del cluster
El orden importa. Equivocarse rompe el cluster. Practicalo en loop con snapshots.
Order matters. Getting it wrong breaks the cluster. Drill it on a loop with snapshots.
L'ordine conta. Sbagliare rompe il cluster. Allenalo in loop con gli snapshot.
◆
Antes de practicar: sacá el snapshot pre-upgrade con el cluster una minor atrás. Cada vez que termines (o rompas) un upgrade, restaurás y lo repetís. Esto se gana con repetición pura hasta que el orden sea automático.
Before practising: take the pre-upgrade snapshot with the cluster one minor behind. Every time you finish (or break) an upgrade, restore and repeat. This is won by pure repetition until the order is automatic.
Prima di esercitarti: fai lo snapshot pre-upgrade con il cluster una minor indietro. Ogni volta che finisci (o rompi) un upgrade, ripristini e ripeti. Questo si vince con la pura ripetizione finché l'ordine non diventa automatico.
★
Gotcha del salto de minor (1.33 → 1.34): el repo pkgs.k8s.io es por minor. Antes de instalar el kubeadm nuevo hay que actualizar /etc/apt/sources.list.d/kubernetes.list a la línea destino, si no apt te sigue ofreciendo solo la versión vieja. Además kubeadm upgrade apply <X> exige que el binario de kubeadm ya sea ≥ X: por eso se upgradea kubeadm primero. Un salto de patch dentro del mismo minor no necesita tocar el repo.
The minor-jump gotcha (1.33 → 1.34): the pkgs.k8s.io repo is per minor. Before installing the new kubeadm you must update /etc/apt/sources.list.d/kubernetes.list to the target line, otherwise apt keeps offering only the old version. On top of that, kubeadm upgrade apply <X> requires the kubeadm binary to already be ≥ X: that is why kubeadm is upgraded first. A patch jump within the same minor needs no repo change.
Il gotcha del salto di minor (1.33 → 1.34): il repo pkgs.k8s.io è per minor. Prima di installare il nuovo kubeadm devi aggiornare /etc/apt/sources.list.d/kubernetes.list alla riga di destinazione, altrimenti apt continua a offrirti solo la versione vecchia. Inoltre kubeadm upgrade apply <X> richiede che il binario di kubeadm sia già ≥ X: per questo kubeadm si aggiorna per primo. Un salto di patch nella stessa minor non richiede di toccare il repo.
Orden en el CONTROL PLANE
Order on the CONTROL PLANE
Ordine sul CONTROL PLANE
Actualizar el repo de apt a la línea destino (solo en salto de minor)
Point the apt repo at the target line (minor jumps only)
Puntare il repo apt alla riga di destinazione (solo salti di minor)
sudo sed -i 's#/v1.33/#/v1.34/#' /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
Casi igual, con dos diferencias: se usa kubeadm upgrade node en vez de apply, y el drain/uncordon se corren desde el control plane. El repo de apt hay que cambiarlo también en el worker: cada nodo tiene el suyo.
Nearly the same, with two differences: you use kubeadm upgrade node instead of apply, and drain/uncordon run from the control plane. The apt repo must be changed on the worker too: each node has its own.
Quasi identico, con due differenze: si usa kubeadm upgrade node invece di apply, e drain/uncordon si eseguono dal control plane. Anche sul worker va cambiato il repo apt: ogni nodo ha il suo.
Regla de oro: control plane PRIMERO, workers DESPUÉS, de a uno. Y dentro de cada nodo: kubeadm → drain → kubelet → uncordon. El drain protege las cargas moviéndolas antes de tocar el nodo; el uncordon lo reincorpora al final.
Golden rule: control plane FIRST, workers AFTER, one at a time. And within each node: kubeadm → drain → kubelet → uncordon. The drain protects workloads by moving them before you touch the node; the uncordon brings it back at the end.
Regola d'oro: control plane PRIMA, worker DOPO, uno alla volta. E dentro ogni nodo: kubeadm → drain → kubelet → uncordon. Il drain protegge i carichi spostandoli prima di toccare il nodo; l'uncordon lo reintegra alla fine.
⚠
El --ignore-daemonsets del drain no es opcional: los DaemonSets (kube-proxy, calico-node) corren en todos los nodos y no se pueden mover, así que sin ese flag el drain falla. Si hay pods con almacenamiento local vas a necesitar además --delete-emptydir-data.
--ignore-daemonsets on the drain is not optional: DaemonSets (kube-proxy, calico-node) run on every node and cannot be moved, so without that flag the drain fails. With pods using local storage you will also need --delete-emptydir-data.
--ignore-daemonsets nel drain non è opzionale: i DaemonSet (kube-proxy, calico-node) girano su ogni nodo e non si possono spostare, quindi senza quel flag il drain fallisce. Con pod che usano storage locale ti servirà anche --delete-emptydir-data.
VisorExplorerVisore · el orden del upgrade, nodo por nodothe upgrade order, node by nodel'ordine dell'upgrade, nodo per nodo
Un nodo a la vez, y siempre el control plane primero. El drain es lo que hace que el upgrade no corte servicio.
One node at a time, control plane always first. The drain is what keeps the upgrade from cutting service.
Un nodo alla volta, sempre il control plane per primo. È il drain a impedire che l'upgrade interrompa il servizio.
1.4
El tema estrella · 20 min
The headline topic · 20 min
Il tema di punta · 20 min
etcd backup & restore
Cae casi siempre. Protegés el corazón del cluster.
It shows up almost every time. You are protecting the cluster's heart.
Cade quasi sempre. Stai proteggendo il cuore del cluster.
Práctica · etcdctl y etcdutl
Practice · etcdctl and etcdutl
Pratica · etcdctl ed etcdutl
Las credenciales que siempre necesitás
The credentials you always need
Le credenziali che servono sempre
etcdctl habla con etcd por TLS. Estos cuatro valores van en casi todos los comandos:
etcdctl talks to etcd over TLS. These four values go in nearly every command:
etcdctl parla con etcd via TLS. Questi quattro valori vanno in quasi ogni comando:
# 1 · restaurar a un data-dir NUEVO# 1 · restore into a NEW data-dir# 1 · ripristinare in un data-dir NUOVOsudo etcdutl snapshot restore /opt/backup.db \
--data-dir=/var/lib/etcd-restore
# etcd ≤ 3.5: sudo ETCDCTL_API=3 etcdctl snapshot restore … (mismos flags)# etcd ≤ 3.5: sudo ETCDCTL_API=3 etcdctl snapshot restore … (same flags)# etcd ≤ 3.5: sudo ETCDCTL_API=3 etcdctl snapshot restore … (stessi flag)# 2 · apuntar etcd al nuevo data-dir# 2 · point etcd at the new data-dir# 2 · puntare etcd al nuovo data-dirsudo vim /etc/kubernetes/manifests/etcd.yaml
# 3 · el kubelet recrea etcd solo al detectar el cambio# 3 · the kubelet recreates etcd on its own when it sees the change# 3 · il kubelet ricrea etcd da solo quando vede la modificak get pods -n kube-system
Anatomía de etcd.yaml — dónde tocar
Anatomy of etcd.yaml — what to touch
Anatomia di etcd.yaml — cosa toccare
# /var/lib/etcd aparece en 3 lugares. Cambiá SOLO el (3):# /var/lib/etcd appears in 3 places. Change ONLY (3):# /var/lib/etcd compare in 3 punti. Cambia SOLO il (3):spec:
containers:
- command:
- etcd
- --data-dir=/var/lib/etcd# (1) NO tocar# (1) do NOT touch# (1) NON toccarevolumeMounts:
- mountPath: /var/lib/etcd# (2) NO tocar# (2) do NOT touch# (2) NON toccarename: etcd-data
volumes:
- hostPath:
path: /var/lib/etcd# (3) SOLO ESTE → /var/lib/etcd-restore# (3) ONLY THIS ONE → /var/lib/etcd-restore# (3) SOLO QUESTO → /var/lib/etcd-restoretype: DirectoryOrCreate
name: etcd-data
★
Por qué solo el hostPath: adentro del contenedor etcd siempre usa /var/lib/etcd — eso son el --data-dir y el mountPath. Lo único que cambiás es de qué carpeta del host sale ese contenido. Si además tocás los otros dos, etcd busca los datos donde no están, el pod entra en CrashLoopBackOff y se cae el cluster. Cambiar los tres "para que coincidan" es EL error que rompe el restore.
Why only the hostPath: inside the container etcd always uses /var/lib/etcd — that is what --data-dir and mountPath are. The only thing you change is which host folder that content comes from. Touch the other two as well and etcd looks for data where there is none, the pod goes CrashLoopBackOff and the cluster goes down. Changing all three "so they match" is THE mistake that breaks the restore.
Perché solo l'hostPath: dentro il container etcd usa sempre /var/lib/etcd — sono --data-dir e mountPath. L'unica cosa che cambi è da quale cartella dell'host arriva quel contenuto. Se tocchi anche gli altri due, etcd cerca i dati dove non ci sono, il pod va in CrashLoopBackOff e il cluster cade. Cambiare tutti e tre "perché coincidano" è L'errore che rompe il restore.
Teoría · Por qué y cómo
Theory · Why and how
Teoria · Perché e come
Qué es un backup de etcd
What an etcd backup is
Cos'è un backup di etcd
Un snapshot de etcd es una foto completa del estado del cluster en ese instante: todos los objetos, todo. Restaurarlo es viajar en el tiempo a ese momento.
An etcd snapshot is a complete photograph of cluster state at that instant: every object, everything. Restoring it is time travel back to that moment.
Uno snapshot di etcd è una fotografia completa dello stato del cluster in quell'istante: ogni oggetto, tutto. Ripristinarlo è viaggiare indietro a quel momento.
Paso
Qué hace
Step
What it does
Passo
Cosa fa
restore
Desempaqueta el .db en un data-dir nuevo
restore
Unpacks the .db into a new data-dir
restore
Estrae il .db in un data-dir nuovo
editar manifest
Decirle a etcd que use ese data-dir
edit manifest
Tell etcd to use that data-dir
modificare manifest
Dire a etcd di usare quel data-dir
kubelet recrea
Al cambiar el static pod, etcd reinicia con los datos restaurados
kubelet recreates
The static pod changed, so etcd restarts on the restored data
il kubelet ricrea
Cambiato lo static pod, etcd riparte sui dati ripristinati
★
etcdctl vs etcdutl. El snapshot save es con etcdctl porque habla con un etcd vivo. El snapshot restore es offline: en etcd 3.6+ (K8s 1.34) se usa etcdutl — a etcdctl le sacaron el restore. En etcd ≤3.5 sigue siendo etcdctl snapshot restore.
etcdctl vs etcdutl.snapshot save uses etcdctl because it talks to a live etcd. snapshot restore is offline: on etcd 3.6+ (K8s 1.34) you use etcdutl — restore was removed from etcdctl. On etcd ≤3.5 it is still etcdctl snapshot restore.
etcdctl contro etcdutl.snapshot save usa etcdctl perché parla con un etcd vivo. snapshot restore è offline: su etcd 3.6+ (K8s 1.34) si usa etcdutl — il restore è stato tolto da etcdctl. Su etcd ≤3.5 resta etcdctl snapshot restore.
⚠
La herramienta debe matchear la versión del server. Restaurar con un etcdctl 3.4 contra un etcd 3.6 genera un data-dir que el server no puede bootear: panic al reaplicar el raft log, y el cluster no vuelve. En el examen las herramientas provistas ya matchean.
The tool must match the server version. Restoring with etcdctl 3.4 against an etcd 3.6 produces a data-dir the server cannot boot: a panic replaying the raft log, and the cluster does not come back. In the exam the provided tools already match.
Lo strumento deve corrispondere alla versione del server. Ripristinare con un etcdctl 3.4 contro un etcd 3.6 produce un data-dir che il server non riesce ad avviare: panic nel riapplicare il raft log, e il cluster non torna. All'esame gli strumenti forniti corrispondono già.
★
Truco: los paths de los certificados salen del propio manifiesto: sudo grep file /etc/kubernetes/manifests/etcd.yaml. Si no te acordás las rutas, ahí están. Y poné siempre ETCDCTL_API=3: no molesta y evita sorpresas.
Trick: the certificate paths come straight from the manifest: sudo grep file /etc/kubernetes/manifests/etcd.yaml. If you cannot recall the paths, they are right there. And always set ETCDCTL_API=3: it costs nothing and avoids surprises.
Trucco: i path dei certificati escono dal manifest stesso: sudo grep file /etc/kubernetes/manifests/etcd.yaml. Se non ricordi i percorsi, sono lì. E metti sempre ETCDCTL_API=3: non costa nulla ed evita sorprese.
◆
Practicá destructivo: restaurá a cluster-ready, hacé un backup, borrá un deployment a propósito, restaurá el backup y verificá que el deployment volvió. Si rompés etcd, restaurás el snapshot de la VM y reintentás.
Practise destructively: restore to cluster-ready, take a backup, delete a deployment on purpose, restore the backup and verify the deployment came back. If you break etcd, restore the VM snapshot and try again.
Esercitati in modo distruttivo: ripristina a cluster-ready, fai un backup, cancella un deployment di proposito, ripristina il backup e verifica che il deployment sia tornato. Se rompi etcd, ripristini lo snapshot della VM e riprovi.
1.5
Competencia oficial · 25 min
Official competency · 25 min
Competenza ufficiale · 25 min
Control plane en alta disponibilidad
Highly-available control plane
Control plane in alta disponibilità
Varios control planes detrás de un endpoint estable. En el examen pesa el concepto y los flags de kubeadm.
Several control planes behind a stable endpoint. In the exam the concept and the kubeadm flags carry the weight.
Più control plane dietro un endpoint stabile. All'esame contano il concetto e i flag di kubeadm.
Práctica · kubeadm con varios control planes
Practice · kubeadm with several control planes
Pratica · kubeadm con più control plane
La topología (etcd "stacked")
The topology ("stacked" etcd)
La topologia (etcd "stacked")
k8s-api.lab:6443 # el endpoint estable (LB o DNS)# the stable endpoint (LB or DNS)# l'endpoint stabile (LB o DNS)
┌──────────────┼──────────────┐
cp1 cp2 cp3
apiserver apiserver apiserver # los 3 activos# all 3 active# tutti e 3 attivi
scheduler scheduler scheduler # 1 líder, 2 en espera# 1 leader, 2 standby# 1 leader, 2 in attesa
ctrl-mgr ctrl-mgr ctrl-mgr # 1 líder, 2 en espera# 1 leader, 2 standby# 1 leader, 2 in attesa
etcd ◄───────► etcd ◄───────► etcd # un cluster raft, :2380# one raft cluster, :2380# un cluster raft, :2380
└──────────── workers ────────┘ # kubelets → k8s-api.lab:6443# kubelets → k8s-api.lab:6443# kubelet → k8s-api.lab:6443
1 · Init del primer control plane
1 · Init the first control plane
1 · Init del primo control plane
sudo kubeadm init \
--control-plane-endpoint "k8s-api.lab:6443" \ # ← la clave de todo# ← the key to everything# ← la chiave di tutto
--upload-certs \ # sube los certs al Secret kubeadm-certs# uploads the certs to the kubeadm-certs Secret# carica i cert nel Secret kubeadm-certs
--pod-network-cidr=192.168.0.0/16
# La salida trae DOS comandos de join:# The output prints TWO join commands:# L'output stampa DUE comandi di join:# - uno con --control-plane --certificate-key → para otro control plane# - one with --control-plane --certificate-key → for another control plane# - uno con --control-plane --certificate-key → per un altro control plane# - uno sin esos flags → para un worker# - one without those flags → for a worker# - uno senza quei flag → per un worker
2 · Sumar otro control plane
2 · Add another control plane
2 · Aggiungere un altro control plane
# en cp2 (y cp3): el join de worker + dos flags# on cp2 (and cp3): the worker join + two flags# su cp2 (e cp3): il join da worker + due flagsudo kubeadm join k8s-api.lab:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane \ # "este nodo es control plane"# "this node is a control plane"# "questo nodo è control plane"
--certificate-key <key> # descifra los certs subidos# decrypts the uploaded certs# decifra i cert caricati
3 · Si el token o la key ya vencieron
3 · If the token or the key has expired
3 · Se il token o la key sono scaduti
# en un control plane que ya funciona:# on a control plane that already works:# su un control plane già funzionante:sudo kubeadm init phase upload-certs --upload-certs # imprime una certificate-key nueva (dura 2 h)# prints a new certificate-key (lasts 2 h)# stampa una nuova certificate-key (dura 2 h)kubeadm token create --print-join-command # join de worker nuevo (el token dura 24 h)# fresh worker join (the token lasts 24 h)# join da worker nuovo (il token dura 24 h)# join de control plane = ese comando + --control-plane --certificate-key <la nueva># control-plane join = that command + --control-plane --certificate-key <the new one># join di control plane = quel comando + --control-plane --certificate-key <la nuova>
4 · Verificar el estado
4 · Check the state
4 · Verificare lo stato
k get nodes -l node-role.kubernetes.io/control-plane
k -n kube-system get cm kubeadm-config -o yaml | grep controlPlaneEndpoint
# ¿quién es el líder ahora?# who is the leader right now?# chi è il leader adesso?k -n kube-system get lease kube-scheduler kube-controller-manager
# miembros de etcd (etcdctl corre dentro del pod de etcd)# etcd members (etcdctl runs inside the etcd pod)# membri di etcd (etcdctl gira dentro il pod di etcd)k -n kube-system exec etcd-cp1 -- 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 \
member list -w table
★
Lo que suele caer: unir un control plane (armar el join con --control-plane --certificate-key, regenerando la key si venció), cuántas fallas tolera un etcd de N miembros, y encontrar el endpoint en el ConfigMap kubeadm-config. No te van a pedir instalar un load balancer.
What tends to show up: joining a control plane (building the join with --control-plane --certificate-key, regenerating the key if it expired), how many failures an N-member etcd tolerates, and finding the endpoint in the kubeadm-config ConfigMap. You will not be asked to install a load balancer.
Quello che cade di solito: unire un control plane (costruire il join con --control-plane --certificate-key, rigenerando la key se è scaduta), quanti guasti tollera un etcd di N membri, e trovare l'endpoint nel ConfigMap kubeadm-config. Non ti chiederanno di installare un load balancer.
⚠
--control-plane-endpoint se decide en el init. Un cluster creado sin él (como el tuyo de práctica: probá el grep de arriba, no devuelve nada) no se convierte en HA con un join: habría que regenerar certificados del apiserver y todos los kubeconfigs. Por eso se usa un nombre DNS aunque al principio haya un solo nodo.
--control-plane-endpoint is decided at init time. A cluster created without it (like your practice one: try the grep above, it returns nothing) does not become HA with a join: you would have to regenerate the apiserver certificates and every kubeconfig. That is why a DNS name is used even when there is only one node at first.
--control-plane-endpoint si decide all'init. Un cluster creato senza (come il tuo di pratica: prova il grep sopra, non restituisce niente) non diventa HA con un join: bisognerebbe rigenerare i certificati dell'apiserver e tutti i kubeconfig. Per questo si usa un nome DNS anche quando all'inizio c'è un solo nodo.
Teoría · Qué se replica y cómo
Theory · What is replicated and how
Teoria · Cosa si replica e come
Cada componente se replica distinto
Each component replicates differently
Ogni componente si replica in modo diverso
Componente
Modo
Por qué
Component
Mode
Why
Componente
Modo
Perché
kube-apiserver
Activo-activo
No guarda estado (todo está en etcd): cualquiera atiende, el LB reparte
kube-apiserver
Active-active
It keeps no state (everything is in etcd): any of them serves, the LB spreads load
kube-apiserver
Attivo-attivo
Non tiene stato (è tutto in etcd): uno qualsiasi risponde, il LB distribuisce
scheduler, controller-manager
Activo-pasivo
Si dos decidieran a la vez habría conflictos: eligen un líder con un objeto Lease
scheduler, controller-manager
Active-passive
Two deciding at once would conflict: they elect a leader through a Lease object
scheduler, controller-manager
Attivo-passivo
Se due decidessero insieme ci sarebbero conflitti: eleggono un leader con un oggetto Lease
etcd
Consenso (raft)
Cada escritura necesita la confirmación de la mayoría de los miembros
etcd
Consensus (raft)
Every write needs confirmation from a majority of the members
etcd
Consenso (raft)
Ogni scrittura richiede la conferma della maggioranza dei membri
Quórum: por qué siempre impar
Quorum: why always odd
Quorum: perché sempre dispari
El quórum es la mayoría estricta: ⌊N/2⌋ + 1. Si quedan menos miembros vivos, etcd deja de aceptar escrituras y el cluster queda de solo lectura.
Quorum is a strict majority: ⌊N/2⌋ + 1. With fewer members alive, etcd stops accepting writes and the cluster becomes read-only.
Il quorum è la maggioranza stretta: ⌊N/2⌋ + 1. Se restano meno membri vivi, etcd smette di accettare scritture e il cluster diventa di sola lettura.
Miembros
Quórum
Tolera caídos
Members
Quorum
Failures tolerated
Membri
Quorum
Guasti tollerati
1
1
0
2
2
0
3
2
1
4
3
1
5
3
2
Pasar de 3 a 4 no suma tolerancia (sigue en 1) y agrega un miembro más que puede fallar. Con 2 es peor que con 1: si cae cualquiera, no hay mayoría. Por eso 3 o 5.
Going from 3 to 4 adds no tolerance (still 1) and adds one more member that can fail. Two is worse than one: if either fails, there is no majority. Hence 3 or 5.
Passare da 3 a 4 non aggiunge tolleranza (resta 1) e aggiunge un membro in più che può guastarsi. Con 2 è peggio che con 1: se ne cade uno qualsiasi, non c'è maggioranza. Per questo 3 o 5.
Stacked contra external etcd
Stacked versus external etcd
Stacked contro external etcd
Stacked
External
Stacked
External
Stacked
External
Dónde corre etcd
En los mismos nodos del control plane (static pod)
En nodos propios
Where etcd runs
On the control plane nodes themselves (static pod)
On dedicated nodes
Dove gira etcd
Sugli stessi nodi del control plane (static pod)
Su nodi propri
Nodos mínimos
3
6 (3 control plane + 3 etcd)
Minimum nodes
3
6 (3 control plane + 3 etcd)
Nodi minimi
3
6 (3 control plane + 3 etcd)
Riesgo
Perder un nodo = perder un apiserver y un miembro de etcd
Las fallas están separadas
Risk
Losing a node = losing an apiserver and an etcd member
Failures are decoupled
Rischio
Perdere un nodo = perdere un apiserver e un membro di etcd
I guasti sono separati
Con kubeadm
Lo que hace por defecto
etcd.external en la ClusterConfiguration
With kubeadm
What it does by default
etcd.external in the ClusterConfiguration
Con kubeadm
Quello che fa di default
etcd.external nella ClusterConfiguration
El endpoint estable
The stable endpoint
L'endpoint stabile
Kubelets, kubectl y los propios componentes apuntan a una dirección (server: en cada kubeconfig). Si apuntaran a la IP de cp1 y cp1 cae, todo pierde el cluster aunque cp2 y cp3 anden. El endpoint lo resuelve un load balancer (HAProxy + keepalived, o kube-vip como static pod) o un DNS que apunte a los tres. Y el nombre tiene que estar en los SANs del certificado del apiserver, que kubeadm agrega solo si lo pasaste en el init.
Kubelets, kubectl and the components themselves point to one address (server: in every kubeconfig). If they pointed to cp1's IP and cp1 died, everything would lose the cluster even with cp2 and cp3 up. The endpoint is provided by a load balancer (HAProxy + keepalived, or kube-vip as a static pod) or a DNS name pointing to all three. And the name must be in the apiserver certificate SANs, which kubeadm adds only if you passed it at init.
Kubelet, kubectl e i componenti stessi puntano a un indirizzo (server: in ogni kubeconfig). Se puntassero all'IP di cp1 e cp1 cadesse, tutto perderebbe il cluster anche con cp2 e cp3 attivi. L'endpoint lo fornisce un load balancer (HAProxy + keepalived, o kube-vip come static pod) o un DNS che punta a tutti e tre. E il nome deve stare nei SAN del certificato dell'apiserver, che kubeadm aggiunge solo se l'hai passato all'init.
★
En tu cluster de práctica ya podés ver la elección de líder: k -n kube-system get lease kube-scheduler muestra en HOLDER qué instancia manda. Con un solo control plane siempre es cp; en HA, si matás al líder, en unos segundos otro toma el Lease.
You can already see leader election on your practice cluster: k -n kube-system get lease kube-scheduler shows in HOLDER which instance is in charge. With one control plane it is always cp; in HA, kill the leader and another takes the Lease within seconds.
Nel tuo cluster di pratica puoi già vedere l'elezione del leader: k -n kube-system get lease kube-scheduler mostra in HOLDER quale istanza comanda. Con un solo control plane è sempre cp; in HA, se uccidi il leader, in pochi secondi un altro prende il Lease.
★
Cierre del módulo
Module wrap-up
Chiusura del modulo
Lo que te llevás del Módulo 1
What you take from Module 1
Cosa porti via dal Modulo 1
Resumen · Comandos clave
Summary · Key commands
Riassunto · Comandi chiave
# componentes del control plane# control plane components# componenti del control planels /etc/kubernetes/manifests/
k get pods -n kube-system
# token de join nuevo# fresh join token# nuovo token di joinkubeadm token create --print-join-command
# upgrade (orden): repo → kubeadm → plan → apply →# upgrade (order): repo → kubeadm → plan → apply →# upgrade (ordine): repo → kubeadm → plan → apply →# drain → kubelet → uncordon# etcd backup# etcd backup# etcd backupsudo ETCDCTL_API=3 etcdctl snapshot save /opt/backup.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=…ca.crt --cert=…server.crt --key=…server.key
# etcd restore (3.6+ = etcdutl · ≤3.5 = etcdctl)# etcd restore (3.6+ = etcdutl · ≤3.5 = etcdctl)# etcd restore (3.6+ = etcdutl · ≤3.5 = etcdctl)sudo etcdutl snapshot restore /opt/backup.db \
--data-dir=/var/lib/etcd-restore
# + editar etcd.yaml: SOLO el hostPath del volumen etcd-data# + edit etcd.yaml: ONLY the hostPath of the etcd-data volume# + modificare etcd.yaml: SOLO l'hostPath del volume etcd-data
Teoría · Lo esencial
Theory · The essentials
Teoria · L'essenziale
Las 4 ideas que no se negocian
The 4 non-negotiable ideas
Le 4 idee non negoziabili
etcd ES el cluster. Todo el estado vive ahí.
El control plane son static pods en /etc/kubernetes/manifests/, y el kubelet los vigila.
Upgrade: control plane primero, workers después, de a uno. drain antes, uncordon después.
etcd: save con etcdctl, restore con etcdutl a un data-dir nuevo, y tocar solo el hostPath.
etcd IS the cluster. All state lives there.
The control plane is static pods in /etc/kubernetes/manifests/, watched by the kubelet.
Upgrade: control plane first, workers after, one at a time. drain before, uncordon after.
etcd: save with etcdctl, restore with etcdutl into a new data-dir, and touch only the hostPath.
etcd È il cluster. Tutto lo stato vive lì.
Il control plane sono static pod in /etc/kubernetes/manifests/, sorvegliati dal kubelet.
Upgrade: prima il control plane, poi i worker, uno alla volta. drain prima, uncordon dopo.
etcd: save con etcdctl, restore con etcdutl in un data-dir nuovo, e toccare solo l'hostPath.
★
Anotá a mano los comandos de etcd y el orden del upgrade. Son los dos que más se preguntan y los que más se olvidan bajo presión.
Write the etcd commands and the upgrade order out by hand. They are the two most asked and the two most forgotten under pressure.
Trascrivi a mano i comandi di etcd e l'ordine dell'upgrade. Sono i due più chiesti e i due più dimenticati sotto pressione.
Reconocimiento, upgrade, etcd y 2 de troubleshooting. Casi todos destructivos.
Recon, upgrade, etcd and 2 troubleshooting drills. Nearly all destructive.
Ricognizione, upgrade, etcd e 2 di troubleshooting. Quasi tutti distruttivi.
0 / 8
◆
Snapshot ANTES de empezar. Este módulo rompe el cluster de verdad: E3/E4 lo actualizan, E6 le cambia el data-dir a etcd y T1/T2 lo dejan sin control plane. Trabajá siempre desde cluster-ready o pre-upgrade, y restaurá entre ejercicios. Sin snapshots esto es una tarde perdida, no una práctica.
Snapshot BEFORE you start. This module genuinely breaks the cluster: E3/E4 upgrade it, E6 changes etcd's data-dir and T1/T2 leave it with no control plane. Always work from cluster-ready or pre-upgrade, and restore between exercises. Without snapshots this is a lost afternoon, not practice.
Snapshot PRIMA di cominciare. Questo modulo rompe il cluster sul serio: E3/E4 lo aggiornano, E6 cambia il data-dir di etcd e T1/T2 lo lasciano senza control plane. Lavora sempre da cluster-ready o pre-upgrade, e ripristina fra un esercizio e l'altro. Senza snapshot questo è un pomeriggio perso, non pratica.
🧠
Modelo mental. Todo el módulo se apoya en dos hechos: el kubelet vigila una carpeta (por eso los static pods se arreglan editando archivos) y etcd guarda todo (por eso el backup es la póliza de seguro). El upgrade es un procedimiento con un orden que no se negocia.
Mental model. The whole module rests on two facts: the kubelet watches a folder (which is why static pods are fixed by editing files) and etcd holds everything (which is why the backup is the insurance policy). The upgrade is a procedure whose order is not negotiable.
Modello mentale. Tutto il modulo poggia su due fatti: il kubelet sorveglia una cartella (per questo gli static pod si aggiustano modificando file) ed etcd contiene tutto (per questo il backup è la polizza assicurativa). L'upgrade è una procedura il cui ordine non si negozia.
E1
Reconocimiento del control plane
Control plane recon
Ricognizione del control plane
~4 min
Sin abrir la documentación, contestá con un comando cada una: ¿qué versión corre cada nodo? ¿Qué static pods hay y dónde están sus manifiestos? ¿En qué puerto escucha etcd y con qué certificados? ¿Está sano el kubelet del worker? ¿Cuándo vencen los certificados del cluster?
Without opening the docs, answer each with one command: which version does each node run? Which static pods exist and where are their manifests? Which port does etcd listen on, and with which certificates? Is the worker's kubelet healthy? When do the cluster certificates expire?
Senza aprire la documentazione, rispondi a ciascuna con un comando: quale versione esegue ogni nodo? Quali static pod esistono e dove sono i loro manifest? Su quale porta ascolta etcd e con quali certificati? Il kubelet del worker è sano? Quando scadono i certificati del cluster?
Ver soluciónShow solutionMostra soluzione
k get nodes -o wide
ls /etc/kubernetes/manifests/
sudo grep -E 'listen-client|file' /etc/kubernetes/manifests/etcd.yaml
sudo systemctl status kubelet # en el worker# on the worker# sul workersudo kubeadm certs check-expiration
Claves
Key points
Punti chiave
El manifiesto de etcd es tu chuleta de rutas: grep file te da los tres certificados sin buscar en la documentación.
kubeadm certs check-expiration aparece poco en el material y sí en el examen: los certs de kubeadm duran un año y se renuevan con kubeadm certs renew all.
El kubelet se diagnostica con systemctl y journalctl, no con kubectl: es un servicio del host, no un pod.
The etcd manifest is your path cheat sheet: grep file gives you the three certificates without opening the docs.
kubeadm certs check-expiration barely appears in study material but does in the exam: kubeadm certs last a year and renew with kubeadm certs renew all.
You diagnose the kubelet with systemctl and journalctl, not kubectl: it is a host service, not a pod.
Il manifest di etcd è il tuo bigliettino dei percorsi: grep file ti dà i tre certificati senza aprire la documentazione.
kubeadm certs check-expiration compare poco nel materiale ma sì all'esame: i cert di kubeadm durano un anno e si rinnovano con kubeadm certs renew all.
Il kubelet si diagnostica con systemctl e journalctl, non con kubectl: è un servizio dell'host, non un pod.
E2
Sumar un worker con el token vencido
Join a worker with an expired token
Aggiungere un worker con il token scaduto
~5 min
Pasaron más de 24 horas desde el init y querés sumar un nodo. El token original ya no sirve. Generá lo necesario y unilo. Después sacá el nodo del cluster de forma limpia.
More than 24 hours have passed since init and you want to add a node. The original token is dead. Generate what you need and join it. Then remove the node from the cluster cleanly.
Sono passate più di 24 ore dall'init e vuoi aggiungere un nodo. Il token originale non vale più. Genera quello che serve e uniscilo. Poi togli il nodo dal cluster in modo pulito.
Ver soluciónShow solutionMostra soluzione
# en el control plane: genera token + hash y arma el comando entero# on the control plane: generates token + hash and builds the whole command# sul control plane: genera token + hash e compone l'intero comandokubeadm token create --print-join-command
# en el nodo nuevo, pegar la salida:# on the new node, paste the output:# sul nodo nuovo, incolla l'output:sudo kubeadm join <IP>:6443 --token … --discovery-token-ca-cert-hash sha256:…
k get nodes
# sacarlo limpio: drenar, borrarlo del API, y resetear el nodo# remove it cleanly: drain, delete from the API, reset the node# toglierlo pulito: drenare, cancellarlo dall'API, resettare il nodok drain w2 --ignore-daemonsets --delete-emptydir-data
k delete node w2
sudo kubeadm reset -f # en w2# on w2# su w2
Claves
Key points
Punti chiave
--print-join-command te ahorra calcular el hash del CA a mano. Es el comando que hay que recordar.
Sacar un nodo son tres pasos: drain (mover cargas), delete node (sacarlo del API) y kubeadm reset (limpiar el nodo). Saltear el reset deja basura que rompe un join posterior.
Un token dura 24 h por diseño: es una credencial de bootstrap, no permanente.
--print-join-command saves you computing the CA hash by hand. That is the command to remember.
Removing a node is three steps: drain (move workloads), delete node (remove it from the API) and kubeadm reset (clean the node). Skipping the reset leaves debris that breaks a later join.
A token lasts 24 h by design: it is a bootstrap credential, not a permanent one.
--print-join-command ti risparmia di calcolare l'hash della CA a mano. È il comando da ricordare.
Togliere un nodo sono tre passi: drain (spostare i carichi), delete node (toglierlo dall'API) e kubeadm reset (pulire il nodo). Saltare il reset lascia residui che rompono un join successivo.
Un token dura 24 h per design: è una credenziale di bootstrap, non permanente.
E3
Upgrade del control plane (salto de minor)
Control plane upgrade (minor jump)
Upgrade del control plane (salto di minor)
~12 min
Partiendo del snapshot pre-upgrade (cluster en 1.33.x), llevá el control plane a 1.34.x. El worker queda como está: es el ejercicio siguiente. Verificá al final que k get nodes muestra las dos versiones distintas — y explicá por qué eso está bien.
Starting from the pre-upgrade snapshot (cluster on 1.33.x), take the control plane to 1.34.x. Leave the worker as it is: that is the next exercise. At the end verify that k get nodes shows two different versions — and explain why that is fine.
Partendo dallo snapshot pre-upgrade (cluster su 1.33.x), porta il control plane a 1.34.x. Il worker resta com'è: è l'esercizio successivo. Alla fine verifica che k get nodes mostri due versioni diverse — e spiega perché va bene così.
Ver soluciónShow solutionMostra soluzione
sudo sed -i 's#/v1.33/#/v1.34/#' /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-mark unhold kubeadm
sudo apt-get install -y kubeadm=1.34.3-1.1
sudo apt-mark hold kubeadm
kubeadm version
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.34.3
k drain cp1 --ignore-daemonsets
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.34.3-1.1 kubectl=1.34.3-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload && sudo systemctl restart kubelet
k uncordon cp1
k get nodes # cp1 en 1.34.3, w1 todavía en 1.33.x# cp1 on 1.34.3, w1 still on 1.33.x# cp1 su 1.34.3, w1 ancora su 1.33.x
Claves
Key points
Punti chiave
Sin cambiar el repo, apt no ve la versión nueva y te da un "no candidate" confuso. Es el paso que más se olvida en un salto de minor.
Por qué está bien la asimetría: el skew policy permite que el kubelet esté hasta 3 minors por detrás del apiserver, nunca por delante. Control plane primero siempre.
upgrade apply reescribe los static pods y renueva certificados de paso; el kubelet del nodo se actualiza aparte.
Without changing the repo, apt cannot see the new version and gives you a confusing "no candidate". It is the most forgotten step in a minor jump.
Why the asymmetry is fine: the skew policy lets the kubelet be up to 3 minors behind the apiserver, never ahead. Control plane first, always.
upgrade apply rewrites the static pods and renews certificates on the way; the node's kubelet is upgraded separately.
Senza cambiare il repo, apt non vede la versione nuova e ti dà un "no candidate" confuso. È il passo più dimenticato in un salto di minor.
Perché l'asimmetria va bene: la skew policy consente al kubelet di essere fino a 3 minor dietro l'apiserver, mai avanti. Control plane per primo, sempre.
upgrade apply riscrive gli static pod e rinnova i certificati strada facendo; il kubelet del nodo si aggiorna a parte.
E4
Upgrade del worker
Worker upgrade
Upgrade del worker
~8 min
Terminá el upgrade llevando w1 a 1.34.x. Antes de drenar, dejá corriendo un Deployment con 2 réplicas en el worker y observá qué les pasa durante el drain. Prestá atención a qué comandos se corren en qué máquina.
Finish the upgrade by taking w1 to 1.34.x. Before draining, leave a Deployment with 2 replicas running on the worker and watch what happens to them during the drain. Pay attention to which commands run on which machine.
Completa l'upgrade portando w1 a 1.34.x. Prima di drenare, lascia in esecuzione un Deployment con 2 repliche sul worker e osserva cosa succede loro durante il drain. Fai attenzione a quali comandi girano su quale macchina.
Ver soluciónShow solutionMostra soluzione
# EN EL WORKER: repo + kubeadm# ON THE WORKER: repo + kubeadm# SUL WORKER: repo + kubeadmsudo sed -i 's#/v1.33/#/v1.34/#' /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.34.3-1.1
sudo apt-mark hold kubeadm
# EN EL CONTROL PLANE: drenar# ON THE CONTROL PLANE: drain# SUL CONTROL PLANE: drenarek drain w1 --ignore-daemonsets --delete-emptydir-data
k get pods -o wide -w # las réplicas renacen en otro nodo# the replicas come back on another node# le repliche rinascono su un altro nodo# EN EL WORKER: node + kubelet# ON THE WORKER: node + kubelet# SUL WORKER: node + kubeletsudo kubeadm upgrade node
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.34.3-1.1 kubectl=1.34.3-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload && sudo systemctl restart kubelet
# EN EL CONTROL PLANE: devolverlo al servicio# ON THE CONTROL PLANE: put it back in service# SUL CONTROL PLANE: rimetterlo in serviziok uncordon w1
Claves
Key points
Punti chiave
En workers es kubeadm upgrade node, no apply. Confundirlos es de los errores más repetidos.
drain y uncordon se corren desde el control plane (son operaciones del API); el resto, en el worker.
Los pods desalojados no vuelven solos tras el uncordon: el scheduler no rebalancea lo que ya corre. El nodo se repuebla con lo nuevo.
On workers it is kubeadm upgrade node, not apply. Confusing them is among the most repeated mistakes.
drain and uncordon run from the control plane (they are API operations); everything else on the worker.
Evicted pods do not come back on their own after the uncordon: the scheduler does not rebalance running workloads. The node refills with new ones.
Sui worker è kubeadm upgrade node, non apply. Confonderli è fra gli errori più ripetuti.
drain e uncordon si eseguono dal control plane (sono operazioni dell'API); il resto sul worker.
I pod espulsi non tornano da soli dopo l'uncordon: lo scheduler non ribilancia ciò che è già in esecuzione. Il nodo si ripopola con i nuovi.
E5
etcd — backup y verificación
etcd — backup and verification
etcd — backup e verifica
~5 min
Sacá un snapshot de etcd en /opt/backup.db y verificá que es válido. No busques las rutas de los certificados en internet: sacalas del cluster. Después anotá cuántas claves tiene el snapshot.
Take an etcd snapshot at /opt/backup.db and verify it is valid. Do not look up the certificate paths online: get them from the cluster. Then note how many keys the snapshot holds.
Fai uno snapshot di etcd in /opt/backup.db e verifica che sia valido. Non cercare i percorsi dei certificati online: prendili dal cluster. Poi annota quante chiavi contiene lo snapshot.
Ver soluciónShow solutionMostra soluzione
sudo grep -E 'cert-file|key-file|trusted-ca' /etc/kubernetes/manifests/etcd.yaml
sudo ETCDCTL_API=3 etcdctl snapshot save /opt/backup.db \
--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
sudo ETCDCTL_API=3 etcdctl snapshot status /opt/backup.db -w table
# HASH | REVISION | TOTAL KEYS | TOTAL SIZE# HASH | REVISION | TOTAL KEYS | TOTAL SIZE# HASH | REVISION | TOTAL KEYS | TOTAL SIZE
Claves
Key points
Punti chiave
El manifiesto de etcd tiene las rutas exactas. Es más rápido y más seguro que recordarlas.
snapshot save necesita etcd vivo (es un cliente TLS). Si el apiserver está caído pero etcd corre, el backup igual sale.
snapshot status es la verificación: si el archivo está corrupto o vacío, te enterás ahora y no durante el restore.
The etcd manifest has the exact paths. Faster and safer than recalling them.
snapshot save needs a live etcd (it is a TLS client). If the apiserver is down but etcd runs, the backup still works.
snapshot status is the verification: a corrupt or empty file shows up now rather than during the restore.
Il manifest di etcd ha i percorsi esatti. Più rapido e più sicuro che ricordarli.
snapshot save richiede un etcd vivo (è un client TLS). Se l'apiserver è giù ma etcd gira, il backup riesce lo stesso.
snapshot status è la verifica: un file corrotto o vuoto si scopre ora e non durante il restore.
E6
etcd — restore de verdad (el que más cae)
etcd — a real restore (the one that comes up most)
etcd — restore vero (quello che cade di più)
~12 min
Creá un namespace antes con un Deployment adentro.
Sacá el backup.
Borrá el namespace entero — a propósito.
Restaurá el snapshot y hacé que el cluster vuelva con el namespace vivo.
Create a namespace antes with a Deployment inside.
Take the backup.
Delete the whole namespace — on purpose.
Restore the snapshot and bring the cluster back with the namespace alive.
Crea un namespace antes con dentro un Deployment.
Fai il backup.
Cancella l'intero namespace — di proposito.
Ripristina lo snapshot e fai tornare il cluster con il namespace vivo.
Ver soluciónShow solutionMostra soluzione
k create ns antes && k create deploy web --image=nginx -n antes
# … backup como en E5 …# … backup as in E5 …# … backup come in E5 …k delete ns antes
# 1 · restaurar a un data-dir NUEVO (etcd 3.6+ → etcdutl)# 1 · restore into a NEW data-dir (etcd 3.6+ → etcdutl)# 1 · ripristinare in un data-dir NUOVO (etcd 3.6+ → etcdutl)sudo etcdutl snapshot restore /opt/backup.db --data-dir=/var/lib/etcd-restore
# 2 · editar SOLO el hostPath del volumen etcd-data# 2 · edit ONLY the hostPath of the etcd-data volume# 2 · modificare SOLO l'hostPath del volume etcd-datasudo vim /etc/kubernetes/manifests/etcd.yaml
# volumes: - hostPath: path: /var/lib/etcd → /var/lib/etcd-restore# volumes: - hostPath: path: /var/lib/etcd → /var/lib/etcd-restore# volumes: - hostPath: path: /var/lib/etcd → /var/lib/etcd-restore# 3 · el kubelet recrea etcd solo. Dale un minuto.# 3 · the kubelet recreates etcd on its own. Give it a minute.# 3 · il kubelet ricrea etcd da solo. Dagli un minuto.sudo crictl ps | grep etcd
k get ns antes
k get deploy -n antes
Claves
Key points
Punti chiave
Un solo cambio en el YAML. Si tocás --data-dir o mountPath, etcd busca los datos donde no están y el cluster se cae en CrashLoopBackOff.
Mientras etcd reinicia, kubectl no responde: es esperable, el apiserver depende de etcd. Diagnosticá con crictl ps y journalctl -u kubelet, que no necesitan el API.
El restore te devuelve el estado del momento del backup: lo creado después desaparece. Es viaje en el tiempo, no un merge.
Si el pod de etcd no vuelve, casi siempre son permisos del data-dir nuevo o los tres paths tocados.
One single change in the YAML. Touch --data-dir or mountPath and etcd looks for data where there is none — the cluster falls into CrashLoopBackOff.
While etcd restarts, kubectl stops answering: expected, the apiserver depends on etcd. Diagnose with crictl ps and journalctl -u kubelet, which need no API.
The restore gives you the state at backup time: anything created after it disappears. It is time travel, not a merge.
If the etcd pod does not come back, it is almost always permissions on the new data-dir, or all three paths edited.
Una sola modifica nello YAML. Se tocchi --data-dir o mountPath, etcd cerca i dati dove non ci sono e il cluster cade in CrashLoopBackOff.
Mentre etcd riparte, kubectl non risponde: è previsto, l'apiserver dipende da etcd. Diagnostica con crictl ps e journalctl -u kubelet, che non richiedono l'API.
Il restore ti restituisce lo stato al momento del backup: ciò che è stato creato dopo sparisce. È viaggio nel tempo, non un merge.
Se il pod di etcd non torna, quasi sempre sono i permessi del nuovo data-dir, o tutti e tre i path modificati.
T1
Troubleshooting — el static pod que no vuelve
Troubleshooting — the static pod that never returns
Troubleshooting — lo static pod che non torna
~7 min
kubectl deja de responder: The connection to the server … was refused. Alguien tocó el manifiesto del apiserver. Diagnosticá sin kubectl y devolvé el cluster a la vida.
Para plantarlo vos mismo: agregá un flag inválido al apiserver, por ejemplo - --this-flag-does-not-exist=true, en /etc/kubernetes/manifests/kube-apiserver.yaml.
kubectl stops answering: The connection to the server … was refused. Someone touched the apiserver manifest. Diagnose it without kubectl and bring the cluster back.
To plant it yourself: add an invalid flag to the apiserver, e.g. - --this-flag-does-not-exist=true, in /etc/kubernetes/manifests/kube-apiserver.yaml.
kubectl smette di rispondere: The connection to the server … was refused. Qualcuno ha toccato il manifest dell'apiserver. Diagnostica senza kubectl e riporta in vita il cluster.
Per prepararlo da solo: aggiungi un flag non valido all'apiserver, ad esempio - --this-flag-does-not-exist=true, in /etc/kubernetes/manifests/kube-apiserver.yaml.
Ver soluciónShow solutionMostra soluzione
# sin API server, kubectl no sirve: se baja al nivel del nodo# with no API server, kubectl is useless: drop to node level# senza API server, kubectl è inutile: si scende a livello nodosudo crictl ps -a | grep apiserver # Exited, reiniciando# Exited, restarting# Exited, in riavviosudo crictl logs <container-id> # unknown flag: --this-flag-does-not-exist# unknown flag: --this-flag-does-not-exist# unknown flag: --this-flag-does-not-existsudo journalctl -u kubelet -n 50 --no-pager
sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml # sacar el flag# remove the flag# togliere il flag# el kubelet lo recrea solo al guardar; esperá ~1 min# the kubelet recreates it on save; wait ~1 min# il kubelet lo ricrea al salvataggio; aspetta ~1 mink get nodes
Claves
Key points
Punti chiave
Cuando el apiserver está caído, kubectl no existe. Tus herramientas son crictl (containers) y journalctl -u kubelet (el que los levanta).
Un static pod no se arregla con kubectl: se arregla editando el archivo. Borrar el pod con kubectl no sirve — el kubelet lo recrea igual desde el manifiesto.
Truco de reinicio limpio: mover el manifiesto fuera de la carpeta, esperar, y volverlo a poner. El kubelet apaga y prende.
When the apiserver is down, kubectl does not exist. Your tools are crictl (containers) and journalctl -u kubelet (whatever starts them).
A static pod is not fixed with kubectl: you fix it by editing the file. Deleting the pod with kubectl achieves nothing — the kubelet recreates it from the manifest anyway.
Clean-restart trick: move the manifest out of the folder, wait, then put it back. The kubelet stops and starts it.
Quando l'apiserver è giù, kubectl non esiste. I tuoi strumenti sono crictl (container) e journalctl -u kubelet (chi li avvia).
Uno static pod non si aggiusta con kubectl: si aggiusta modificando il file. Cancellare il pod con kubectl non serve — il kubelet lo ricrea comunque dal manifest.
Trucco per un riavvio pulito: sposta il manifest fuori dalla cartella, aspetta, e rimettilo. Il kubelet lo spegne e lo riaccende.
T2
Troubleshooting — nodo NotReady
Troubleshooting — node NotReady
Troubleshooting — nodo NotReady
~6 min
Un worker aparece NotReady y sus pods quedan Terminating o se recrean en otro lado. Diagnosticá la causa y devolvelo a Ready.
Para plantarlo vos mismo: en el worker, sudo systemctl stop kubelet. Variante más interesante: sudo systemctl stop containerd.
A worker shows NotReady and its pods sit Terminating or get recreated elsewhere. Diagnose the cause and get it back to Ready.
To plant it yourself: on the worker, sudo systemctl stop kubelet. A more interesting variant: sudo systemctl stop containerd.
Un worker risulta NotReady e i suoi pod restano Terminating o vengono ricreati altrove. Diagnostica la causa e riportalo a Ready.
Per prepararlo da solo: sul worker, sudo systemctl stop kubelet. Variante più interessante: sudo systemctl stop containerd.
Ver soluciónShow solutionMostra soluzione
k get nodes
k describe node w1 | grep -A10 Conditions
# Ready Unknown "kubelet stopped posting node status"# Ready Unknown "kubelet stopped posting node status"# Ready Unknown "kubelet stopped posting node status"# en el worker: el kubelet es un servicio, no un pod# on the worker: the kubelet is a service, not a pod# sul worker: il kubelet è un servizio, non un podsudo systemctl status kubelet
sudo journalctl -u kubelet -n 50 --no-pager
sudo systemctl status containerd # si el kubelet corre pero se queja del CRI# if the kubelet runs but complains about the CRI# se il kubelet gira ma si lamenta del CRIsudo systemctl start kubelet # (o containerd)# (or containerd)# (o containerd)sudo systemctl enable --now kubelet
k get nodes -w
Claves
Key points
Punti chiave
NotReady es casi siempre del nodo, no del cluster: kubelet caído, containerd caído, CNI roto, disco lleno. Las Conditions del describe node te dicen cuál.
Si el kubelet corre pero el nodo sigue NotReady, mirá el runtime (containerd) y el CNI. El mensaje típico del CNI: network plugin is not ready.
Tras ~5 minutos NotReady, el taint node.kubernetes.io/unreachable:NoExecute empieza a desalojar los pods. Eso conecta directo con M5.
NotReady is nearly always the node, not the cluster: kubelet down, containerd down, broken CNI, full disk. The Conditions in describe node tell you which.
If the kubelet runs but the node stays NotReady, look at the runtime (containerd) and the CNI. The classic CNI message: network plugin is not ready.
After ~5 minutes NotReady, the node.kubernetes.io/unreachable:NoExecute taint starts evicting pods. That connects straight to M5.
NotReady è quasi sempre il nodo, non il cluster: kubelet giù, containerd giù, CNI rotto, disco pieno. Le Conditions di describe node ti dicono quale.
Se il kubelet gira ma il nodo resta NotReady, guarda il runtime (containerd) e il CNI. Il messaggio tipico del CNI: network plugin is not ready.
Dopo ~5 minuti di NotReady, il taint node.kubernetes.io/unreachable:NoExecute inizia a espellere i pod. Questo si collega direttamente a M5.
Autoevaluación — antes de marcar M1 como ★ dominado
Self-check — before marking M1 as ★ mastered
Autovalutazione — prima di segnare M1 come ★ padroneggiato
Nombrar los 5 componentes, decir cuál es static pod y cuál servicio de systemd.
Regenerar un join command y sacar un nodo del cluster en los 3 pasos.
Upgrade completo del control plane con el cambio de repo, sin mirar apuntes.
Upgrade de un worker sabiendo qué comando va en cada máquina.
Backup de etcd sacando las rutas del manifiesto.
Restore completo tocando solo el hostPath, y saber que en 1.34 es etcdutl.
Diagnosticar un control plane caído con crictl y journalctl, sin kubectl.
Diagnosticar un NotReady leyendo las Conditions del nodo.
Name the 5 components and say which is a static pod and which a systemd service.
Regenerate a join command and remove a node in the 3 steps.
Full control plane upgrade including the repo change, from memory.
Worker upgrade, knowing which command runs on which machine.
etcd backup, pulling the paths out of the manifest.
Complete restore touching only the hostPath, knowing 1.34 uses etcdutl.
Diagnose a downed control plane with crictl and journalctl, without kubectl.
Diagnose a NotReady by reading the node's Conditions.
Nominare i 5 componenti e dire quale è static pod e quale servizio systemd.
Rigenerare un join command e togliere un nodo nei 3 passi.
Upgrade completo del control plane incluso il cambio di repo, a memoria.
Upgrade di un worker sapendo quale comando va su quale macchina.
Backup di etcd ricavando i percorsi dal manifest.
Restore completo toccando solo l'hostPath, sapendo che in 1.34 si usa etcdutl.
Diagnosticare un control plane caduto con crictl e journalctl, senza kubectl.
Diagnosticare un NotReady leggendo le Conditions del nodo.
Módulo 1 completado · El núcleo administrativo del cluster · Siguiente: RBAC, ServiceAccounts y kubeconfig
Module 1 complete · The cluster's administrative core · Next: RBAC, ServiceAccounts and kubeconfig
Modulo 1 completato · Il nucleo amministrativo del cluster · Prossimo: RBAC, ServiceAccount e kubeconfig