Unverified Commit b384f628 authored by Lemon-miaow's avatar Lemon-miaow
Browse files

feat(crd): 数值字段加上下限校验,rcon.port 用 CEL 限定默认端口,文档写明 v1beta1 演进与多节点前提

parent 925cfcf8
Loading
Loading
Loading
Loading
+16 −0
Changes for deploy/crd/felis.lolicon.best_minecraftservers.yaml: 16 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ spec:
                      EmptySecondsBeforeStop is how long the server may sit empty before the
                      operator scales it down.
                    format: int32
                    maximum: 604800
                    minimum: 0
                    type: integer
                type: object
              image:
@@ -127,6 +129,8 @@ spec:
                    description: TerminationGracePeriodSeconds is the pod grace period
                      (default 300).
                    format: int64
                    maximum: 3600
                    minimum: 0
                    type: integer
                type: object
              motd:
@@ -159,6 +163,8 @@ spec:
                  port:
                    description: Port is the RCON TCP port (default 25575).
                    format: int32
                    maximum: 65535
                    minimum: 0
                    type: integer
                  secretRef:
                    description: SecretRef points at the Secret holding the RCON password.
@@ -172,6 +178,10 @@ spec:
                    - name
                    type: object
                type: object
                x-kubernetes-validations:
                - message: the allow-rcon NetworkPolicy admits only port 25575; leave
                    port unset
                  rule: '!has(self.port) || self.port == 0 || self.port == 25575'
              reaperExempt:
                description: ReaperExempt opts this server out of the world reaper
                  entirely (spec §18).
@@ -250,16 +260,22 @@ spec:
                      (notably LOOHP/Limbo) where the felis-limbo plugin reports true
                      readiness only after the first server tick.
                    format: int32
                    maximum: 65535
                    minimum: 0
                    type: integer
                  readinessTimeoutSeconds:
                    description: ReadinessTimeoutSeconds is the budget for the first
                      successful RCON probe.
                    format: int32
                    maximum: 86400
                    minimum: 0
                    type: integer
                  timeoutSeconds:
                    description: TimeoutSeconds is the overall budget before the server
                      is marked Failed.
                    format: int32
                    maximum: 86400
                    minimum: 0
                    type: integer
                type: object
              storage:
+34 −1
Changes for docs/operations.md: 34 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -44,7 +44,9 @@ node's local-path storage, so a game server's pod is pinned to the node that fir
scheduled it and cannot move when that node fails; the operator and felis-api each run
as a single replica without leader election, so an upgrade or a node restart pauses
wakes and stops until their pod is back. Joining k3s agents to the cluster is untested
and gains no failover.
and gains no failover. A multi-node shape would need, at least, storage that can follow a
pod to another node and leader election in felis-operator (controller-runtime's
`LeaderElection`) so a second replica can stand by.

## 2. Sizing

@@ -261,6 +263,37 @@ sudo systemctl start postgresql
sudo k3s kubectl -n felis scale deploy/felis-api deploy/felis-operator --replicas=1
```

### The MinecraftServer CRD [VM-VERIFIED]

Every rerun applies the CRD embedded in the `felis` binary (`felis bootstrap-assets crd`).
It serves and stores the single version `v1alpha1`, and the apiserver refuses values the
operator cannot act on:

| Field | Accepted |
|---|---|
| `spec.rcon.port` | unset, `0` or `25575`: the allow-rcon NetworkPolicy opens only 25575, so any other port leaves the server unprobeable |
| `spec.startup.timeoutSeconds`, `readinessTimeoutSeconds` | 0 – 86400 |
| `spec.startup.healthHTTPPort` | 0 – 65535 |
| `spec.lifecycle.terminationGracePeriodSeconds` | 0 – 3600 |
| `spec.idle.emptySecondsBeforeStop` | 0 – 604800 (the panel caps it at 86400) |

`0` means the operator's default throughout. An object stored before these rules keeps an
out-of-range value until someone edits that field (CRD validation ratcheting). The operator
reads a negative value as its default and an oversized one as written, so fix such a
value by hand: `kubectl -n minecraft edit minecraftserver <name>`.

**Moving to `v1beta1` (planned, not built).** The first breaking change to the spec ships as a new
version, in this order, each step one release:

1. The CRD serves `v1alpha1` and `v1beta1`, storage stays `v1alpha1`. While the two
   schemas carry the same fields, `conversion.strategy: None` suffices; a renamed or
   reshaped field needs a conversion webhook, which felis-operator would serve.
2. Storage moves to `v1beta1`. The installer rewrites every object so etcd holds the new
   version (`kubectl get minecraftservers -A -o json | kubectl replace -f -`), then sets
   `status.storedVersions` of the CRD to `["v1beta1"]`.
3. A later release stops serving `v1alpha1`. Felis itself reads through one Go type at a
   time, so the operator and felis-api switch in the release that moves storage.

## 5. Disaster recovery

The procedures are in §16: what a database bundle holds, restoring one on the same host,
+3 −2
Changes for docs/troubleshooting.md: 3 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -140,8 +140,9 @@ message is the verbatim dial error:
  backend's `rcon.password`. Reconcile the two. [GO-TESTED that this maps to
  `RconNotReachable`.]
- `connection refused` / `i/o timeout` → the backend has not opened the RCON
  port yet, RCON is disabled in `server.properties`, or `spec.rcon.port`
  (default 25575) is wrong. [INTEGRATION-ONLY for the live handshake.]
  port yet, RCON is disabled in `server.properties`, or the image listens on a
  port other than 25575 (the CRD accepts only that one for `spec.rcon.port`,
  operations.md §4). [INTEGRATION-ONLY for the live handshake.]

The per-probe timeout is a fixed 5s in code (`prober.go:45`, shortened further if
the reconcile context has a nearer deadline). It is **not** derived from
+2 −1
Changes for go.mod: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -19,11 +19,13 @@ require (
	k8s.io/api v0.31.3
	k8s.io/apimachinery v0.31.3
	k8s.io/client-go v0.31.0
	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340
	sigs.k8s.io/controller-runtime v0.19.3
	sigs.k8s.io/yaml v1.4.0
)

require (
	github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
	github.com/atotto/clipboard v0.1.4 // indirect
	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
	github.com/beorn7/perks v1.0.1 // indirect
@@ -108,7 +110,6 @@ require (
	gopkg.in/yaml.v3 v3.0.1 // indirect
	k8s.io/apiextensions-apiserver v0.31.0 // indirect
	k8s.io/klog/v2 v2.130.1 // indirect
	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
	k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+2 −0
Loading