|

Kubernetes local con Docker usando Kind: guía 2026

¿Querés correr un cluster de Kubernetes en tu propia máquina sin virtualizar medio equipo? La forma más rápida hoy es Kubernetes local con Docker usando Kind: creás el cluster en segundos, containerizás tu app Node.js, la cargás con kind load docker-image y la accedés desde el navegador con un port-forward. Todo sobre Docker, sin máquina virtual pesada.

Kind (Kubernetes IN Docker) es una herramienta oficial del proyecto Kubernetes que levanta un cluster completo corriendo cada nodo como un contenedor de Docker. Se usa para desarrollo local y para testear en CI. A diferencia de Minikube, que suele arrancar una VM, Kind reutiliza el motor de Docker que ya tenés, así que consume menos y arranca más rápido.

En resumen

  • Kind vs Minikube: Kind corre los nodos como contenedores Docker; Minikube arranca por defecto una VM. Para local liviano, Kind gana.
  • Necesitás tres cosas: Docker corriendo, el binario kubectl y el binario kind.
  • Un comando y listo: kind create cluster te deja un cluster funcionando en menos de un minuto.
  • El paso que todos olvidan: la imagen que buildeaste en local no está dentro de Kind hasta que corrés kind load docker-image.
  • Para verla en el navegador: kubectl port-forward si usás ClusterIP, o un Service tipo NodePort.

¿Qué herramientas necesito para correr Kubernetes en local?

Ponele que querés probar un Deployment antes de mandarlo a producción y no querés romper nada compartido. Para eso hay varias opciones, y no todas hacen lo mismo.

Las cuatro que vas a cruzar todo el tiempo son estas:

  • Kind: levanta el cluster como contenedores Docker. Liviano, ideal para CI y para simular varios nodos.
  • Minikube: el clásico. Por defecto usa una VM, aunque también tiene driver de Docker. Más pesado, pero muy completo (dashboard, addons).
  • Docker Desktop: trae un Kubernetes de un solo nodo que activás con un checkbox. Cómodo si ya lo tenés instalado.
  • Podman: alternativa a Docker sin daemon. Kind también corre sobre Podman, con algún ajuste extra.
HerramientaCómo correPesoMulti-nodo
KindContenedores DockerBajo
MinikubeVM (o driver Docker)Medio/Alto
Docker DesktopNodo embebidoMedioNo
PodmanContenedores sin daemonBajoSí (con ajustes)
kubernetes local con docker diagrama explicativo

Mi recomendación para arrancar: Kind. Es el que usa el tutorial de dev.to que originó esta nota y el que menos fricción te va a dar si ya tenés Docker andando.

Instalación paso a paso: Docker, kubectl y Kind según tu sistema operativo

Primero, Docker tiene que estar corriendo. Sin eso, Kind no arranca. En Windows, andá con Docker Desktop sobre WSL2. En macOS, Docker Desktop u OrbStack. En Linux, el paquete de Docker Engine directo. Sobre eso profundizamos en cómo integrar CI/CD en tu cluster Kubernetes.

Después instalás los dos binarios. En macOS con Homebrew es directo:

brew install kind kubectl

En Linux, según la guía oficial de Kind, bajás el binario, lo hacés ejecutable y lo movés al PATH:

curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

Verificá que todo quedó bien antes de seguir. Este paso parece trivial, pero es donde principiante tras principiante se frena (versiones que no matchean, PATH mal configurado, Docker que no levantó).

docker version
kubectl version --client
kind version

¿Cómo creo mi primer cluster local con Kind?

Un comando:

kind create cluster --name mi-cluster

¿Qué hace por debajo? Kind arranca uno o más contenedores Docker que hacen de nodos del cluster y configura tu kubeconfig para que kubectl apunte ahí. En segundos tenés un control plane funcionando. Comprobalo:

kubectl get nodes

Si te devuelve el nodo en estado Ready, ya estás. Ahora falta la parte que le da sentido a todo esto: meter tu propia app adentro.

¿Cómo containerizo una app Node.js con Docker?

Vamos con una Todo API mínima en Node.js 20 con Express, igual que en el tutorial base. La estructura no tiene misterio: tu server.js, el package.json y el Dockerfile. El Dockerfile conviene armarlo sobre node:20-alpine, que es una imagen chica. Esto se conecta con lo que analizamos en alternativas a Docker Desktop en Mac.

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Agregá un .dockerignore con node_modules adentro (si no, copiás basura pesada a la imagen). Después buildeás y, ojo con esto, probá el contenedor en local antes de tocar Kubernetes:

docker build -t todo-api:1.0 .
docker run -p 3000:3000 todo-api:1.0

Si en localhost:3000 responde, la imagen está sana. Si no responde acá, no va a responder mágicamente dentro del cluster.

¿Cómo escribo los manifests YAML para mi app?

Un manifest es un archivo YAML donde declarás el estado que querés, y Kubernetes se encarga de llegar a ese estado. En lugar de un docker run imperativo, describís qué querés que exista. Para una app web necesitás dos objetos: un Deployment (que maneja los Pods y las réplicas) y un Service (que expone esos Pods bajo una IP estable).

