improve minecraft performance by using a non nfs volume for live data

This commit is contained in:
Remy Moll 2025-04-26 14:07:34 +02:00
parent 75a7f6b9b7
commit 4ebc0b1069
4 changed files with 91 additions and 2 deletions

View File

@ -1,3 +1,11 @@
## Setup
Because minecraft is quite sensitive to io performance, we want the data to be stored on a local disk. But hostpath is not well supported in talos (and is not persistent), so we use an ephemeral volume instead. In order to do this, we create an emptyDir volume and mount it to the pod.
We use an initContaier that copies the data to the local storage. Afterwards, copying from the local storage back to the persistent storage is handled by a preStop lifecycle event.
This way, we can have the best of both worlds: fast local storage and persistent storage.
## Sending a command ## Sending a command
``` ```
kubectl exec -it -n minecraft deploy/minecraft-server -- /bin/bash kubectl exec -it -n minecraft deploy/minecraft-server -- /bin/bash

View File

@ -9,6 +9,16 @@ spec:
app: minecraft-server app: minecraft-server
spec: spec:
restartPolicy: OnFailure restartPolicy: OnFailure
initContainers:
- name: copy-data-to-local
image: alpine
command: ["/bin/sh"]
args: ["-c", "cp -r /data/* /local-data/"]
volumeMounts:
- name: local-data
mountPath: /local-data
- name: minecraft-data
mountPath: /data
containers: containers:
- name: minecraft-server - name: minecraft-server
image: minecraft image: minecraft
@ -49,12 +59,34 @@ spec:
value: "false" value: "false"
- name: ENABLE_AUTOSTOP - name: ENABLE_AUTOSTOP
value: "true" value: "true"
- name: AUTOSTOP_TIMEOUT_EST
value: "1800" # stop 30 min after last disconnect
volumeMounts: volumeMounts:
- name: minecraft-data - name: local-data
mountPath: /data mountPath: /data
- name: copy-data-to-persistent
image: rsync
command: ["/bin/sh"]
# args: ["-c", "sleep infinity"]
args: ["/run-rsync.sh"]
volumeMounts:
- name: local-data
mountPath: /local-data
- name: minecraft-data
mountPath: /persistent-data
- name: rsync-config
mountPath: /run-rsync.sh
subPath: run-rsync.sh
volumes: volumes:
- name: minecraft-data - name: minecraft-data
persistentVolumeClaim: persistentVolumeClaim:
claimName: minecraft-data claimName: minecraft-data
- name: local-data
emptyDir: {}
- name: rsync-config
configMap:
name: rsync-config
defaultMode: 0777

View File

@ -8,6 +8,7 @@ resources:
- pvc.yaml - pvc.yaml
- job.yaml - job.yaml
- service.yaml - service.yaml
- rsync.configmap.yaml
- curseforge.sealedsecret.yaml - curseforge.sealedsecret.yaml
@ -15,3 +16,9 @@ images:
- name: minecraft - name: minecraft
newName: itzg/minecraft-server newName: itzg/minecraft-server
newTag: java21 newTag: java21
- name: alpine
newName: alpine
newTag: "3.21"
- name: rsync
newName: eeacms/rsync
newTag: "2.6"

View File

@ -0,0 +1,42 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: rsync-config
data:
run-rsync.sh: |-
#!/bin/sh
set -eu
echo "Starting rsync..."
no_change_count=0
while [ "$no_change_count" -lt 3 ]; do
# use the i flag to get per line output of each change
rsync_output=$(rsync -avzi --delete /local-data/ /persistent-data/)
# echo "$rsync_output"
# in this format rsync outputs at least 4 lines:
# ---
# sending incremental file list
#
# sent 145,483 bytes received 717 bytes 26,581.82 bytes/sec
# total size is 708,682,765 speedup is 4,847.35
# ---
# even though a non-zero number of bytes is sent, no changes were made
line_count=$(echo "$rsync_output" | wc -l)
if [ "$line_count" -eq 4 ]; then
echo "Rsync output was: $rsync_output"
no_change_count=$((no_change_count + 1))
echo "No changes detected. Incrementing no_change_count to $no_change_count."
else
no_change_count=0
echo "Changes detected. Resetting no_change_count to 0."
fi
echo "Rsync completed. Sleeping for 10 minutes..."
sleep 600
done
echo "No changes detected for 3 consecutive runs. Exiting."