Servidor Minecraft en Kubernetes: guía completa 2026

“`html

En pocas palabras: Un servidor de Minecraft corre en Kubernetes con tres manifiestos: un Deployment con la imagen itzg/minecraft-server, un PersistentVolumeClaim de 10Gi para guardar el mundo y un Service tipo LoadBalancer que expone el puerto del juego, siempre con replicas: 1.

Ejecutar un Servidor Minecraft en Kubernetes se resume en tres manifiestos: un Deployment con la imagen de itzg, un PersistentVolumeClaim de 10Gi para el mundo y un Service tipo LoadBalancer para exponer el juego. Así lo muestra la tercera parte de la serie publicada en dev.to.

Un servidor de Minecraft en Kubernetes es un contenedor del juego orquestado por un clúster mediante tres recursos: un Deployment que corre la imagen pública de itzg (minecraft-server para Java, minecraft-bedrock-server para Bedrock), un PersistentVolumeClaim que guarda el mundo y un Service que expone el puerto del juego. El tutorial fue publicado en dev.to por el usuario celsonery.

En 30 segundos

  • Las imágenes base son itzg/minecraft-server (Java) y itzg/minecraft-bedrock-server (Bedrock), ambas públicas en Docker Hub.
  • El mundo se guarda en un PersistentVolumeClaim de 10Gi; sin él, cada reinicio del pod arranca con un mundo vacío.
  • Siempre replicas: 1. El juego no soporta varias instancias escribiendo el mismo guardado.
  • Java habla TCP por el puerto 25565; Bedrock, UDP por el 19132.
  • En clústeres on-premise, el LoadBalancer queda en PENDING hasta instalar MetalLB.

¿Por qué migrar tu servidor Minecraft a Kubernetes?

Ponele que ya hiciste la tarea de las partes anteriores: instalaste el server a mano en una máquina, después lo containerizaste con Docker, volúmenes y restart automático. Todo funciona. Hasta que el disco se llena, o la máquina se apaga, o querés mover el server a otro host y descubrís que estás casado con ese hardware.

Migrar a Kubernetes resuelve justo eso. Según el tutorial de celsonery en dev.to, el salto al clúster aporta tres cosas concretas:

  • Almacenamiento manejado: el PersistentVolumeClaim garantiza que el mundo sobreviva a reinicios y recreaciones del pod, sin que vos administres volúmenes a mano.
  • Libertad de nodo: el pod puede correr en cualquier nodo disponible del clúster; dejás de depender de una sola máquina física.
  • Aislamiento limpio: un Namespace propio separa los recursos de Minecraft del resto del clúster.

Ojo con una expectativa común: esto escala la infraestructura, no el servidor. Minecraft es un juego con estado (el mundo guardado), así que no podés replicarlo horizontal como una API sin estado. Una sola instancia consistente accediendo al volumen, siempre.

¿Qué necesitás antes de empezar?

Cuatro cosas, ni una más:

  • Un clúster Kubernetes funcionando, sea en la nube (donde el LoadBalancer asigna IP solo) u on-premise.
  • kubectl configurado y con acceso al clúster.
  • Nociones básicas de Deployment, Service y volúmenes; si nunca viste un PVC, la documentación oficial de Kubernetes lo explica mejor que yo.
  • Las imágenes de itzg en Docker Hub, estándar de facto para self-hostear Minecraft.

Esta guía es la parte 3 de una serie: la parte 1 cubre la instalación bare metal y la parte 2, Docker. Si venís desde ahí, todo te va a sonar.

¿Cuál es la diferencia entre Minecraft Java y Bedrock en Kubernetes?

La diferencia de fondo está en el protocolo: Java se comunica por TCP en el puerto 25565, mientras que Bedrock usa UDP en el 19132. Eso cambia cómo escribís el Service y cómo abrís el firewall, así que conviene definirlo antes de desplegar.

CaracterísticaMinecraft JavaMinecraft Bedrock
Imagen Dockeritzg/minecraft-serveritzg/minecraft-bedrock-server
ProtocoloTCPUDP
Puerto2556519132
DispositivosPC (Windows, macOS, Linux)Consolas, celulares y Windows
Mods y pluginsEcosistema amplioSin mods tradicionales
Variables claveMEMORY, VERSION, ONLINE_MODEEULA, GAMEMODE, DIFFICULTY
servidor minecraft en kubernetes diagrama explicativo

En la práctica, la elección depende de con quién jugás. Si tu grupo está en PC y quiere mods, Java. Si mezclan consolas y celulares, Bedrock.

¿Qué componentes necesita un Servidor Minecraft en Kubernetes?

Cuatro recursos hacen todo el trabajo, y conviene tenerlos claros antes de copiar el YAML.

  • PersistentVolumeClaim (PVC): es un pedido de almacenamiento que el pod le hace al clúster. Para Minecraft, el tutorial reserva 10Gi donde vive el mundo guardado; sin ese volumen, cada nuevo pod arranca con un mundo vacío (spoiler: nadie quiere ser el que le explique eso a los jugadores).
  • Deployment: define el contenedor, la imagen y las variables de entorno. Acá va fijo replicas: 1 (y no es capricho).
  • Service: expone el puerto del juego fuera del clúster; el tipo LoadBalancer es el que usa el tutorial.
  • Namespace: agrupa y aísla todos estos recursos bajo un mismo techo.

¿Por qué una sola réplica y no tres? Porque el motor del juego no soporta que varias instancias escriban el mismo guardado a la vez. ¿Y qué pasa si lo intentás de todas formas? Exacto: datos corruptos y un mundo que hay que restaurar desde backup, si es que tenés backup.

Cómo desplegar servidor Minecraft Bedrock en Kubernetes

Arrancamos por Bedrock porque es el flujo más directo. El manifiesto del tutorial junta los cuatro recursos en un solo archivo, minecraft-bedrock.yaml:

apiVersion: v1
kind: Namespace
metadata:
 name: minecraft-br
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: minecraft-bedrock-pvc
 namespace: minecraft-br
spec:
 accessModes: ["ReadWriteOnce"]
 resources:
 requests:
 storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: minecraft-bedrock-server
 namespace: minecraft-br
spec:
 replicas: 1
 selector:
 matchLabels:
 app: minecraft-bedrock
 template:
 metadata:
 labels:
 app: minecraft-bedrock
 spec:
 containers:
 - name: minecraft-bedrock
 image: itzg/minecraft-bedrock-server:latest
 env:
 - name: EULA
 value: "TRUE"
 - name: GAMEMODE
 value: "survival"
 - name: DIFFICULTY
 value: "normal"
 ports:
 - containerPort: 19132
 protocol: UDP
 volumeMounts:
 - name: minecraft-bedrock-data
 mountPath: /data
 volumes:
 - name: minecraft-bedrock-data
 persistentVolumeClaim:
 claimName: minecraft-bedrock-pvc
---
apiVersion: v1
kind: Service
metadata:
 name: minecraft-bedrock-service
 namespace: minecraft-br
spec:
 type: LoadBalancer
 selector:
 app: minecraft-bedrock
 ports:
 - port: 19132
 targetPort: 19132
 protocol: UDP

Lo aplicás y verificás:

kubectl apply -f minecraft-bedrock.yaml
kubectl get pods -n minecraft-br

Subís el manifiesto, el scheduler elige un nodo con lugar, el kubelet baja la imagen de itzg, el contenedor descarga los archivos del server por primera vez, monta el PVC y a los pocos minutos tenés el mundo andando con tus amigos adentro. Para seguir el proceso en vivo: kubectl logs deployment/minecraft-bedrock-server -n minecraft-br.

Un detalle que el tutorial remarca y muchos otros omiten: en clústeres on-premise, el tipo LoadBalancer normalmente no provisiona una IP automáticamente (eso es una feature de los proveedores cloud). Necesitás un controlador como MetalLB para que el Service reciba una IP externa usable. Sin él, la IP queda en PENDING indefinidamente. Relacionado: Windows frente a Ubuntu en rendimiento real.

Cómo desplegar servidor Minecraft Java en Kubernetes

La receta Java es casi idéntica, con una diferencia estructural: el Service declara el protocolo TCP en el 25565, coherente con lo que la parte 2 de la serie mostró sobre la comunicación de esta edición. La imagen suma, además, variables de entorno propias:

env:
 - name: EULA
 value: "TRUE"
 - name: MEMORY
 value: "2G"
 - name: VERSION
 value: "1.21"
 - name: ONLINE_MODE
 value: "TRUE"
  • MEMORY: fija el límite de memoria que la imagen le pasa a la JVM internamente, equivalente al flag -Xmx de una instalación a pelo.
  • VERSION: te permite clavar una versión específica del juego en vez de usar siempre la última; útil cuando un mod todavía no se actualizó.
  • ONLINE_MODE: exige autenticación con cuenta válida de Microsoft/Mojang. Desactivalo solo si sabés exactamente por qué (usualmente, clientes no originales, con implicaciones de seguridad y legales incluidas).

¿Cómo expongo mi servidor Minecraft fuera del clúster?

El Service tipo LoadBalancer es la puerta de entrada. En un clúster cloud (AWS, Azure, Google Cloud), el proveedor asigna una IP externa apenas creás el Service. En on-premise, hace falta MetalLB u otro controlador equivalente.

Si no podés instalar MetalLB, el plan B es un Service tipo NodePort: Kubernetes abre el puerto en cada nodo y te conectás a nodo:puerto. Es menos prolijo, porque tenés que recordar el puerto alto que asigna, pero zafa para labs caseros.

Mejores prácticas y solución de problemas

  • Una réplica, siempre: resistí la tentación de subir replicas “para que rinda más”; el resultado es corrupción del guardado, no performance.
  • Ajustá MEMORY a la realidad del nodo: si el contenedor pide más heap de la que tiene la máquina, el kernel mata el pod y el server entra en loop de reinicios.
  • Mirá los logs antes de tocar nada: kubectl logs deployment/minecraft-server te dice si falta el EULA, si la descarga inicial sigue en curso o si el mundo cargó bien.
  • Verificá que el PVC esté Bound: un claim en Pending significa que ningún volumen satisfizo el pedido, y el pod ni va a arrancar.
SíntomaCausa probableSolución
IP externa en PENDINGFalta MetalLB en on-premiseInstalar MetalLB o cambiar a NodePort
El pod reinicia en loopEULA sin aceptarAgregar EULA=TRUE al Deployment
Conexión rechazadaPuerto o protocolo mal declarado25565/TCP para Java, 19132/UDP para Bedrock
El mundo aparece vacíoPVC no montado o no BoundRevisar volumeMounts y el estado del claim

Qué está confirmado y qué no

Confirmado, según el tutorial: el PVC de referencia reserva 10Gi, el Deployment exige una única réplica, la imagen Java soporta las variables MEMORY, VERSION y ONLINE_MODE, y el primer arranque descarga los archivos del server, lo que toma minutos. Sobre eso hablamos en cómo evitar caídas con DNS autoritativos.

Lo que las fuentes no aclaran: no hay benchmarks de rendimiento del server dentro del clúster, no hay cifras de costo de infraestructura cloud, y el tutorial no menciona un operador de Kubernetes específico para Minecraft. ¿Alguien midió performance de forma independiente? Todavía no, así que cualquier promesa en esa dirección, tomala con pinzas.

Errores comunes al llevar Minecraft a Kubernetes

Tres tropiezos que aparecen una y otra vez cuando alguien pasa de Docker Compose a un clúster con un server de juegos:

  • Tratar el server como una API sin estado. El reflejo DevOps es escalar horizontal ante carga; con Minecraft eso corrompe el mundo. La escala acá es vertical: más RAM al nodo y más MEMORY a la JVM.
  • Probar “rápido” sin PVC. Levantás el pod sin volumen para ver si anda, funciona, y una semana después el clúster reprograma el pod a otro nodo. Adiós mundo. El PVC va desde el día uno.
  • Asumir que LoadBalancer es universal. En tu lab con k3s o Minikube la IP no aparece sola; sin MetalLB esperás sentado. Fijate qué proveedor de LoadBalancer trae tu distribución antes de culpar al YAML.

Preguntas Frecuentes

¿Cómo ejecuto un servidor Minecraft en Kubernetes?

Creás un Namespace, un PersistentVolumeClaim de 10Gi, un Deployment con la imagen itzg/minecraft-server (Java) o itzg/minecraft-bedrock-server (Bedrock) con replicas: 1, y un Service tipo LoadBalancer. Aplicás todo con kubectl apply y seguís los logs hasta que el mundo termine de cargar.

¿Qué es un PersistentVolumeClaim para Minecraft?

Es un pedido de almacenamiento que reserva espacio en el clúster para los datos del juego. En el tutorial de dev.to, el PVC minecraft-bedrock-pvc reserva 10Gi y garantiza que el mundo sobreviva a reinicios y recreaciones del pod.

¿Cuál es la diferencia entre Minecraft Java y Bedrock en Kubernetes?

Java usa TCP en el puerto 25565 con la imagen itzg/minecraft-server; Bedrock usa UDP en el 19132 con itzg/minecraft-bedrock-server. Java soporta mods y expone variables como MEMORY y VERSION; Bedrock se configura con EULA, GAMEMODE y DIFFICULTY.

¿Cómo expongo mi servidor Minecraft fuera del clúster?

Con un Service tipo LoadBalancer, que asigna una IP externa automáticamente en clouds públicos. En clústeres on-premise necesitás MetalLB u otro controlador; sin él, la IP queda en PENDING. Como alternativa simple existe NodePort.

¿Se puede escalar horizontalmente un servidor de Minecraft en Kubernetes?

No. El mundo guardado es estado compartido y el motor del juego no soporta múltiples instancias escribiendo sobre el mismo volumen. La única réplica válida es una; para más capacidad, sumá recursos al nodo.

Conclusión

La serie deja una progresión clara: bare metal resolvió “que ande”, Docker resolvió persistencia y reinicio automático, y Kubernetes agrega almacenamiento manejado e independencia del hardware. Cada etapa tapó una limitación de la anterior.

Si tu caso es un server para amigos con mods y presupuesto acotado, Docker Compose en un VPS sigue siendo lo más simple (y un hosting administrado como donweb.com te evita hasta eso). Kubernetes se justifica cuando ya tenés un clúster, querés que el server sobreviva a la caída de un nodo o simplemente querés aprender orquestación con algo divertido. Que, seamos honestos, es la mejor razón de todas.

¿Cuánta RAM necesita un servidor de Minecraft en Kubernetes?

Depende de la cantidad de jugadores y de si usás mods: para un grupo chico en vanilla, la variable MEMORY en 2G alcanza, mientras que los modpacks pesados suelen pedir 4G o más. Dejá siempre margen por debajo del límite del nodo, porque si el contenedor pide más memoria de la disponible, Kubernetes lo mata con un error OOMKilled.

¿Cómo hago backup del mundo de mi servidor Minecraft en Kubernetes?

El mundo vive entero dentro del PVC, así que lo más directo es copiar el contenido de la carpeta /data del contenedor o usar una herramienta de backup de volúmenes como Velero. Hacelo con el servidor detenido o en horario de poca actividad: copiar el mundo mientras se está escribiendo puede dejar el guardado corrupto.

¿Cómo me conecto a mi servidor Minecraft una vez desplegado en Kubernetes?

Con la IP externa que le asignó el LoadBalancer: corré kubectl get svc -n minecraft-br (o el namespace que hayas usado) y tomá el valor de EXTERNAL-IP. En Java agregás esa IP con el puerto 25565 en la lista de servidores del juego; en Bedrock, la misma IP con el puerto 19132.

Fuentes

Te puede interesar...