From dfc55e1d9e41d627854b4b0b2285b2ecbc7dd355 Mon Sep 17 00:00:00 2001 From: panxiao81 Date: Mon, 21 Sep 2026 06:39:11 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E5=90=AF=E7=94=A8=20Runner=20=E6=97=A0?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E6=BB=9A=E5=8A=A8=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/dynamic-runner/README.md | 7 +++++-- platform/dynamic-runner/deployment.yaml | 6 +++--- platform/dynamic-runner/rbac.yaml | 3 +++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/platform/dynamic-runner/README.md b/platform/dynamic-runner/README.md index 1b241bf..f914a87 100644 --- a/platform/dynamic-runner/README.md +++ b/platform/dynamic-runner/README.md @@ -21,10 +21,13 @@ OpenSandbox chart 所有权边界。 ## Canary 安全边界 -- Deployment 为单副本,滚动策略固定 `maxSurge: 0`、`maxUnavailable: 1`,避免两个 - scheduler 共享同一个 Gitea runner 身份。 +- Deployment 为单副本,滚动策略固定 `maxSurge: 1`、`maxUnavailable: 0`,保证新 + facade Ready 后才终止旧实例。scheduler 必须通过 Kubernetes Lease 保持单 leader, + 不能依赖 Recreate 避免重复领取。 - controller 的 single-flight gate 只允许一个已领取 task 运行;Gitea 接受终态 `UpdateTask` 后才领取下一条。`POD_CAPACITY=1` 同时限制 worker 创建并发。 +- rollout 重叠期间只有持有 `Lease/dynamic-runner-scheduler` 的 controller 执行 + `FetchTask`;所有 Ready 实例都可通过 backend metadata 恢复 claim 并服务 facade。 - executor 镜像使用 digest;Pod 以 UID 2000 运行,SPIRE `ClusterStaticEntry` 同时绑定 具体 Pod UID 与 `unix:uid:2000`。 - facade 只有 ClusterIP,executor 通过 diff --git a/platform/dynamic-runner/deployment.yaml b/platform/dynamic-runner/deployment.yaml index 8e346f2..deda86c 100644 --- a/platform/dynamic-runner/deployment.yaml +++ b/platform/dynamic-runner/deployment.yaml @@ -8,8 +8,8 @@ spec: strategy: type: RollingUpdate rollingUpdate: - maxSurge: 0 - maxUnavailable: 1 + maxSurge: 1 + maxUnavailable: 0 selector: matchLabels: app.kubernetes.io/name: dynamic-runner-controller @@ -38,7 +38,7 @@ spec: mountPath: /trust containers: - name: controller - image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:efbe44fdb13cf24f83f92d703c7051d3106cfc7d3bed9ee5debddd1d27db9dec + image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:c165a0ec950fb5972acb9f4010c0a9cb1b89fb6c9f95c78b36cc0cbdf6f482b7 imagePullPolicy: IfNotPresent args: [controller] env: diff --git a/platform/dynamic-runner/rbac.yaml b/platform/dynamic-runner/rbac.yaml index 5dd3a7b..6f875e9 100644 --- a/platform/dynamic-runner/rbac.yaml +++ b/platform/dynamic-runner/rbac.yaml @@ -19,6 +19,9 @@ rules: - apiGroups: [""] resources: [pods] verbs: [create, get, list, watch, patch, delete] + - apiGroups: [coordination.k8s.io] + resources: [leases] + verbs: [create, get, list, watch, update, patch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding -- 2.54.0 From 098ff4e27fcb86445720e7a71fe9c70cb70d8d6a Mon Sep 17 00:00:00 2001 From: panxiao81 Date: Mon, 21 Sep 2026 06:51:37 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Runner=20=E5=AE=B9?= =?UTF-8?q?=E9=87=8F=E9=9A=94=E7=A6=BB=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/dynamic-runner/README.md | 16 ++++++++-------- platform/dynamic-runner/deployment.yaml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/dynamic-runner/README.md b/platform/dynamic-runner/README.md index f914a87..f3dad91 100644 --- a/platform/dynamic-runner/README.md +++ b/platform/dynamic-runner/README.md @@ -24,8 +24,8 @@ OpenSandbox chart 所有权边界。 - Deployment 为单副本,滚动策略固定 `maxSurge: 1`、`maxUnavailable: 0`,保证新 facade Ready 后才终止旧实例。scheduler 必须通过 Kubernetes Lease 保持单 leader, 不能依赖 Recreate 避免重复领取。 -- controller 的 single-flight gate 只允许一个已领取 task 运行;Gitea 接受终态 - `UpdateTask` 后才领取下一条。`POD_CAPACITY=1` 同时限制 worker 创建并发。 +- scheduler 将 assignment 持久化后继续领取;`POD_CAPACITY=1` 与 `VM_CAPACITY=1` + 分别限制两个 durable consumer,任一 backend 不占用另一方的执行槽位。 - rollout 重叠期间只有持有 `Lease/dynamic-runner-scheduler` 的 controller 执行 `FetchTask`;所有 Ready 实例都可通过 backend metadata 恢复 claim 并服务 facade。 - executor 镜像使用 digest;Pod 以 UID 2000 运行,SPIRE `ClusterStaticEntry` 同时绑定 @@ -37,9 +37,9 @@ OpenSandbox chart 所有权边界。 `spiffe://ddupan.top/ns/dynamic-runner/sa/dynamic-runner-controller`。 - NATS 保留既有最小权限分离:`ci-producer` 仅 publish,`ci-worker` 仅 pull/ACK。 -当前 facade claim registry 与 single-flight gate 是进程内状态。异常重启时应先检查 -现存 assignment Pod 和 Gitea task,再人工决定是否恢复 scheduler;不能通过扩大副本数 -规避。完成 backend-driven recovery 前保持 `replicas: 1`。 +facade claim registry 在启动时从 Pod/OpenSandbox metadata 恢复;scheduler leadership +由 Kubernetes Lease 持久化协调。Deployment 仍保持 `replicas: 1`,滚动更新期间允许 +一个额外 Pod 提供 facade 连续性。 ## Secret 边界 @@ -86,12 +86,12 @@ kubectl -n dynamic-runner logs deploy/dynamic-runner-controller -f 2. `gitea-task-` Pod 创建,取得实际 Pod UID; 3. 同名 `ClusterStaticEntry` 的 parent ID 包含该 UID,SPIFFE ID 使用 repository/job key; 4. 官方 runner v3.5.0 经 facade claim 精确 task,Gitea 实时收到日志和终态; -5. terminal gate 释放后才领取下一条任务。 +5. Pod consumer 达到 capacity 时 VM consumer 仍可独立接受任务。 Pod 与 VM 都在 Gitea 接受终态后先把 terminal marker 写入各自 backend metadata,再由 lifecycle reconciler 删除执行器。首次 VM 测试仍须观察 BatchSandbox、Pod 与 -ClusterStaticEntry 全部消失;完整自动清理通过前不得提高 `POD_CAPACITY`、`VM_CAPACITY` -或 scheduler single-flight 并发。 +ClusterStaticEntry 全部消失;完整自动清理通过前不得提高 `POD_CAPACITY` 或 +`VM_CAPACITY`。 ## 回滚 diff --git a/platform/dynamic-runner/deployment.yaml b/platform/dynamic-runner/deployment.yaml index deda86c..5328247 100644 --- a/platform/dynamic-runner/deployment.yaml +++ b/platform/dynamic-runner/deployment.yaml @@ -38,7 +38,7 @@ spec: mountPath: /trust containers: - name: controller - image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:c165a0ec950fb5972acb9f4010c0a9cb1b89fb6c9f95c78b36cc0cbdf6f482b7 + image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:261a24134e9aa2275682454be794b1ee6053cadafb0c8632dea7ee2839cf8484 imagePullPolicy: IfNotPresent args: [controller] env: -- 2.54.0