DEV Community

Celso Nery
Celso Nery

Posted on

Servidor Minecraft - Parte 3: Rodando no Kubernetes

🇺🇸 English version comming soon

Servidor Minecraft - Parte 3: Rodando no Kubernetes

Na Parte 2 desta série, colocamos o servidor Minecraft para rodar em containers Docker, com persistência via volumes e reinício automático. Neste artigo, vamos levar o mesmo servidor para dentro de um cluster Kubernetes, ganhando armazenamento gerenciado via PersistentVolumeClaim, isolamento por Namespace e a flexibilidade de rodar em qualquer nó disponível do cluster.

Minecraft Bedrock no Kubernetes

---
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
          ports:
            - containerPort: 19132
              protocol: UDP
          env:
            - name: EULA
              value: "TRUE"
            - name: GAMEMODE
              value: "survival"
            - name: MAX_PLAYERS
              value: "10"
            - name: MOTD
              value: "Servidor Bedrock Minecraft!"
            - name: OPS
              value: "seu_username"
          volumeMounts:
            - mountPath: /data
              name: minecraft-bedrock-data
      volumes:
        - name: minecraft-bedrock-data
          persistentVolumeClaim:
            claimName: minecraft-bedrock-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: minecraft-bedrock-service
  namespace: minecraft-br
spec:
  selector:
    app: minecraft-bedrock
  ports:
    - name: bedrock-udp
      port: 19132
      targetPort: 19132
      protocol: UDP
  type: LoadBalancer
Enter fullscreen mode Exit fullscreen mode

Repare na estrutura, que junta vários conceitos já vistos ao longo da série:

  • Namespace (minecraft-br): isola os recursos do Minecraft Bedrock do restante do cluster;
  • PersistentVolumeClaim (10Gi): garante que o mundo salvo sobreviva a reinicializações e recriações do pod, sem isso, cada novo pod começaria com um mundo vazio;
  • Deployment: roda uma única réplica (replicas: 1), múltiplas réplicas de um mesmo mundo Minecraft não funcionam, já que o jogo não foi projetado para múltiplas instâncias acessando o mesmo save simultaneamente;
  • Service do tipo LoadBalancer, na porta UDP 19132, expondo o servidor para fora do cluster.

Em clusters on-premise, o tipo LoadBalancer normalmente não provisiona um IP automaticamente (isso é um recurso nativo de provedores de nuvem), é necessário um controlador como o MetalLB para que o Service realmente receba um IP externo utilizável. Sem isso, o Service ficará com o IP externo em estado <pending> indefinidamente.

Minecraft Java no Kubernetes

apiVersion: v1
kind: Namespace
metadata:
  name: minecraft-java
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: minecraft-pvc
  namespace: minecraft-java
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: minecraft-server
  namespace: minecraft-java
spec:
  replicas: 1
  selector:
    matchLabels:
      app: minecraft
  template:
    metadata:
      labels:
        app: minecraft
    spec:
      containers:
        - name: minecraft
          image: itzg/minecraft-server:latest
          ports:
            - containerPort: 25565
          env:
            - name: EULA
              value: "TRUE"
            - name: MEMORY
              value: "1G"
            - name: VERSION
              value: "latest"
            - name: MAX_PLAYERS
              value: "10"
            - name: MOTD
              value: "Bem-vindo ao servidor Minecraft"
            - name: ONLINE_MODE
              value: "TRUE"
            - name: WHITELIST
              value: "false"
            - name: OPS
              value: "seu_username"
          volumeMounts:
            - mountPath: /data
              name: minecraft-data
      volumes:
        - name: minecraft-data
          persistentVolumeClaim:
            claimName: minecraft-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: minecraft-service
  namespace: minecraft-java
spec:
  selector:
    app: minecraft
  ports:
    - name: mc-tcp
      port: 25565
      targetPort: 25565
      protocol: TCP
  type: LoadBalancer
Enter fullscreen mode Exit fullscreen mode

Diferente do Bedrock, aqui a porta do containerPort e do Service usam TCP (o padrão, quando protocol não é especificado no container, mas explicitado no Service para clareza), coerente com o fato de o Minecraft Java se comunicar via TCP, como vimos na Parte 2.

Alguns campos de ambiente específicos dessa imagem:

  • MEMORY: define o limite de memória passado para a JVM internamente pela imagem (equivalente ao -Xmx visto na instalação bare metal);
  • VERSION: permite fixar uma versão específica do Minecraft (por exemplo, "1.20.4") em vez de sempre usar a mais recente;
  • ONLINE_MODE: quando "TRUE", exige que os jogadores estejam autenticados com uma conta Microsoft/Mojang válida, desative apenas se souber exatamente por que precisa (geralmente para servidores com clientes piratas, o que tem implicações de segurança e legalidade).

Aplicando os manifestos

kubectl apply -f minecraft-bedrock.yaml
kubectl apply -f minecraft-java.yaml
Enter fullscreen mode Exit fullscreen mode

Verificando se os pods subiram corretamente:

kubectl -n minecraft-br get po

e

kubectl -n minecraft-java get po
Enter fullscreen mode Exit fullscreen mode

Acompanhando os logs de inicialização (o primeiro start baixa os arquivos do servidor, podendo levar alguns minutos):

kubectl -n minecraft-java logs -f deploy/minecraft-server

e

kubectl -n minecraft-br logs -f deploy/minecraft-bedrock-server
Enter fullscreen mode Exit fullscreen mode

Considerações finais da série

Ao longo desta série, vimos o mesmo servidor Minecraft por três estágios: instalação manual bare metal, containerização com Docker, e por fim orquestração em um cluster Kubernetes. Cada estágio resolveu uma limitação do anterior, do gerenciamento manual de processos, passando por persistência e reinício automático, até chegar em armazenamento gerenciado e independência de um único host físico.

Vale reforçar um ponto importante que se aplica às três abordagens: por se tratar de um jogo com estado (o "mundo" salvo), não é possível escalar horizontalmente rodando múltiplas réplicas do mesmo servidor, diferente de uma API stateless, o Minecraft precisa de uma única instância consistente acessando o volume de dados por vez.

Top comments (0)