Construir un cluster de Kubernetes en Google Cloud Platform con kubeadm

¿Alguna vez te preguntaste cómo funcionan realmente los clusters de Kubernetes por debajo? En esta guía te voy a acompañar paso a paso para que construyas tu propio cluster de Kubernetes en Google Cloud Platform desde cero usando kubeadm. Esta experiencia práctica te va a dar una comprensión más profunda de la arquitectura de Kubernetes y te va a ayudar a apreciar lo que servicios administrados como GKE hacen detrás de escena.
Ya sea que estés preparando una certificación, armando tu homelab, o simplemente tengas curiosidad sobre la orquestación de contenedores, este tutorial paso a paso te tiene cubierto.
Lo que vas a necesitar
Tranquilo—la configuración es simple. Esto es lo que necesitás antes de arrancar:
- Cuenta de Google Cloud: necesitás una cuenta de GCP activa con facturación habilitada. Si sos nuevo en GCP, ofrecen créditos gratuitos para arrancar.
- gcloud CLI: el Google Cloud SDK en tu máquina local (conseguilo acá)
- Configuración rápida:
gcloud auth loginpara autenticarte
- Configuración rápida:
- Permisos apropiados: tu cuenta de GCP debe poder:
- Crear y administrar proyectos
- Levantar instancias de Compute Engine
- Configurar redes VPC y reglas de firewall
- Cierta familiaridad con:
- Comandos básicos de Linux
- Conexiones SSH
- Fundamentos de Kubernetes (aunque vamos a ir explicando sobre la marcha)
Manos a la obra
¿Listo para ensuciarte las manos? Vamos a construir este cluster paso a paso, empezando por la infraestructura y subiendo hasta tener un cluster completamente funcional. Te voy a explicar qué hace cada comando y por qué importa.
Paso 1: Configurar tu proyecto de GCP
Lo primero es lo primero—creemos un proyecto de GCP dedicado para nuestro cluster y hagámoslo el proyecto activo. Ejecutá estos comandos en tu máquina local:
gcloud projects create my-k8s-cluster
gcloud config set project my-k8s-clusterPaso 2: Armar tu infraestructura de red
Configurá una red VPC personalizada con ruteo BGP regional y creá una subred en la región us-central1. Ejecutá estos comandos en tu máquina local:
gcloud compute networks create k8s-vpc \
--subnet-mode=custom \
--bgp-routing-mode=regional
gcloud compute networks subnets create k8s-subnet \
--network=k8s-vpc \
--range=10.0.0.0/24 \
--region=us-central1Paso 3: Blindar la seguridad con reglas de firewall
Configurá reglas de firewall para habilitar acceso SSH desde cualquier lado y permitir toda la comunicación interna entre los nodos del cluster. Ejecutá estos comandos en tu máquina local:
gcloud compute firewall-rules create k8s-allow-ssh \
--network=k8s-vpc \
--allow=tcp:22 \
--source-ranges=0.0.0.0/0
gcloud compute firewall-rules create k8s-allow-internal \
--network=k8s-vpc \
--allow=tcp,udp,icmpPaso 4: Levantar tu nodo de control plane
Aprovisioná una instancia e2-medium con Ubuntu 22.04 LTS para que funcione como el control plane del cluster. Ejecutá este comando en tu máquina local:
gcloud compute instances create k8s-control-plane \
--machine-type=e2-medium \
--subnet=k8s-subnet \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--zone=us-central1-aPaso 5: Entrar a tu control plane
Conectate a la VM del control plane usando el CLI de gcloud. Ejecutá este comando en tu máquina local:
gcloud compute ssh k8s-control-plane --zone=us-central1-aPaso 6: Preparar el entorno del control plane
Instalar containerd en Ubuntu para un cluster de Kubernetes requiere algunos ajustes específicos a nivel de sistema operativo antes de la instalación en sí, para asegurar que el networking y la administración de recursos (cgroups) funcionen correctamente.
Acá va la guía paso a paso para dejarlo funcionando. Todos los comandos de esta sección se ejecutan en el nodo del control plane.
Prerrequisitos de configuración del sistema
Kubernetes necesita módulos de kernel y configuraciones de red específicas para que el runtime de contenedores pueda manejar tráfico con bridging.
Cargar módulos de kernel
Creá un archivo de configuración para cargar los módulos necesarios al arrancar (en el control plane):
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilterConfigurar Sysctl
Habilitá el reenvío de IP y el networking con bridge. El comando sysctl aplica estos cambios de inmediato, sin necesidad de reiniciar (en el control plane):
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 --systemInstalar containerd
Podés instalar containerd directamente desde los repositorios oficiales de Ubuntu (en el control plane):
sudo apt update
sudo apt install -y containerdConfigurar containerd para Kubernetes
Este es el paso más crítico. Por defecto, containerd no usa el driver de cgroup de systemd, que Kubernetes recomienda fuertemente para mayor estabilidad.
Generar la configuración por defecto
Creá el directorio y generá un archivo de configuración limpio (en el control plane):
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/nullHabilitar el driver de cgroup de systemd
Necesitás cambiar SystemdCgroup = false por true. Podés hacerlo manualmente con un editor o usar este comando sed (en el control plane):
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.tomlReiniciar containerd
Aplicá la nueva configuración (en el control plane):
sudo systemctl restart containerd
sudo systemctl enable containerdInstalar kubeadm, kubelet y kubectl
Agregá el repositorio de paquetes de Kubernetes e instalá los componentes necesarios. Tené en cuenta que el directorio /etc/apt/keyrings normalmente ya está presente en los sistemas Ubuntu 22.04. Los paquetes quedan marcados como retenidos para evitar actualizaciones automáticas (en el control plane):
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/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.35/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
sudo systemctl enable --now kubeletPaso 7: Iniciar el control plane de Kubernetes
Inicializá el control plane de Kubernetes con el rango de CIDR de red de pods especificado (en el control plane):
sudo kubeadm init --pod-network-cidr=10.244.0.0/16Una vez que la inicialización termine con éxito, configurá el acceso de kubectl para tu usuario (en el control plane):
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configLa inicialización va a mostrar un token de join para agregar nodos worker. Podés guardarlo, aunque generar uno nuevo más adelante es igual de simple.
Desplegar tu plugin de red de pods
Desplegá Flannel como plugin CNI (Container Network Interface) para habilitar la comunicación pod-a-pod en todo el cluster (en el control plane):
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.ymlPotenciar tu experiencia con kubectl
Habilitá el autocompletado de comandos de kubectl para la sesión actual y persistilo para sesiones futuras. El primer comando lo activa de inmediato, y el segundo lo agrega a tu perfil de bash (en el control plane):
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrcDe forma opcional, creá un alias k para kubectl con el mismo comportamiento de autocompletado (en el control plane):
alias k=kubectl
complete -o default -F __start_kubectl kPaso 8: Sumar nodos worker a la mezcla
Con el control plane listo, aprovisioná una instancia de VM adicional que va a funcionar como nodo worker para correr las cargas de trabajo. Ejecutá este comando en tu máquina local:
gcloud compute instances create k8s-worker-1 \
--machine-type=e2-medium \
--subnet=k8s-subnet \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--zone=us-central1-aPaso 9: Entrar a tu nodo worker
Conectate a la VM del nodo worker usando el CLI de gcloud. Ejecutá este comando en tu máquina local:
gcloud compute ssh k8s-worker-1 --zone=us-central1-aPaso 10: Preparar el entorno del nodo worker
Todos los comandos de esta sección se ejecutan en el nodo worker. Repetí todos los pasos de instalación del Paso 6 en el nodo worker: prerrequisitos de configuración del sistema, instalar containerd, configurar containerd para Kubernetes, e instalar kubeadm, kubelet y kubectl.
Paso 11: Sumar el worker al control plane
Generá un comando de join nuevo desde el control plane (en el control plane):
kubeadm token create --print-join-commandEjecutá el comando de la salida en el nodo worker para registrarlo en el cluster (en el nodo worker).
Paso 12: Ponele a prueba tu cluster
Ahora que tu cluster está completamente operativo, verificá que todo funcione desplegando un servidor web nginx simple. Todos los comandos kubectl se ejecutan en el control plane.
Crear y correr un pod de nginx
Desplegá un pod de nginx en tu cluster (en el control plane):
kubectl run nginx-test --image=nginx:latest --port=80Verificar que el pod esté corriendo
Revisá el estado de tu pod (en el control plane):
kubectl get podsDeberías ver una salida similar a esta:
NAME READY STATUS RESTARTS AGE
nginx-test 1/1 Running 0 30sObtener información detallada del pod
Mirá más detalles sobre el pod en ejecución (en el control plane):
kubectl describe pod nginx-testExponer el pod al mundo
Si querés acceder a nginx desde adentro del cluster, creá un service (en el control plane):
kubectl expose pod nginx-test --type=NodePort --port=80Revisá el service y el puerto asignado (en el control plane):
kubectl get services nginx-testAcceder a nginx desde tu computadora
Para acceder al servidor nginx desde tu máquina local, vas a necesitar abrir el NodePort en el firewall de GCP y conseguir la IP externa de uno de tus nodos.
Primero, creá una regla de firewall para permitir tráfico en el rango de NodePort (30000-32767), ejecutá esto en tu máquina local:
gcloud compute firewall-rules create k8s-allow-nodeport \
--network=k8s-vpc \
--allow=tcp:30000-32767 \
--source-ranges=0.0.0.0/0Conseguí la dirección IP externa de tu nodo worker o del control plane (en tu máquina local):
gcloud compute instances list --filter="name~'k8s-'"Anotá el EXTERNAL_IP de la salida. Ahora conseguí el NodePort asignado a tu service (en el control plane):
kubectl get service nginx-test -o jsonpath='{.spec.ports[0].nodePort}'Esto va a mostrar un número de puerto entre 30000 y 32767. Accedé a nginx abriendo en tu navegador:
http://EXTERNAL_IP:NODEPORTPor ejemplo, si tu IP externa es 34.123.45.67 y el NodePort es 31234, visitá:
http://34.123.45.67:31234Deberías ver la página "Welcome to nginx!".
Limpiar los recursos de prueba
Eliminá el pod y el service de nginx cuando termines de probar (en el control plane):
kubectl delete service nginx-test
kubectl delete pod nginx-testSi creaste la regla de firewall de NodePort, eliminala también (en tu máquina local):
gcloud compute firewall-rules delete k8s-allow-nodeportPaso 13: Desarmar tu cluster
Desarmá todos los recursos creados en orden inverso. Empezá por las VMs, y después eliminá las reglas de firewall, la subred y la VPC. Ejecutá estos comandos en tu máquina local:
gcloud compute instances delete k8s-control-plane k8s-worker-1 \
--zone=us-central1-a
gcloud compute firewall-rules delete k8s-allow-ssh k8s-allow-internal
gcloud compute networks subnets delete k8s-subnet \
--region=us-central1
gcloud compute networks delete k8s-vpcSi querés eliminar el proyecto entero y todo su contenido, ejecutá:
gcloud projects delete my-k8s-clusterUna palabra sobre estar listo para producción
Antes de cerrar, tengamos una conversación honesta: este cluster es perfecto para aprender y hacer pruebas, pero no está listo para producción. Pensalo como tu terreno de entrenamiento—un espacio seguro para experimentar, romper cosas y aprender.
Reflexión final
¡Felicitaciones por construir tu propio cluster de Kubernetes! Ganaste experiencia práctica en orquestación de contenedores que muchos desarrolladores nunca llegan a tener. Usá esta configuración para experimentar, probar tus aplicaciones, y profundizar tu comprensión de cómo funciona Kubernetes en la realidad.
Cuando estés listo para producción, vas a apreciar todavía más los servicios administrados—pero también vas a entender qué está pasando detrás de escena. Y ese conocimiento no tiene precio.
¡Feliz clustering! Si tenés preguntas o querés compartir tu experiencia, escribime. Sigamos aprendiendo juntos.