apiVersion: v1 kind: ServiceAccount metadata: name: mc-router namespace: minecraft --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: services-watcher namespace: minecraft rules: - apiGroups: [""] resources: ["services"] verbs: ["watch", "list"] - apiGroups: ["apps"] resources: ["statefulsets", "statefulsets/scale"] verbs: ["watch", "list", "get", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: mc-router-services-watcher namespace: minecraft subjects: - kind: ServiceAccount name: mc-router namespace: minecraft roleRef: kind: ClusterRole name: services-watcher apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: Service metadata: name: mc-router namespace: minecraft spec: type: NodePort selector: run: mc-router ports: - targetPort: web name: web port: 8080 nodePort: 30001 - targetPort: proxy name: proxy port: 25565 nodePort: 25565 --- apiVersion: apps/v1 kind: Deployment metadata: name: mc-router namespace: minecraft labels: run: mc-router spec: selector: matchLabels: run: mc-router strategy: type: Recreate template: metadata: namespace: minecraft labels: run: mc-router spec: serviceAccountName: mc-router containers: - image: itzg/mc-router imagePullPolicy: Always name: mc-router args: [ "--api-binding", ":8080", "--in-kube-cluster", "--auto-scale-up", "--debug", ] env: - name: AUTO_SCALE_UP value: "true" ports: - name: proxy containerPort: 25565 - name: web containerPort: 8080 resources: requests: memory: 50Mi cpu: "100m" limits: memory: 100Mi cpu: "250m" # Cron job for stopping empty servers --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: mc-shutdown namespace: minecraft rules: - apiGroups: ["apps"] resources: ["statefulsets", "statefulsets/scale"] verbs: ["list", "get", "update", "patch"] - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: mc-shutdown namespace: minecraft subjects: - kind: ServiceAccount name: mc-shutdown namespace: default roleRef: kind: ClusterRole name: mc-shutdown apiGroup: "rbac.authorization.k8s.io" --- apiVersion: v1 kind: ServiceAccount metadata: name: mc-shutdown namespace: minecraft --- apiVersion: batch/v1 kind: CronJob metadata: name: mc-shutdown namespace: minecraft spec: schedule: "*/5 * * * *" concurrencyPolicy: Forbid jobTemplate: spec: template: spec: serviceAccountName: mc-shutdown restartPolicy: OnFailure containers: - name: shutdown image: bitnami/kubectl:latest imagePullPolicy: IfNotPresent command: - /bin/bash - -c - source shutdown-script.sh volumeMounts: - name: shutdown-script mountPath: /shutdown-script.sh subPath: shutdown-script.sh readOnly: true volumes: - name: shutdown-script configMap: name: shutdown-script items: - key: shutdown-script.sh path: shutdown-script.sh # uses container label containertype=minecraft-server to find running servers # TODO: get ownerReferences link to StatefulSet/name from pod metadate instead of sed string manipulation --- apiVersion: v1 kind: ConfigMap metadata: name: shutdown-script namespace: minecraft data: shutdown-script.sh: | #!/bin/bash MC_PODS=$(kubectl get pods -l containertype=minecraft-server -o=jsonpath="{range .items[*]}{.metadata.name},"| sed 's/,/\n/g') for p in $MC_PODS; do echo "found minecraft pod $p, sleeping 120 seconds to prevent shutdown before login" sleep 120 deployment=$(echo $p |sed 's/-0//g') # check online player count in the mc server if [[ $(kubectl exec -i $p -- /usr/local/bin/mc-monitor status) == *"online=0"* ]] ;then kubectl scale statefulset $deployment --replicas=0 fi done