Customizing Game Server State
Overview
Games are stateful services. OpenKruiseGame allows defining game server states, and developers can set corresponding handling actions based on different game server states. For example, when scaling down, only scale down idle game server Pods (no players in that room).
Detection Script
The container image of docker-minecraft-server provides the mc-health script. Executing it can detect the status of minecraft-server, including statistics on the number of online players:
$ mc-health
localhost:25565 : version=1.21 online=1 max=20 motd='A Minecraft Server'
We can write another script as a wrapper to detect whether the game server is idle. When online=0 is detected, return an exit code of 0, indicating the game server is idle:
#!/bin/bash
result=$(mc-health | grep "online=0")
if [ "$result" != "" ]; then
exit 0
fi
exit 1
Eventually, this script needs to be placed in a ConfigMap. If you deploy using kustomize, you can use configMapGenerator in kustomization.yaml to reference this script file and generate the corresponding ConfigMap:
configMapGenerator:
- name: minecraft-script
options:
disableNameSuffixHash: true
files:
- idle.sh
Customizing Service Quality in GameServerSet
Focus on the highlighted sections:
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
gameServerTemplate:
volumeClaimTemplates:
- metadata:
name: minecraft
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: minecraft
resources:
requests:
storage: 20Gi
spec:
volumes: # Reference ConfigMap for idle.sh script file
- name: script
configMap:
name: minecraft-script
defaultMode: 0755
containers:
- image: itzg/minecraft-server:latest
name: minecraft
volumeMounts:
- name: script # Mount idle.sh script file
mountPath: /idle.sh
subPath: idle.sh
- name: minecraft
mountPath: /data
env:
- name: EULA
value: "TRUE"
- name: ONLINE_MODE
value: "FALSE"
serviceQualities:
- name: idle
containerName: minecraft
permanent: false
exec:
command: ["bash", "/idle.sh"] # Use idle.sh detection to determine opsState
serviceQualityAction:
- state: true
opsState: WaitToBeDeleted # When idle.sh returns 0, set opsState to WaitToBeDeleted. During rolling updates, delete Pod only when this state is detected, achieving "upgrade game server when idle"
- state: false
opsState: None
Testing and Observing opsState
After connecting to the game server with the client, execute the following command to view the opsState of each game server:
$ kubectl get gameserver
NAME STATE OPSSTATE DP UP AGE
minecraft-0 Ready WaitToBeDeleted 0 0 68m
minecraft-1 Ready None 0 0 69m
minecraft-2 Ready WaitToBeDeleted 0 0 70m
Among them,
Noneindicates that players are playing on that server, andWaitToBeDeletedindicates that the server has no players and can be scaled down.