fix(deploy): ship runnable control-plane and matcher workloads

The Kubernetes base deployed a control-plane image the Dockerfile never
built -- cmd/control-plane was absent from the Go build stage and no
target existed -- while the Dockerfile built a matcher image no manifest
ever deployed. Applying the checked-in base therefore could not produce
the advertised topology: one required workload had no repository-defined
artifact, and nothing consumed queued tickets. Tickets could be created
but never became proposals.

Add the production control-plane build and image target, explicitly not
the testkit-api target, which injects a fake login accepting any ticket.
Add casual and ranked matcher Deployments as separate workloads: they
have different match sizes, and separating them keeps a ranked backlog
from delaying casual formation. One replica each -- CreateProposal's
SKIP LOCKED fences make more replicas safe, but they would halve the
candidate pool each worker sees per poll and worsen formation for no
throughput gain at this scale. Their PDB uses maxUnavailable, since
minAvailable against a single replica blocks node drains outright.

Also fix both blocked traffic directions. No ingress policy admitted
UDP/7777 to game-server pods, so an allocated server was unreachable
from the internet under the namespace-wide default deny. And
control-plane ingress admitted only edge-gateway pods, so roster fetch,
registration, connection receipts, shutdown and result submission from
game servers were dropped even inside the cluster, despite their egress
being permitted. The default deny stays.

Manifest tests now assert every required role is deployed, both
playlists are scheduled, every referenced image maps to a real
Dockerfile target, and both traffic directions are permitted. Each was
verified to fail against the defect it covers. The control-plane image
was built and run to confirm the target works.
This commit is contained in:
Josh Creek
2026-09-05 10:52:52 +01:00
parent 801fca7cb0
commit d40344a2c0
7 changed files with 340 additions and 0 deletions
+17
View File
@@ -57,6 +57,7 @@ COPY server/go.mod server/go.sum ./
RUN go mod download
COPY server/ ./
RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/game-server-supervisor ./cmd/game-server-supervisor
RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/control-plane ./cmd/control-plane
RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/testkit-api ./cmd/testkit-api
RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/matcher ./cmd/matcher
RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/allocator ./cmd/allocator
@@ -76,6 +77,22 @@ COPY --from=supervisor-build /opt/cosmic-clash/game-server-supervisor /opt/cosmi
RUN chmod 0755 /opt/cosmic-clash/game-server-supervisor
ENTRYPOINT ["/opt/cosmic-clash/game-server-supervisor"]
# The production control-plane API. deploy/k8s/base/control-plane-deployment.yaml
# has always referenced this image, but nothing built it: cmd/control-plane was
# absent from the Go build stage and no target existed, so the checked-in
# Kubernetes base could not produce its own advertised topology.
#
# This must never be substituted with the testkit-api target below, which
# injects a fake login provider that accepts any ticket string.
FROM server AS control-plane
COPY --from=supervisor-build /opt/cosmic-clash/control-plane /opt/cosmic-clash/control-plane
COPY server/migrations /opt/cosmic-clash/migrations
RUN chmod 0755 /opt/cosmic-clash/control-plane
EXPOSE 8080
ENTRYPOINT ["/opt/cosmic-clash/control-plane"]
# TEST ONLY. Supplies a fake Steam login that accepts any ticket; never deploy
# this in place of the control-plane target above.
FROM server AS testkit-api
COPY --from=supervisor-build /opt/cosmic-clash/testkit-api /opt/cosmic-clash/testkit-api
COPY server/migrations /opt/cosmic-clash/migrations