apiVersion: apps/v1
kind: Deployment
metadata:
 name: todo-api
spec:
 replicas: 3
 selector:
 matchLabels:
 app: todo-api
 template:
 metadata:
 labels:
 app: todo-api
 spec:
 containers:
 - name: todo-api
 image: todo-api:1.0
 ports:
 - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
 name: todo-api
spec:
 selector:
 app: todo-api
 ports:
 - port: 80
 targetPort: 3000

Fijate en los labels y el selector: es el pegamento entre el Service y los Pods del Deployment. Si esas etiquetas no coinciden, el Service no encuentra nada y te vas a comer un rato de debug preguntándote por qué no responde. Para más detalles técnicos, mirá elige la herramienta de automatización ideal.

¿Cómo cargo mi imagen Docker en el cluster de Kind?

Acá está el paso que hace tropezar a casi todos. Tu imagen todo-api:1.0 vive en el Docker de tu máquina, pero el cluster de Kind corre en contenedores aislados y no la ve. Si aplicás el manifest tal cual, los Pods quedan en ErrImagePull buscando una imagen que “no existe”.

La solución es una línea:

kind load docker-image todo-api:1.0 --name mi-cluster

Eso copia la imagen local adentro de los nodos de Kind. Recién ahí Kubernetes la va a encontrar sin salir a internet.

Deploy y acceso a la app desde tu máquina

Aplicás el manifest y mirás cómo arrancan los Pods:

kubectl apply -f k8s/
kubectl get pods
kubectl get svc

Esperá a que los tres Pods estén en Running. Como el Service es ClusterIP (interno al cluster), para llegar desde tu navegador armás un túnel con port-forward:

kubectl port-forward svc/todo-api 3000:80

Ahora sí: abrís localhost:3000 y tu Todo API responde desde adentro de Kubernetes. Cuando este flujo ya lo tenés aceitado en local y querés llevarlo a un servidor real, en donweb.com tenés VPS y cloud para hostear tus clusters sin depender de tu máquina.

Errores comunes al correr Kubernetes local (y cómo evitarlos)

La lista de tropiezos reales, ordenada por cuánto tiempo te hace perder:

  • No cargar la imagen en Kind: el error #1. Pods en ErrImagePull. Corré kind load docker-image después de cada build nuevo.
  • Confundir puertos: el containerPort es el que expone tu app (3000), el port del Service es otra cosa. Mezclarlos rompe el ruteo.
  • Indentación YAML rota: un espacio de más y el manifest no parsea. Los YAML no perdonan tabs.
  • No esperar a que el Pod esté listo: pegás port-forward con el Pod en ContainerCreating y falla. Mirá kubectl get pods primero.
  • No mirar los logs: ante cualquier duda, kubectl logs nombre-del-pod te dice qué pasó adentro.

¿Y si nada de esto arregla el problema? Borrá y volvé a empezar limpio con kind delete cluster --name mi-cluster. A veces reconstruir es más rápido que perseguir un estado sucio. Ya lo cubrimos antes en ejecuta agentes en tu ambiente local.

Preguntas Frecuentes

¿Qué diferencia hay entre Kind y Minikube?

Kind corre los nodos del cluster como contenedores de Docker, mientras que Minikube por defecto arranca una máquina virtual. Kind es más liviano y rápido de levantar, y es la opción típica en pipelines de CI. Minikube trae más extras integrados, como dashboard y addons.

¿Necesito una máquina virtual para correr Kubernetes local con Docker?

No con Kind. Reutiliza el motor de Docker que ya tenés instalado y levanta los nodos como contenedores, sin virtualizar un sistema operativo completo. En Windows sí conviene tener Docker Desktop sobre WSL2 por debajo.

¿Por qué mis Pods quedan en ErrImagePull?

Porque la imagen que buildeaste está en tu Docker local, no dentro del cluster de Kind. Corré kind load docker-image tu-imagen:tag --name tu-cluster y volvé a aplicar el manifest. Es el error más frecuente de quien arranca.

¿Cómo accedo a mi app desde el navegador?

Si el Service es ClusterIP, usá kubectl port-forward svc/tu-servicio 3000:80 y abrí localhost:3000. Otra opción es definir el Service como NodePort para exponer un puerto directo del nodo.

¿Kind sirve para producción?

No. Kind está pensado para desarrollo local y testing en CI, no para cargas productivas. Para producción usás un Kubernetes gestionado o uno instalado sobre servidores reales, con alta disponibilidad y almacenamiento persistente.

Conclusión

Levantar Kubernetes local con Docker dejó de ser un dolor de cabeza. Con Kind, el ciclo completo (crear cluster, buildear la imagen, cargarla con kind load, aplicar el YAML y acceder con port-forward) te lleva minutos y no ensucia nada compartido. El truco es no saltearse el paso de cargar la imagen, que es donde se traba casi todo el mundo.

Si estás arrancando con Kubernetes, esta es la forma más barata de aprender: rompés, borrás el cluster, volvés a empezar, sin costo. Cuando el flujo ya te salga de memoria, el próximo paso lógico es sumar base de datos, ConfigMaps e Ingress, y de ahí llevarlo a un servidor de verdad.

Fuentes

Te puede interesar...