diff --git a/charts/grounds-geyser/templates/configmap.yaml b/charts/grounds-geyser/templates/configmap.yaml index 8d35856..5542902 100644 --- a/charts/grounds-geyser/templates/configmap.yaml +++ b/charts/grounds-geyser/templates/configmap.yaml @@ -20,9 +20,9 @@ metadata: data: config.yml: | bedrock: - # 0.0.0.0, not the pod IP: with a hostPort the kubelet forwards from the - # node's address into the pod, so binding anything narrower means the - # forwarded packets arrive at a socket nothing is listening on. + # 0.0.0.0, not the pod IP: packets arrive translated by the Service that + # fronts this port, so binding anything narrower means they land on a + # socket nothing is listening on. address: 0.0.0.0 port: {{ .Values.bedrock.port }} # The port advertised to the client in the pong is this one, not the diff --git a/charts/grounds-geyser/templates/daemonset.yaml b/charts/grounds-geyser/templates/daemonset.yaml index 239b020..cddf3c3 100644 --- a/charts/grounds-geyser/templates/daemonset.yaml +++ b/charts/grounds-geyser/templates/daemonset.yaml @@ -29,10 +29,9 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{/* The hostPort is exclusive, so the old pod on a node has to be gone before - its replacement can bind. RollingUpdate on a DaemonSet already deletes - before it creates, one node at a time — a Bedrock player on that node - reconnects, players on the others never notice. */}} + {{/* One node at a time: a Bedrock player on that node reconnects, players on + the others never notice. RakNet sessions are per-process, so a pod + replacement always drops the sessions it was holding. */}} updateStrategy: type: RollingUpdate rollingUpdate: @@ -73,12 +72,20 @@ spec: - name: geyser image: "{{ $imageRepo }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + {{/* No hostPort. It is what a Bedrock client needs — 19132 is outside + the NodePort range, so a Service cannot serve it the ordinary way + — but binding it here costs the whole namespace its PodSecurity + level: baseline forbids hostPort, so allowing one means enforcing + `privileged` for everything alongside. + + The region's Pulumi stack owns a Service with `externalIPs` set to + the node addresses instead. Cilium runs with kube-proxy + replacement and programs those, so UDP 19132 on any node address + reaches these pods without the pod claiming a port on the host — + and the namespace stays at baseline. */}} ports: - name: bedrock containerPort: {{ .Values.bedrock.port }} - {{- if .Values.bedrock.hostPort }} - hostPort: {{ .Values.bedrock.port }} - {{- end }} protocol: UDP {{- with .Values.resources }} resources: diff --git a/charts/grounds-geyser/values.yaml b/charts/grounds-geyser/values.yaml index 0fb4c3a..42f7f4c 100644 --- a/charts/grounds-geyser/values.yaml +++ b/charts/grounds-geyser/values.yaml @@ -42,17 +42,20 @@ image: # belongs on the environment whose users are the team, not the one whose users # are players. bedrock: - port: 19132 - # Bound on the node, not behind a Service: a Bedrock client speaks RakNet - # over UDP and the address it dials is the only routing key that exists - # before the session is up — there is no handshake hostname for anything to - # route on, the way mc-router does for Java. So the player has to reach the - # node directly. + # A Bedrock client speaks RakNet over UDP, and the address it dials is the + # only routing key that exists before the session is up — there is no + # handshake hostname for anything to route on, the way mc-router does for + # Java. So the player has to reach a node address directly, on this port. + # + # Reaching it is NOT this chart's job. 19132 sits outside the NodePort range, + # so an ordinary Service cannot serve it, and a hostPort would cost the whole + # namespace its PodSecurity level — baseline forbids hostPort, so one pod + # binding it means enforcing `privileged` for everything alongside. # - # `hostPort` and not `hostNetwork`: the pod keeps its own network namespace, - # so nothing else on the node is exposed, and the remote address below can - # still be a cluster DNS name. - hostPort: true + # The region's Pulumi stack owns a Service with `externalIPs` set to the node + # addresses. Cilium programs those, so this port reaches the pods without any + # of them claiming a port on the host. + port: 19132 # What the Bedrock server list shows before the player connects. Geyser # answers these locally — the ping never reaches Velocity. motd1: "Grounds"