Ever wanted to put your Rapsberry Pi cluster to great use? Our team is working remotely, so we started to play Minecraft. I decided I would host the Minecraft server on my Raspberry Pi cluster. This gist will guide you through the steps I took to get a k3s cluster up with k3sup and later installed Minecraft as well as metrics exporter and Prometheus Operator
Quoniam Possumus - Because we can
-
Raspberry Pis to run kubernetes on. I used 3 Raspberry Pi 3 and one Raspberry Pi 4.
-
A copy of the game Minecraft Java Edition so you can play on your server.
Read about how you can install kubernetes to your Raspberry Pi in 15 minutes
Or visit https://k3sup.dev/ to setup your cluster.
Note, If you are using Raspberry Pi 4, consider using a 64 bit kernel to utilize more than 2 GB memory per process.
To give the node where Minecraft is running access to the whole CPU and RAM you'll need to taint it so it only tolerates the Minecraft Server
kubectl taint nodes minecraft-node app=minecraft:NoSchedule
And to make sure that the minecraft installation will select the node it tolerates you'll also need to label the node.
kubectl label nodes minecraft-node role=minecraft
This is the helmchart that we will use https://github.com/helm/charts/tree/master/stable/minecraft
Minecraft Server comes in many flavours.
-
To install Minecraft and later install Minecraft Prometheus Export plugin we need to use the
SPIGOT
distribution of Minecraft Server, you can also runPAPER
. This is also running more lightweight thanVANILLA
Minecraft which is a perfect fit for Raspberry Pi. -
We need to make sure we are using the correct Minecraft Server image
itzg/minecraft-server:multiarch
-
Further more Minecraft needs to have the
tolerations
that we tainted the minecraft-node with and thenodeSelector
-
Minecraft on Raspberry Pi takes longer time to start than on modern servers, the readyness and liveness probe is turned up a lot. If you have problems with restarts, try to increase the probes even more.
All of these settings are represented in the values file that will be used with the helm chart for Minecraft.
Create the values.yaml
below to use with your helm installation.
kubectl create namespace minecraft
helm install --namespace minecraft minecraft -f values.yaml stable/minecraft
Make sure Minecraft has started and is in Ready
state
kubectl get pods -n minecraft
Lookup the IP address for your Minecraft Server.
kubectl get service -n minecraft
Use the IP of the loadbalancer to start playing right away. Or continue with metrics.
Now we will install
- One plugin to expose metrics that can be scraped by Prometheus
- Prometheus Operator to get a full fledged monitoring system
To get metrics scraped we need to install a Bukkit plugin for just this.
The plugin we are going to install can be found here https://github.com/sladkoff/minecraft-prometheus-exporter
This step requires manual labour inside the minecraft containers.
Get the latest release from minecraft-prometheus-exporter, it is the .jar
file that you want to use. Copy that into the Minecraft pod's mounted volume, where the plugins should go.
kubectl cp minecraft-prometheus-exporter-<VERSION>.jar minecraft/minecraft-minecraft-<POD-ID>:/data/plugins
Next restart the pod by deleteing the pod, and it will restart again
We need to make one more change, make sure the exporter listens to all traffic. Exec into the pod and change the config.yml
of the minecraft-prometheus-exporter, as described on the plugins README.md file.
# Note that the HTTP server binds to localhost by default.
# If your Prometheus runs on another host or inside a Kubernetes cluster
# set this to any reachable IP or 0.0.0.0 to listen on all interfaces.
host: localhost
port: 9225
Connect to your pod:
kubectl exec -it -n minecraft minecraft-minecraft-<POD-ID> -- /bin/bash
Edit the config file as per our needs set host to 0.0.0.0 instead of localhost
nano plugins/PrometheusExporter/config.yml
host: 0.0.0.0
port: 9225
...
and exit the pod
exit
Now we need to expose the 9225 port from the deployment as well
kubectl patch deployment -n minecraft minecraft-minecraft --type='json' -p='[{"op":"add", "path": "/spec/template/spec/containers/0/ports/-", "value":{"containerPort":9225, "name":"metrics"}}]'
This adds a port entry with containerPort: 9225
and name: metrics
.
The end result will look like this
...e: minecraft-minecraft
ports:
- containerPort: 25565
name: minecraft
protocol: TCP
- containerPort: 9225
name: metrics
protocol: TCP
readine...
Install the Prometheus Operator. To do this an ARM (Raspberry Pi architecture) I used https://github.com/uocxp/prometheus-operator-chart-arm.
Prometheus is using ServiceMonitors to scrape endpoints. We need to create a ServiceMonitor that let us scrape a port that we now produce metrics on.
Create a servicemonitor.yaml
below.
kubectl apply -f servicemonitor.yaml
Note that the namespace of the service monitor should be the same as where you installed prometheus operator
-
The label
release: prometheus-operator
needs to be there because the operator only listens to ServiceMonitors with that label by default. -
The targetPort is the one that we just created in the previous step and the app: minecraft-minecraft comes from the helm chart.
-
The relabeling is to get the node as server_name on the dashboards.
Now you are ready to open up Grafana and install the two dashboards that can be found on the minecraft-prometheus-exporter repository.
kubectl port-forward -n monitor svc/prometheus-operator-grafana 3000:80
Open a browser to http://localhost:3000 and login with the default username and password for prometheus-operator
admin
prom-operator
Ah or... you have the node selector...
You can remove that part from the values.yaml file. If the none of the nodes have this role.