This guide will show you how to deploy BlueDragon using Kubernetes.
Note
Kubernetes is the recommended way to deploy BlueDragon in a production environment. With a Kubernetes deployment, you will have Agones , which allows you to perform rolling game server updates without kicking players, and Puffin , which coordinates with your game servers and ensures that an appropriate number of games are running at all times.
Prerequisites
A running Kubernetes cluster (v1.26+)
Helm v3+ installed and configured
kubectl installed and configured
Container Registry
Before running any BlueDragon images, you need to push them to your own container registry.
On Microk8s
If you’re using microk8s
, you can install the built-in registry with microk8s enable registry
.
Your base registry URL will be the IP address of your cluster on port 32000
. You may also be able to use localhost
.
For more information, see the registry plugin documentation .
On Minikube
If you’re using minikube
, see their official documentation on registries.
Outside the Cluster
You can also create a registry outside of your cluster and configure it for use within the cluster.
For more information, see the official documentation .
Install Agones
When running on Kubernetes, BlueDragon uses Agones to orchestrate game servers. To install Agones , run the following commands:
kubectl create namespace agones-system
kubectl apply --server-side -f https://raw.githubusercontent.com/googleforgames/agones/release-1.38.0/install/yaml/install.yaml
You can also install it via Helm by running:
helm repo add agones https://agones.dev/chart/stable
helm install agones --namespace agones-system --create-namespace agones/agones
Deploy MongoDB
There are many ways to deploy MongoDB on Kubernetes. In production, we recommend using the MongoDB Community Operator, which can be installed via Helm by running:
helm repo add mongodb https://mongodb.github.io/helm-charts
helm install community-operator mongodb/community-operator
Then, you can create a MongoDB ReplicaSet
by applying some YAML to your cluster in the default
namespace:
apiVersion : mongodbcommunity.mongodb.com/v1
name : mongodb-bluedragon-password
scramCredentialsSecretName : bluedragon
storage.wiredTiger.engineConfig.journalCompressor : zlib
name : mongodb-bluedragon-password
password : <your MongoDB password>
Replace <your MongoDB password>
with the password you want to use for your MongoDB user. Then, save the file and apply it to your cluster.
After a few minutes, the operator should create a secret in the default namespace called mongodb-instance-admin-bluedragon
. It will contain a key called connectionString.standard
, which other services will use to connect.
Deploy LuckPerms
Create a Deployment and a Service for LuckPerms:
image : ghcr.io/luckperms/rest-api
- name : LUCKPERMS_STORAGE_METHOD
- name : LUCKPERMS_DATA_MONGODB_CONNECTION_URI
# Populate the environment variable using the MongoDB operator's autogenerated secret
name : mongodb-instance-admin-bluedragon
key : connectionString.standard
- name : LUCKPERMS_DATA_DATABASE
- name : LUCKPERMS_SYNC_MINUTES
name : luckperms # This name is used for DNS lookups in other pods
Apply this file to your cluster to deploy LuckPerms in the default
namespace under the hostname luckperms
.
Giving Yourself Permissions
To give yourself permissions, you can run the following command:
kubectl run luckperms-temp --env=LUCKPERMS_STORAGE_METHOD=mongodb --env=LUCKPERMS_DATA_DATABASE=luckperms --env= " LUCKPERMS_DATA_MONGODB_CONNECTION_URI=$( kubectl get secret mongodb-instance-admin-bluedragon -o jsonpath= " {.data.connectionString\.standard} " | base64 -d ) " --rm -it --image=ghcr.io/luckperms/rest-api:latest
Once the LuckPerms container starts, run the following command:
lp user <your username> permission set * true
This gives you all permissions. Then, exit the container by pressing Ctrl+C
and then run:
kubectl rollout restart deployment luckperms
This will restart the existing LuckPerms pod, forcing it to pick up your new permissions.
Deploy Puffin
Required Files
This Puffin deployment requires a folder on the host machine located at /data/worlds
.
This folder should contain one folder per game, and each of those should contain one folder per world.
For more information, see the Worlds Folder guide.
Apply this manifest to your cluster to install Puffin and give it the necessary permissions to watch Kubernetes and Agones resources:
# This ServiceAccount is used to allow Puffin to use the Kubernetes API for certain resources
serviceAccountName : puffin-service-account
image : <your registry url>/bluedragonmc/puffin:latest
- name : PUFFIN_WORLD_FOLDER
- name : PUFFIN_MONGO_CONNECTION_STRING
# Populate the environment variable using the MongoDB operator's autogenerated secret
name : mongodb-instance-admin-bluedragon
key : connectionString.standard
mountPath : /puffin/worlds
mountPath : /service/config
- key : buffer-config.properties
path : buffer-config.properties
name : puffin # This name is used for DNS lookups in other pods
name : puffin-service-account
# Allow Puffin to get, list, and watch pods and Agones resources
apiVersion : rbac.authorization.k8s.io/v1
name : puffin-cluster-role
# Bind the ClusterRole to the ServiceAccount that the Puffin Deployment uses
apiVersion : rbac.authorization.k8s.io/v1
name : puffin-cluster-role-binding
name : puffin-cluster-role
apiGroup : rbac.authorization.k8s.io
name : puffin-service-account
# `buffer-config.properties` defines Puffin's desired state of running games.
# See the Buffer Config guide for more information.
buffer-config.properties : |
# Defines the required "buffer" of instances for each game type, map name, and mode.
# For keys: <game type>_<map name>_<mode>
# <mode> is optional. If it's not included, the last _ should also be omitted.
# - Each term can consist of a number and one optional operator prefixing it
# - Valid operators include:
# - "+" takes the current amount of joinable servers and adds the following quantity to it
# - "/" takes the current amount of logged in players and divides it by the following quantity (and adds one)
# - A plain number will result in that number of instances.
# - "/25" makes one server for every 25 players, rounding down: floor(n / 25), where n is the current number of players
# - "+1" keeps one additional server as a "buffer" if all other servers are full.
# - "+3" keeps a buffer of 3 servers. This means that, at most times, there will be 3 joinable game servers of this type.
# - "/25 +5" creates 1 server for every 25 players, plus a buffer of 5 servers that must be joinable.
# - Plain numbers and the "/" operator are not influenced by the status of each server (whether there are any empty slots).
# ^ Keep 1 server for ArenaPvP, plus one for every 10 players
Infinijump_Classic_Solo=+2
Infinijump_Classic_Versus=+2
Infinijump_Classic_Race=+1
# ^ Keep 2 lobbies with empty player slots as well as one for every 25 players
Modify the buffer config according to this guide , replace <your registry url>
with your Docker registry, and apply the YAML to your cluster.
Deploy Velocity Proxy
Forwarding Secret
Before deploying Velocity, you will need a forwarding secret. You can randomly generate one using the following command:
kubectl create secret generic proxy-forwarding-secret --from-literal=secret=$(openssl rand -hex 48 )
If you don’t have OpenSSL installed, you can generate a random one using a service like this one .
image : <your registry url>/bluedragonmc/komodo:latest
mountPath : /proxy/config/
mountPath : /proxy/plugins/bluedragon-jukebox/songs/
- name : PUFFIN_VELOCITY_SECRET
name : proxy-forwarding-secret
- name : LUCKPERMS_STORAGE_METHOD
- name : LUCKPERMS_DATA_MONGODB_CONNECTION_URI
name : mongodb-instance-admin-bluedragon
key : connectionString.standard
- name : LUCKPERMS_DATA_DATABASE
- key : proxy-config.properties
path : proxy-config.properties
# This NodePort exposes the proxy to the internet on port 30000.
# If you are using a cloud provider or MetalLB, the NodePort can
# be switched out for a LoadBalancer.
name : proxy # This name is used for DNS lookups in other pods
# This ConfigMap is mounted into the proxy pod at /proxy/config/proxy-config.properties
proxy-config.properties : |
motd.line_1.text=<bold><gradient:#4EB2F4:#3336f4>BlueDragon</gradient></bold> <gray>[<green>1.20.1<gray>]
Replace <your registry url>
with your Docker registry, and apply the YAML to your cluster.
Deploy Minecraft Server Fleet
apiVersion : " agones.dev/v1 "
# This image should be based on bluedragonmc/server,
# but should also include your minigame JARs.
image : <your registry url>/bluedragonmc/server:latest
- name : PUFFIN_VELOCITY_SECRET
name : proxy-forwarding-secret
- name : BLUEDRAGON_MONGO_CONNECTION_STRING
name : mongodb-instance-admin-bluedragon
key : connectionString.standard
# Agones takes 30m for its sidecar container, so in total, the pod requests 1/2 of a CPU.
mountPath : /server/worlds
Replace <your registry url>
with your Docker registry, and apply the YAML to your cluster.
You can scale the Fleet of game servers by running:
kubectl scale fleet server --replicas=10 # 10 is the number of game server instances you want to run
That’s It!
Congratulations, you’ve successfully deployed BlueDragon on Kubernetes!
You should be able to connect to the server on port 30000
.
If the port is not forwarded, then you can temporarily use kubectl
as a proxy:
kubectl port-forward svc/proxy 30000:30000
Then, connect to the server on localhost:30000
.