feat(operator): 游戏容器加 startup/liveness 探针,超时启动按 1/2/4 分钟退避重建 Pod 至多 3 次,Running 每 60s 重探且连续 3 次失败才降级,Failed 放缓重排
This commit is contained in:
10 files changed
+440
-35
No files matched your search
@@ -153,8 +153,10 @@ func APIBuildRole(p Params) *rbacv1.Role {
|
||||
// call fails closed with a 403), and reads RCON Secrets. Jobs are list-only,
|
||||
// through the manager's uncached API reader: before scaling a server up from zero
|
||||
// the operator checks that no restore/backup/file-write Job holds its world
|
||||
// (internal/maintenance). It never touches pods, PVCs, Events, or finalizers, so
|
||||
// none appear here.
|
||||
// (internal/maintenance). Pods are delete-only: a start that timed out is retried
|
||||
// by deleting its pod for the StatefulSet to recreate (bounded, three attempts;
|
||||
// internal/operator.recoverFailedStart). It never touches PVCs, Events, or
|
||||
// finalizers, so none appear here.
|
||||
func OperatorRole(p Params) *rbacv1.Role {
|
||||
p = p.withDefaults()
|
||||
return role(p.MinecraftNamespace, "felis-operator", ComponentOperator, []rbacv1.PolicyRule{
|
||||
@@ -172,6 +174,9 @@ func OperatorRole(p Params) *rbacv1.Role {
|
||||
// list only: an uncached List (no informer, so no watch) of the world-volume
|
||||
// maintenance Jobs; the operator never creates or deletes a Job.
|
||||
rule([]string{groupBatch}, []string{"jobs"}, []string{"list"}),
|
||||
// delete only, through the direct client: no read of pods is needed to
|
||||
// remove the one named <server>-0.
|
||||
rule([]string{groupCore}, []string{"pods"}, []string{"delete"}),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -189,11 +189,20 @@ func TestOperatorRole_ScopeExact(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Hard exclusions.
|
||||
for _, res := range []string{"persistentvolumeclaims", "pods", "events"} {
|
||||
for _, res := range []string{"persistentvolumeclaims", "events"} {
|
||||
if grantsResource(op, groupCore, res) {
|
||||
t.Errorf("operator must NOT touch core/%s", res)
|
||||
}
|
||||
}
|
||||
// Pods are delete-only: the bounded retry of a timed-out start.
|
||||
if !hasRule(op, groupCore, "pods", "delete") {
|
||||
t.Error("operator must have pods:delete (auto-restart of a timed-out start)")
|
||||
}
|
||||
for _, v := range []string{"get", "list", "watch", "create", "update", "patch", "deletecollection", "*"} {
|
||||
if hasRule(op, groupCore, "pods", v) {
|
||||
t.Errorf("operator pods rule must be delete-only, found %s", v)
|
||||
}
|
||||
}
|
||||
// The world-volume lock check lists Jobs uncached; it never writes one.
|
||||
if !hasRule(op, groupBatch, "jobs", "list") {
|
||||
t.Error("operator must have jobs:list (maintenance hold before scale-up)")
|
||||
|
||||
Reference in new issue
Block a user