feat(distributed): 支持单主控多节点部署和停服迁移
复用现有 k3s 调度和 Job 生命周期,增加 worker 接入与批准、受保护节点身份、归档传输、持久迁移锁及活动 PVC 切换;同步管理员 API、CLI、面板和隔离规则。分布式模式默认关闭,保持单机兼容。 验证:Go 全量测试与 vet;面板 874 个测试、lint/build;Linux VM 安装器测试、清单服务端 dry-run、网络命名空间防火墙实测。A/B/C 三机 WireGuard、Velocity 和迁移验收仍待完成。
This commit is contained in:
77 files changed
+5224
-73
No files matched your search
@@ -52,6 +52,7 @@ import (
|
||||
"time"
|
||||
|
||||
"felis.lolicon.best/internal/naming"
|
||||
"felis.lolicon.best/internal/placement"
|
||||
)
|
||||
|
||||
// Errors the Editor returns, which internal/api maps onto HTTP status codes
|
||||
@@ -106,6 +107,7 @@ type Runner interface {
|
||||
// deployment-specific, and when it is empty cmd/felis leaves the API's FileEditor
|
||||
// nil so the endpoints report 503 rather than creating a Job that cannot run.
|
||||
type Config struct {
|
||||
ResolveWorld placement.Resolver
|
||||
// Namespace is where the world PVCs live and the Job runs (the minecraft
|
||||
// namespace), co-located with the world it edits.
|
||||
Namespace string
|
||||
@@ -338,6 +340,14 @@ func (e *Editor) run(ctx context.Context, server string, p JobParams) (Result, e
|
||||
return Result{}, err
|
||||
}
|
||||
|
||||
if cfg.ResolveWorld != nil {
|
||||
world, err := cfg.ResolveWorld(ctx, server)
|
||||
if err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
p.WorldPVC, p.NodeName = world.Claim, world.Node
|
||||
}
|
||||
|
||||
// Bound the wait here rather than trusting the caller's context: this is an HTTP
|
||||
// handler's goroutine and the Pod it waits on may never become ready (an
|
||||
// unschedulable node, an unpullable image). The Job's own activeDeadlineSeconds
|
||||
@@ -438,6 +448,13 @@ func (e *Editor) start(ctx context.Context, server string, p JobParams) (OpState
|
||||
if err != nil {
|
||||
return OpState{}, err
|
||||
}
|
||||
if cfg.ResolveWorld != nil {
|
||||
world, err := cfg.ResolveWorld(ctx, server)
|
||||
if err != nil {
|
||||
return OpState{}, err
|
||||
}
|
||||
p.WorldPVC, p.NodeName = world.Claim, world.Node
|
||||
}
|
||||
p.Async = true
|
||||
p.Deadline, p.TTLAfterFinished, p.CPULimit = cfg.AsyncDeadline, cfg.AsyncTTL, cfg.AsyncCPULimit
|
||||
if err := e.Runner.Start(ctx, p); err != nil {
|
||||
|
||||
Reference in new issue
Block a user