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.
Total: ~6 vCPU · ~8 GB RAM · Red interna entre las 3 VMs
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
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
# 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
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.# 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
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
# 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
# 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
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
# 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
kubectl get nodes
# Deberías ver cp1, w1, w2 todos en Ready
| Snapshot | Estado | Cuándo restaurás a él |
|---|---|---|
| base-prep | Sistema listo, sin cluster | Para practicar kubeadm init from scratch |
| cluster-ready | Cluster 3 nodos funcional | El default — después de cada ejercicio destructivo |
| pre-upgrade | Cluster en v1.33 (1 versión atrás) | Para practicar upgrades repetidamente |
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.
sudo hostnamectl set-hostname w3.kubeadm token create.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 + etcd | SÍ — solo acá | init, join, upgrade, etcd backup necesitan nodos reales |
| 2 · RBAC | Funciona en cualquier cluster | Objetos K8s estándar |
| 3 · Helm/Kustomize/CRDs | Funciona en cualquiera | Objetos K8s estándar |
| 4-5 · Workloads/Scheduling | VMs mejor (multi-node real) | Taints, affinity necesitan varios nodos |
| 6-7 · Services/Networking | VMs mejor | CNI, NetworkPolicy, kube-proxy reales |
| 8 · Storage | Funciona en cualquiera | PV/PVC estándar |
| 9 · Troubleshooting apps | Funciona en cualquiera | Pods rotos |
| 10 · Troubleshooting cluster | SÍ — solo acá | kubelet, static pods, systemctl necesitan systemd real |
| 11 · Troubleshooting red | VMs mejor | CoreDNS, CNI reales |