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. extraPortMappings solo 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. Ejecuta cloud-provider-kind en 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, deja minikube tunnel -p dev corriendo. 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.

  1. Lista imágenes que no están en un registro (docker images). Las volverás a cargar.
  2. Libera los puertos del host 80 y 443 si los mapeaste.
  3. Crea el nuevo clúster. No enlaces puertos del host 80 y 443 en dos clústeres a la vez.
  4. Carga imágenes con el comando de esa herramienta. Un archivo kind no es un k3d image import.
  5. kubectl config use-context a kind-dev, dev, o k3d-dev.
  6. kubectl apply -f o kubectl apply -k. Arregla storageClassName si un PVC queda Pendiente, e ingress class si el tráfico nunca llega (nginx en el complemento de minikube, traefik en k3d por defecto).
  7. Elimina el clúster antiguo: kind delete cluster --name dev, minikube delete -p dev, o k3d 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

Share.

Los comentarios están cerrados.