CKA · Setup de entorno K8s v1.34

VMs con kubeadm + snapshots

El entorno de máxima fidelidad: el mismo que vas a ver en el examen. Armado una vez, con estrategia de snapshots para repetir escenarios destructivos infinitas veces.

Esta es la corrección al Módulo 0: kind no sirve para CKA porque corre los nodos como contenedores Docker, sin systemd real — no podés practicar kubeadm, etcd backup, ni node troubleshooting, que juntos son más del 40% del examen. El entorno correcto son VMs Linux con kubeadm, exactamente como el examen. Tu idea de snapshots es la pieza que lo hace imbatible: practicás escenarios destructivos y volvés atrás en segundos.

Topología del cluster de práctica

cp1
Control Plane
2 vCPU · 2-4 GB RAM
20 GB disco
Ubuntu 24.04 LTS
w1
Worker
2 vCPU · 2 GB RAM
20 GB disco
Ubuntu 24.04 LTS
w2
Worker
2 vCPU · 2 GB RAM
20 GB disco
Ubuntu 24.04 LTS

Total: ~6 vCPU · ~8 GB RAM · Red interna entre las 3 VMs

01
Provisioning · 15 min

Crear las 3 VMs

Elegí UN método según tu hipervisor

Opción A — multipass (la más simple, Ubuntu nativo)

Si estás en Linux/Mac/Windows, multipass levanta VMs Ubuntu en segundos. Es lo más rápido para arrancar.

# Instalar multipass: https://multipass.run
# Crear las 3 VMs (2 CPU, 2GB RAM, 20GB disco)
multipass launch 24.04 --name cp1 --cpus 2 --memory 2G --disk 20G
multipass launch 24.04 --name w1 --cpus 2 --memory 2G --disk 20G
multipass launch 24.04 --name w2 --cpus 2 --memory 2G --disk 20G

# Verificar IPs (las vas a necesitar)
multipass list

# Entrar a una VM
multipass shell cp1

Opción B — VirtualBox + Vagrant (mejor para snapshots)

VirtualBox tiene mejor manejo de snapshots desde la GUI. Vagrant automatiza el provisioning.

# Vagrantfile para las 3 VMs
cat > Vagrantfile <<'EOF'
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"
  nodes = { "cp1" => "192.168.56.10",
            "w1"  => "192.168.56.11",
            "w2"  => "192.168.56.12" }
  nodes.each do |name, ip|
    config.vm.define name do |node|
      node.vm.hostname = name
      node.vm.network "private_network", ip: ip
      node.vm.provider "virtualbox" do |vb|
        vb.memory = 2048
        vb.cpus = 2
      end
    end
  end
end
EOF

vagrant up
Decisión de snapshots: si tu prioridad es el roll back fácil, VirtualBox gana — su árbol de snapshots con GUI es superior. multipass no tiene snapshots nativos tan cómodos. Para CKA donde vas a romper y restaurar mucho, vale la pena VirtualBox.
02
Preparación · 20 min

Prep del sistema (las 3 VMs)

Idéntico en cp1, w1 y w2
▶ Correr en: TODAS las VMs

2.1 — Swap off + kernel modules + sysctl

# Kubelet no arranca con swap activo
sudo swapoff -a
sudo sed -i '/\sswap\s/d' /etc/fstab

# Módulos de kernel para networking de K8s
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl: que el tráfico bridged sea visible a iptables
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system
Si br_netfilter no está cargado, el CNI parece instalarse bien pero el tráfico pod-a-pod y los Services se comportan de forma fantasmal: el cluster "está arriba" pero la red nunca funciona del todo. No te saltees este paso.

2.2 — Instalar containerd

# Repo de Docker (trae containerd estable)
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list

sudo apt-get update
sudo apt-get install -y containerd.io

2.3 — El gotcha crítico: SystemdCgroup = true

Este es el paso que tumba el 80% de las instalaciones. Sin esto, kubelet y containerd usan cgroup drivers distintos y el kubeadm init falla.

# Generar config default de containerd
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml

# EL PASO CLAVE: activar SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# Reiniciar containerd
sudo systemctl restart containerd
sudo systemctl enable containerd

2.4 — Instalar kubeadm, kubelet, kubectl (v1.34)

# Repo oficial pkgs.k8s.io (el viejo apt.kubernetes.io está muerto)
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
  https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /" | \
  sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

# Pin de versión: que no se actualicen solos
sudo apt-mark hold kubelet kubeadm kubectl
★ SNAPSHOT #1 — "base-prep"
Apagá las 3 VMs y sacá un snapshot acá. Este es tu punto de partida limpio: sistema preparado pero cluster sin inicializar. Si algo sale mal en el init, volvés acá sin reinstalar todo.
03
Bootstrap · 15 min

Inicializar el cluster

Pasos diferentes para control plane vs workers
▶ Correr en: SOLO cp1 (control plane)

