kind, minikube y k3d te dan una API Kubernetes en una laptop. Difieren en cuánto tarda el primer arranque, cuánta RAM gastan y cómo un LoadBalancer o Ingress se convierte en un puerto que puedes abrir. Crea un clúster con los comandos de abajo y carga una imagen local sin enviarla a un registro.
Respuesta corta
Usa kind cuando el clúster debe comportarse como Kubernetes ascendente y cuando los mismos comandos deben ejecutarse en CI. Usa minikube cuando quieres minikube addons enable ingress, un controlador que no sea Docker, o un túnel que dé a los Servicios LoadBalancer una dirección. Usa k3d cuando quieres k3s, una huella pequeña y un puerto del host en el balanceador incorporado sin instalar controladores extra.
Los tres contactan al motor Docker por defecto. docker info tiene que funcionar. Si falla con un error de socket, arregla Permiso denegado para el socket Docker antes de depurar la herramienta de clúster. Los nombres de contexto kubectl y los comandos diarios están en la hoja de trucos kubectl.
Lado a lado
| kind | minikube | k3d | |
|---|---|---|---|
| Lo que ejecuta | Kubernetes ascendente vía kubeadm, un contenedor por nodo | Kubernetes ascendente en un contenedor o una VM | k3s en Docker |
| Runtime por defecto | Docker | Docker, o un controlador de VM | Docker |
| Multi-nodo | Archivo de configuración, role: worker |
--nodes |
--servers y --agents |
| Ingress | Instalas el controlador | minikube addons enable ingress |
Traefik, a menos que lo desactives |
| LoadBalancer | Pendiente hasta cloud-provider-kind o MetalLB | minikube tunnel (mantén el proceso corriendo) |
k3s ServiceLB más el proxy de k3d |
| Pon una imagen local en los nodos | kind load docker-image |
minikube image load |
k3d image import |
| Contexto kubeconfig | kind-<nombre> |
Nombre del perfil (minikube por defecto) |
k3d-<nombre> |
| CI | Opción usual; sin paso de complemento | Funciona con --driver=docker; más pesado |
Funciona; el balanceador incorporado ahorra pasos |
El primer arranque espera la descarga de la imagen del nodo en los tres. Después de que esa imagen se cachea, kind y k3d generalmente alcanzan Ready más rápido que minikube, y un controlador de VM de minikube también arranca un SO invitado. Trata eso como un orden, no como una comparativa.
k3s ejecuta el plano de control como un proceso, así que k3d suele ser el más ligero en RAM. kind ejecuta los procesos normales del plano de control en el contenedor del nodo. Un controlador de VM de minikube reserva la --memory que estableces. El controlador de Docker queda más cerca de kind, más cualquier complemento que habilites.
Crea un clúster
kind
brew install kind
winget install Kubernetes.kind
brew es macOS o Linux. winget es Windows. Chocolatey envía choco install kind.
Un nodo:
kind create cluster --name dev
kubectl cluster-info --context kind-dev
kind delete cluster --name dev
Más de un nodo, y puertos del host 80 y 443 apuntados al contenedor del plano de control, necesitan un archivo de configuración. kind no tiene una bandera --nodes.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
- role: worker
- role: worker
kind create cluster --name dev --config kind-config.yaml
Fija la imagen del nodo cuando necesitas una versión menor específica de Kubernetes, por ejemplo --image kindest/node:v1.31.0. La etiqueta tiene que existir para esa versión de kind.
minikube
brew install minikube
winget install Kubernetes.minikube
minikube start -p dev --driver=docker --nodes=3 --cpus=2 --memory=4g
minikube status -p dev
minikube delete -p dev
--nodes=3 es un plano de control más dos workers. --driver es docker o podman cuando ya tienes un motor de contenedor, o kvm2, qemu2, hyperv, virtualbox, o vfkit para una VM. --ha significa varios nodos del plano de control, no «más workers».
El nombre del perfil es el contexto kubectl: -p dev es kubectl config use-context dev. El perfil por defecto es minikube. Fija una versión con --kubernetes-version=v1.31.0 o stable.
k3d
k3d necesita Docker. macOS y Linux:
brew install k3d
Windows: choco install k3d o scoop install k3d. El proyecto también publica un instalador:
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create dev --agents 2 --port "8080:80@loadbalancer"
kubectl cluster-info --context k3d-dev
k3d cluster delete dev
--agents 2 añade dos workers al lado de un servidor. El contexto es k3d-dev. Sin nombre, el clúster es k3s-default y el contexto es k3d-k3s-default.
--port publica un puerto del host a través del proxy de k3d. Sin él, k3d imprime los puertos altos que eligió. @server:0 es suficiente para desactivar Traefik en el primer servidor:
k3d cluster create dev --agents 2 --k3s-arg "--disable=traefik@server:0" --port "8080:80@loadbalancer"
Instala tu propio controlador de ingress después de eso, y apúntalo al puerto publicado.
Imágenes, ingress y LoadBalancer
Construye con la CLI de Docker, luego copia la imagen en los nodos. Un registro no es requerido para una máquina única.
docker build -t example/web:1.4.0 ./web
kind load docker-image example/web:1.4.0 --name dev
minikube image load example/web:1.4.0 -p dev
k3d image import example/web:1.4.0 -c dev
kind acepta varias etiquetas en una llamada. minikube también acepta un archivo tar (minikube image load web.tar).
Evita la etiqueta latest. Kubernetes trata latest y una etiqueta ausente como imagePullPolicy: Always, así que kubelet sigue contactando un registro. Cualquier otra etiqueta por defecto es IfNotPresent. Si el pull se ejecuta y la etiqueta no se publica, el Pod es ImagePullBackOff.
En Docker actual, kind load docker-image puede fallar cuando el daemon usa el almacén de imágenes containerd (un error de digest de ctr). Guarda una plataforma e importa el archivo en su lugar. La plataforma debe coincidir con el nodo. Un archivo amd64 en un nodo arm64 falla al arrancar con un error de formato de ejecución.
docker image save --platform linux/amd64 --output web.tar example/web:1.4.0
kind load image-archive web.tar --name dev
Usa linux/arm64 cuando los nodos de kind son Apple Silicon.
Ingress y LoadBalancer son puertas diferentes:
- kind no instala un controlador de ingress o un balanceador de carga en la nube.
extraPortMappingssolo publica puertos de contenedor. Instala el controlador que usas en producción y enlázalo a 80 y 443 en ese nodo. Un Servicio LoadBalancer queda<pendiente>hasta que existe uno. Ejecutacloud-provider-kinden el host (go install sigs.k8s.io/cloud-provider-kind@latest, luego el binario, en primer plano). Necesita permiso para abrir puertos. MetalLB es la otra opción. - minikube habilita ingress-nginx con
minikube addons enable ingress -p dev. Para LoadBalancer, dejaminikube tunnel -p devcorriendo. Detenerlo cae las rutas. Puede solicitar una contraseña de administrador para cambiar las rutas del host. - k3d instala Traefik y k3s ServiceLB. Accede a ellos con
--port ...@loadbalancer. Desactiva Traefik antes de instalar un segundo controlador.
Los nombres de StorageClass difieren, por eso un manifiesto que funcionó en una laptop queda Pendiente en otra. Revisa con kubectl get storageclass. Un clúster kind por defecto y un clúster minikube por defecto llaman a la clase standard. Un clúster k3d por defecto la llama local-path. Un reclamo que establece storageClassName al nombre incorrecto no se vincula. Ve Pod Pendiente / FailedScheduling.
Cuándo elegir kind
Elige kind para probar contra kubeadm, o para ejecutar los mismos pasos create-load-apply en CI. Multi-nodo es un archivo de configuración. Ingress y LoadBalancer son instalaciones extra. Un trabajo típico es kind create cluster, kind load docker-image, kubectl apply, luego kubectl wait.
kubectl wait --for=condition=available deployment/api --timeout=120s
Cuándo elegir minikube
Elige minikube cuando quieras minikube addons list y un comando para ingress, o una VM Hyper-V, KVM o QEMU porque Docker no está disponible. minikube tunnel reemplaza un proceso cloud-provider. Es una opción de CI más débil: el controlador de Docker funciona, pero un túnel es un proceso de larga duración que un job raramente quiere.
Cuándo elegir k3d
Elige k3d cuando la RAM es escasa, la producción ya es k3s, o quieres Traefik y un balanceador de carga en el primer arranque. La API es Kubernetes. Traefik, ServiceLB, local-path y un plano de control más esbelto son defaults de k3s, no de kubeadm.
Ruta de migración
Mover entre estas herramientas no exporta el clúster. Los manifiestos en git son la fuente de verdad.
- Lista imágenes que no están en un registro (
docker images). Las volverás a cargar. - Libera los puertos del host 80 y 443 si los mapeaste.
- Crea el nuevo clúster. No enlaces puertos del host 80 y 443 en dos clústeres a la vez.
- Carga imágenes con el comando de esa herramienta. Un archivo kind no es un
k3d image import. kubectl config use-contextakind-dev,dev, ok3d-dev.kubectl apply -fokubectl apply -k. ArreglastorageClassNamesi un PVC queda Pendiente, e ingress class si el tráfico nunca llega (nginxen el complemento de minikube,traefiken k3d por defecto).- Elimina el clúster antiguo:
kind delete cluster --name dev,minikube delete -p dev, ok3d cluster delete dev.
En un clúster compartido, envía etiquetas a un registro y descarta mapeos de puertos del host. Docker Compose vs Kubernetes cubre el lado de la aplicación: Compose en un motor, estas herramientas para una API local, un clúster real cuando tienes más de una máquina.
Preguntas frecuentes
¿Qué herramienta de Kubernetes local es la más cercana a un clúster de producción?
kind. Cada nodo es un clúster kubeadm dentro de un contenedor, que es el mismo arranque que usa la mayoría de los clústeres ascendentes. k3d es una API Kubernetes real en k3s, con Traefik y un balanceador de servicios ya instalado. minikube es también una API real; sus complementos y su controlador son las partes que no coincidirán con tu clúster de producción.
¿Cómo cargo una imagen creada localmente sin un registro?
Cárgala en los nodos del clúster antes de aplicar. kind usa kind load docker-image, minikube usa minikube image load y k3d usa k3d image import. Fija una etiqueta que no sea latest, o establece imagePullPolicy: IfNotPresent, o kubelet intentará contactar al registro de todas formas.
¿Por qué un Servicio LoadBalancer queda en Pendiente?
Nada en kind implementa ese tipo de Servicio hasta que ejecutes cloud-provider-kind o instales MetalLB. minikube necesita que minikube tunnel siga ejecutándose en otra terminal. k3d viene con k3s ServiceLB y un contenedor proxy, así que la dirección aparece una vez que el clúster está arriba y publicas un puerto del host.
¿Puedo ejecutar kind, minikube y k3d al mismo tiempo?
Sí, si Docker tiene memoria y los puertos del host 80 y 443 no se reclaman dos veces. Cada herramienta escribe su propio contexto kubeconfig: kind-<nombre>, el nombre del perfil de minikube, y k3d-<nombre>. Cambia entre ellos con kubectl config use-context.
Cómo se verificó esta guía
Escrita a mano a partir de la documentación oficial, con cada comando comprobado de nuevo y una segunda revisión antes de publicar. Última revisión: .
Fuentes oficiales consultadas para este artículo

