manage Minecraft workloads as GitOps manifests

This commit is contained in:
2026-10-21 14:14:59 +02:00
parent e13c3f2ae5
commit 41c2cb3d4d
13 changed files with 457 additions and 21 deletions
+28
View File
@@ -0,0 +1,28 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: atm10-dashboard
labels:
grafana_dashboard: '1'
data:
dashboard.json: |
{
"uid": "minecraft-atm10",
"title": "Minecraft — ATM10",
"tags": ["minecraft", "atm10"],
"schemaVersion": 39,
"version": 1,
"refresh": "30s",
"time": {"from": "now-3h", "to": "now"},
"panels": [
{"id": 1, "type": "stat", "title": "Server status", "gridPos": {"x": 0, "y": 0, "w": 4, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max(minecraft_status_healthy{namespace=\"atm10\"})", "instant": true}]},
{"id": 2, "type": "gauge", "title": "Players online", "gridPos": {"x": 4, "y": 0, "w": 5, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max(minecraft_status_players_online_count{namespace=\"atm10\"})", "instant": true}], "fieldConfig": {"defaults": {"min": 0, "max": 20, "unit": "short"}}},
{"id": 3, "type": "stat", "title": "Node", "gridPos": {"x": 9, "y": 0, "w": 7, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max by (node) (kube_pod_info{namespace=\"atm10\",pod=~\"atm10-.*\"})", "instant": true, "legendFormat": "{{node}}"}]},
{"id": 4, "type": "timeseries", "title": "CPU cores", "gridPos": {"x": 0, "y": 4, "w": 12, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum(rate(container_cpu_usage_seconds_total{namespace=\"atm10\",pod=~\"atm10-.*\",container=\"atm10\"}[5m]))", "legendFormat": "CPU cores"}], "fieldConfig": {"defaults": {"unit": "cores", "min": 0}}},
{"id": 5, "type": "timeseries", "title": "Memory", "gridPos": {"x": 12, "y": 4, "w": 12, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum(container_memory_working_set_bytes{namespace=\"atm10\",pod=~\"atm10-.*\",container=\"atm10\"})", "legendFormat": "Working set"}], "fieldConfig": {"defaults": {"unit": "bytes", "min": 0}}},
{"id": 6, "type": "timeseries", "title": "Network", "gridPos": {"x": 0, "y": 12, "w": 24, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum by (pod) (rate(container_network_receive_bytes_total{namespace=\"atm10\",pod=~\"atm10-.*\"}[5m]))", "legendFormat": "{{pod}} receive"}, {"refId": "B", "expr": "sum by (pod) (rate(container_network_transmit_bytes_total{namespace=\"atm10\",pod=~\"atm10-.*\"}[5m]))", "legendFormat": "{{pod}} transmit"}], "fieldConfig": {"defaults": {"unit": "Bps", "min": 0}}}
],
"templating": {"list": [{"name": "DS_PROMETHEUS", "type": "datasource", "query": "prometheus", "label": "Prometheus", "current": {"text": "Prometheus", "value": "${DS_PROMETHEUS}"}, "hide": 0}]},
"annotations": {"list": []},
"links": []
}
+83
View File
@@ -0,0 +1,83 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: atm10
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
template:
metadata:
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 600
nodeSelector:
kubernetes.io/hostname: arschrock
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- name: atm10
image: docker.io/library/eclipse-temurin:21.0.12_8-jre-noble
imagePullPolicy: IfNotPresent
workingDir: /data
command: [java]
args:
- '@user_jvm_args.txt'
- '@libraries/net/neoforged/neoforge/21.1.224/unix_args.txt'
- nogui
ports:
- name: minecraft
containerPort: 25566
protocol: TCP
startupProbe:
tcpSocket:
port: minecraft
periodSeconds: 10
failureThreshold: 120
readinessProbe:
tcpSocket:
port: minecraft
periodSeconds: 10
failureThreshold: 3
volumeMounts:
- name: server-data
mountPath: /data
- name: mc-monitor
image: docker.io/itzg/mc-monitor:1.18.3
imagePullPolicy: IfNotPresent
args:
- export-for-prometheus
- -servers
- 127.0.0.1:25566
- -port
- '8080'
- -timeout
- 10s
ports:
- name: metrics
containerPort: 8080
readinessProbe:
httpGet:
path: /metrics
port: metrics
periodSeconds: 10
volumes:
- name: server-data
hostPath:
path: /home/feedc0de/ATM10
type: Directory
+7
View File
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- services.yaml
- monitoring.yaml
- dashboard.yaml
+17
View File
@@ -0,0 +1,17 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: atm10
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
spec:
selector:
matchLabels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
app.kubernetes.io/component: metrics
endpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
+62
View File
@@ -0,0 +1,62 @@
apiVersion: v1
kind: Service
metadata:
name: atm10
annotations:
metallb.io/address-pool: default
mikrotik.brunner.ninja/router: newgw
mikrotik.brunner.ninja/forwardings: '[{"name":"tcp","servicePort":"minecraft","dstAddressList":"WANs"}]'
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
ports:
- name: minecraft
port: 25566
targetPort: minecraft
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: atm10-arschrock
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
spec:
type: ClusterIP
externalIPs:
- 10.12.4.170
- 192.168.0.2
selector:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
ports:
- name: minecraft
port: 25566
targetPort: minecraft
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: atm10-metrics
labels:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
app.kubernetes.io/component: metrics
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: minecraft-atm10
app.kubernetes.io/instance: atm10
ports:
- name: metrics
port: 8080
targetPort: metrics
protocol: TCP
+28
View File
@@ -0,0 +1,28 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: paper-dashboard
labels:
grafana_dashboard: '1'
data:
dashboard.json: |
{
"uid": "minecraft-paper",
"title": "Minecraft — Paper",
"tags": ["minecraft", "paper"],
"schemaVersion": 39,
"version": 1,
"refresh": "30s",
"time": {"from": "now-3h", "to": "now"},
"panels": [
{"id": 1, "type": "stat", "title": "Server status", "gridPos": {"x": 0, "y": 0, "w": 4, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max(minecraft_status_healthy{namespace=\"mcserver\"})", "instant": true}]},
{"id": 2, "type": "gauge", "title": "Players online", "gridPos": {"x": 4, "y": 0, "w": 5, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max(minecraft_status_players_online_count{namespace=\"mcserver\"})", "instant": true}], "fieldConfig": {"defaults": {"min": 0, "max": 20, "unit": "short"}}},
{"id": 3, "type": "stat", "title": "Node", "gridPos": {"x": 9, "y": 0, "w": 7, "h": 4}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "max by (node) (kube_pod_info{namespace=\"mcserver\",pod=~\"paper-.*\"})", "instant": true, "legendFormat": "{{node}}"}]},
{"id": 4, "type": "timeseries", "title": "CPU cores", "gridPos": {"x": 0, "y": 4, "w": 12, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum(rate(container_cpu_usage_seconds_total{namespace=\"mcserver\",pod=~\"paper-.*\",container=\"paper\"}[5m]))", "legendFormat": "CPU cores"}], "fieldConfig": {"defaults": {"unit": "cores", "min": 0}}},
{"id": 5, "type": "timeseries", "title": "Memory", "gridPos": {"x": 12, "y": 4, "w": 12, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum(container_memory_working_set_bytes{namespace=\"mcserver\",pod=~\"paper-.*\",container=\"paper\"})", "legendFormat": "Working set"}], "fieldConfig": {"defaults": {"unit": "bytes", "min": 0}}},
{"id": 6, "type": "timeseries", "title": "Network", "gridPos": {"x": 0, "y": 12, "w": 24, "h": 8}, "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"}, "targets": [{"refId": "A", "expr": "sum by (pod) (rate(container_network_receive_bytes_total{namespace=\"mcserver\",pod=~\"paper-.*\"}[5m]))", "legendFormat": "{{pod}} receive"}, {"refId": "B", "expr": "sum by (pod) (rate(container_network_transmit_bytes_total{namespace=\"mcserver\",pod=~\"paper-.*\"}[5m]))", "legendFormat": "{{pod}} transmit"}], "fieldConfig": {"defaults": {"unit": "Bps", "min": 0}}}
],
"templating": {"list": [{"name": "DS_PROMETHEUS", "type": "datasource", "query": "prometheus", "label": "Prometheus", "current": {"text": "Prometheus", "value": "${DS_PROMETHEUS}"}, "hide": 0}]},
"annotations": {"list": []},
"links": []
}
+88
View File
@@ -0,0 +1,88 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: paper
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
template:
metadata:
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 600
nodeSelector:
kubernetes.io/hostname: arschrock
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- name: paper
image: docker.io/library/eclipse-temurin:26.0.2_10-jre-noble
imagePullPolicy: IfNotPresent
workingDir: /data
command: [java]
args:
- -Ddisable.watchdog=true
- -Xms2G
- -Xmx8G
- -jar
- paper-26.3-166.jar
ports:
- name: minecraft
containerPort: 25565
protocol: TCP
- name: dynmap
containerPort: 8124
protocol: TCP
startupProbe:
tcpSocket:
port: minecraft
periodSeconds: 10
failureThreshold: 60
readinessProbe:
tcpSocket:
port: minecraft
periodSeconds: 10
failureThreshold: 3
volumeMounts:
- name: server-data
mountPath: /data
- name: mc-monitor
image: docker.io/itzg/mc-monitor:1.18.3
imagePullPolicy: IfNotPresent
args:
- export-for-prometheus
- -servers
- 127.0.0.1:25565
- -port
- '8080'
- -timeout
- 10s
ports:
- name: metrics
containerPort: 8080
readinessProbe:
httpGet:
path: /metrics
port: metrics
periodSeconds: 10
volumes:
- name: server-data
hostPath:
path: /home/feedc0de/mcserver
type: Directory
+25
View File
@@ -0,0 +1,25 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: paper-mcmap-strip
spec:
stripPrefix:
prefixes:
- /mcmap
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: mcmap
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`brunner.ninja`) && PathPrefix(`/mcmap`)
middlewares:
- name: paper-mcmap-strip
services:
- kind: Service
name: paper-dynmap
port: http
+8
View File
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- services.yaml
- monitoring.yaml
- dynmap.yaml
- dashboard.yaml
+17
View File
@@ -0,0 +1,17 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: paper
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
spec:
selector:
matchLabels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
app.kubernetes.io/component: metrics
endpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
+81
View File
@@ -0,0 +1,81 @@
apiVersion: v1
kind: Service
metadata:
name: paper
annotations:
metallb.io/address-pool: default
mikrotik.brunner.ninja/router: newgw
mikrotik.brunner.ninja/forwardings: '[{"name":"tcp","servicePort":"minecraft","dstAddressList":"WANs"}]'
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
ports:
- name: minecraft
port: 25565
targetPort: minecraft
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: paper-arschrock
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
spec:
type: ClusterIP
externalIPs:
- 10.12.4.170
- 192.168.0.2
selector:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
ports:
- name: minecraft
port: 25565
targetPort: minecraft
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: paper-dynmap
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
app.kubernetes.io/component: dynmap
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
ports:
- name: http
port: 8124
targetPort: dynmap
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: paper-metrics
labels:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
app.kubernetes.io/component: metrics
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: minecraft-paper
app.kubernetes.io/instance: paper
ports:
- name: metrics
port: 8080
targetPort: metrics
protocol: TCP
+5 -11
View File
@@ -5,23 +5,17 @@ metadata:
namespace: argocd
spec:
project: minecraft
sources:
- repoURL: https://brunner.ninja/charts
chart: minecraft-atm10
targetRevision: 6.6.0-1-g7042a8d
helm:
releaseName: atm10
valueFiles: [$values/apps/minecraft-atm10/values.yaml]
- repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
ref: values
source:
repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
path: apps/minecraft-atm10
destination:
server: https://kubernetes.default.svc
namespace: atm10
syncPolicy:
automated:
enabled: true
prune: false
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+8 -10
View File
@@ -5,19 +5,17 @@ metadata:
namespace: argocd
spec:
project: minecraft
sources:
- repoURL: https://brunner.ninja/charts
chart: minecraft-paper
targetRevision: 26.3.166-1-g2acc76d
helm:
releaseName: paper
valueFiles: [$values/apps/minecraft-paper/values.yaml]
- repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
ref: values
source:
repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
path: apps/minecraft-paper
destination:
server: https://kubernetes.default.svc
namespace: mcserver
syncPolicy:
automated:
enabled: true
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true