3.1 — kubeadm init

# Inicializar el control plane
# --pod-network-cidr debe matchear el CNI (Calico usa esta por convención)
sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --apiserver-advertise-address=192.168.56.10

# Guardá el comando 'kubeadm join ...' que imprime al final.
# Lo vas a necesitar para los workers.

# Configurar kubectl para tu usuario
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

3.2 — Instalar CNI (Calico)

Sin CNI, los nodos quedan en NotReady y CoreDNS no arranca. Calico es el más usado en CKA.

kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/calico.yaml

# Esperar a que los nodos pasen a Ready (1-2 min)
kubectl get nodes -w
▶ Correr en: w1 y w2 (workers)

3.3 — Join de los workers

# Pegá el comando que imprimió kubeadm init. Se ve así:
sudo kubeadm join 192.168.56.10:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

# Si perdiste el token, regeneralo desde cp1:
#   kubeadm token create --print-join-command
▶ Verificar en: cp1
kubectl get nodes
# Deberías ver cp1, w1, w2 todos en Ready
★ SNAPSHOT #2 — "cluster-ready"
Apagá las 3 VMs y sacá snapshot. Este es tu estado "cluster funcional 3 nodos". Es el que más vas a restaurar: cada vez que termines un ejercicio destructivo, volvés acá y tenés un cluster limpio listo para el próximo.
04
Tu ventaja · estrategia

Snapshots como superpoder

El uso correcto del roll back para practicar CKA

Los 3 snapshots base que mantenés siempre

SnapshotEstadoCuándo restaurás a él
base-prepSistema listo, sin clusterPara practicar kubeadm init from scratch
cluster-readyCluster 3 nodos funcionalEl default — después de cada ejercicio destructivo
pre-upgradeCluster en v1.33 (1 versión atrás)Para practicar upgrades repetidamente

Cómo aprovecharlos por tipo de ejercicio

Troubleshooting destructivo: restaurás a cluster-ready, rompés algo a propósito (parás kubelet, borrás un static pod, corrompés un manifiesto), lo arreglás, y restaurás de nuevo para el próximo escenario. Repetición infinita.

Upgrades (Módulo 1): creás pre-upgrade con el cluster una versión atrás. Practicás el upgrade completo. Sale bien o mal, restaurás y lo repetís hasta que sea automático. El upgrade es de los temas que más se gana con repetición pura.

etcd backup/restore: hacés un backup, borrás recursos a propósito, restaurás el backup, verificás que volvieron. Si rompés etcd mal, restaurás el snapshot y reintentás.

kubeadm from scratch: restaurás a base-prep y practicás el kubeadm init + join entero. Es el ejercicio que más fideliza con el examen.

Crear un 4º nodo desde imagen: como mencionaste, podés clonar w2 desde su snapshot para tener un w3. Solo cuidá de cambiar hostname, MAC y product_uuid (K8s exige que sean únicos) antes de hacer el join. En VirtualBox: clonar con "Generate new MAC addresses" activado, después sudo hostnamectl set-hostname w3.
Cuidado con snapshots y tiempo: si restaurás un snapshot viejo de un cluster que estuvo apagado mucho, los certificados de kubeadm o los tokens pueden haber expirado. Para práctica normal no es problema (restaurás y usás al toque), pero si un cluster restaurado da errores raros de auth, regenerá el token con kubeadm token create.
05
Mapa de uso

Qué módulo practicás en estas VMs

Estas VMs te sirven para el 100% del temario, a diferencia de kind. Pero algunos módulos las aprovechan especialmente:

Módulo¿VMs imprescindibles?Por qué
1 · kubeadm + etcdSÍ — solo acáinit, join, upgrade, etcd backup necesitan nodos reales
2 · RBACFunciona en cualquier clusterObjetos K8s estándar
3 · Helm/Kustomize/CRDsFunciona en cualquieraObjetos K8s estándar
4-5 · Workloads/SchedulingVMs mejor (multi-node real)Taints, affinity necesitan varios nodos
6-7 · Services/NetworkingVMs mejorCNI, NetworkPolicy, kube-proxy reales
8 · StorageFunciona en cualquieraPV/PVC estándar
9 · Troubleshooting appsFunciona en cualquieraPods rotos
10 · Troubleshooting clusterSÍ — solo acákubelet, static pods, systemctl necesitan systemd real
11 · Troubleshooting redVMs mejorCoreDNS, CNI reales
Conclusión: armás esto UNA vez y te sirve de principio a fin. No necesitás kind ni minikube en paralelo. Las VMs cubren todo, y los snapshots te dan la repetibilidad que kind te daba con su "descartabilidad" — pero sin perder fidelidad con el examen.
Entorno listo de inicio a fin · Snapshots configurados · Ahora sí, al Módulo 1: kubeadm en profundidad