资源治理
本文档描述 TFRS Operator 的计算资源治理方案,包括 ResourceQuota 管理、组件资源默认值和自动填充机制。
治理模型概览
ResourceQuota(命名空间级)
├── TFRTenant 内部组件(12 个)── 用户配置 > Operator 默认值
└── TFRServer 容器(3 个)──── 用户配置 > Operator 默认值
核心逻辑:当命名空间存在包含 CPU/Memory 的 ResourceQuota 时,Kubernetes 要求所有容器声明资源。Operator 通过三层机制确保 Pod 不被 apiserver 拒绝:
- 组件资源自动填充:未配置资源的组件使用 Operator 默认值
- LimitRange 默认值:为第三方 Operator 注入的容器(如 MinIO sidecar)提供兜底资源
- Istio sidecar 注解:为 istio-proxy 容器声明资源
ResourceQuota 管理
启用方式
通过 TFRTenant CR 的 spec.resourceQuota 字段控制:
apiVersion: infra.tfrobot.io/v1
kind: TFRTenant
spec:
resourceQuota:
enabled: true
spec:
hard:
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "16"
limits.memory: "32Gi"
pods: "50"
- CRD 类型定义:
api/infra/v1/tfrtenant_types.go:316-329 - Deployable 实现:
internal/controller/infra/tenant/resource_quota.go
生命周期
| 操作 | 行为 |
|---|---|
enabled: true | 创建或更新 tfrs-quota-{tenantName} 对象 |
enabled: true + compute 资源 | 同时创建 tfrs-limit-{tenantName} LimitRange |
enabled: false | 自动删除 ResourceQuota 和 LimitRange |
| TFRTenant 删除 | 通过 OwnerReference 级联删除 |
| Spec 变更 | Spec 漂移检测自动纠正(resource_quota.go:155-191) |
LimitRange 自动创建
当 ResourceQuota 包含 compute 资源(CPU/Memory)时,Operator 自动创建 LimitRange 为未声明资源的容器提供默认值:
| 类型 | Default (limits) | DefaultRequest (requests) |
|---|---|---|
| Container | 50m / 64Mi | 10m / 32Mi |
定位为"最低防线":仅防止无资源声明的容器被 Quota 拒绝,不作为合理默认值。解决第三方 Operator 注入的容器(如 MinIO 的 sidecar 和 validate-arguments)没有资源声明被 ResourceQuota 拒绝的问题。
实现:internal/controller/infra/tenant/resource_quota.go
Istio Sidecar 资源注解
当组件设置了 Resources 时,Operator 自动为 Pod 添加 Istio sidecar 资源注解:
| 注解 | 值 |
|---|---|
sidecar.istio.io/proxyCPU | 10m |
sidecar.istio.io/proxyMemory | 64Mi |
sidecar.istio.io/proxyCPULimit | 100m |
sidecar.istio.io/proxyMemoryLimit | 128Mi |
实现:internal/controller/infra/tenant/resources.go 中的 MergeIstioSidecarAnnotations()
Quota 检测
Operator 通过两种方式检测命名空间是否存在计算资源 Quota:
- 查询 APIServer:检查命名空间内所有 ResourceQuota 对象(
resources.go:192-213) - 检查 TFRTenant Spec:处理首次 reconcile 时 ResourceQuota 对象尚未创建的场景(
resources.go:172-188)
检测字段:requests.cpu、requests.memory、limits.cpu、limits.memory,命中任一即触发自动填充。
调用入口:tfrtenant_controller.go:276-277
TFRTenant 组件资源
默认值一览
所有默认值定义在 internal/controller/infra/tenant/resources.go:
| 组件 | Requests (CPU/Mem) | Limits (CPU/Mem) |
|---|---|---|
| PostgreSQL | 200m / 256Mi | 1000m / 1Gi |
| MinIO | 200m / 256Mi | 1000m / 1Gi |
| RabbitMQ | 200m / 256Mi | 1000m / 1Gi |
| TimescaleDB | 250m / 1Gi | 500m / 2Gi |
| TFRSUtils Worker | 250m / 256Mi | 1000m / 2Gi |
| Prometheus | 100m / 128Mi | 500m / 512Mi |
| Redis Server | 100m / 128Mi | 500m / 512Mi |
| OtelCollector | 100m / 128Mi | 500m / 512Mi |
| Vector | 100m / 128Mi | 500m / 512Mi |
| Grafana | 100m / 128Mi | 500m / 512Mi |
| TFRSUtils Beat | 100m / 128Mi | 500m / 512Mi |
| Jaeger | 50m / 128Mi | 500m / 1Gi |
| TFRobotFront | 50m / 64Mi | 200m / 256Mi |
| Redis Insight | 50m / 64Mi | 200m / 256Mi |
全部组件 Requests 合计:约 1.85 CPU / 3Gi Memory
全部组件 Limits 合计:约 8.4 CPU / 11.5Gi Memory
资源优先级
用户在 TFRTenant spec 中显式配置 > Operator 默认值
通过 EnsureResources() 实现(resources.go:289-294):用户配置非 nil 时直接使用,否则回退到默认值。
用户配置示例
apiVersion: infra.tfrobot.io/v1
kind: TFRTenant
spec:
postgresql:
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
redis:
resources:
requests:
cpu: "200m"
memory: "256Mi"
支持资源配置的组件字段见各组件 Options 定义:internal/controller/infra/tenant/options.go:131-207
TFRServer 容器资源
默认值一览
定义在 internal/controller/tfrobot/deployables/resources.go:22-46:
| 容器 | Requests (CPU/Mem) | Limits (CPU/Mem) |
|---|---|---|
| API | 250m / 256Mi | 1000m / 1Gi |
| Worker (memory-worker) | 500m / 512Mi | 2000m / 2Gi |
| RobotWorker | 500m / 512Mi | 2000m / 2Gi |
单个 TFRServer Requests 合计:1.25 CPU / 1.25Gi Memory
单个 TFRServer Limits 合计:5 CPU / 5Gi Memory
自动填充触发条件
同时满足以下两个条件时触发(deployables/resources.go:48-60):
- 至少一个容器的 resources 为 nil
- 命名空间存在包含 CPU/Memory 的 ResourceQuota
调用入口:tfrserver_controller.go:286-295
用户配置示例
apiVersion: tfrobot.tfrobot.io/v1
kind: TFRServer
spec:
apiResources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
workerResources:
requests:
cpu: "1000m"
memory: "1Gi"
CRD 字段定义:api/tfrobot/v1/tfrserver_types.go:401-418
Quota 容量规划
以单租户(1 个 TFRTenant + 1 个 TFRServer)为例,使用默认值时的最低 Quota:
| 资源类型 | Requests | Limits |
|---|---|---|
| CPU | 3.1 (1.85 + 1.25) | 13.4 (8.4 + 5) |
| Memory | 4.3Gi (3 + 1.25) | 16.5Gi (11.5 + 5) |
- 以上仅为 Operator 管理的 Pod,不含 Kubernetes 系统组件和第三方 Operator 的 Pod
- 多个 TFRServer 时需按比例增加:每增加一个 TFRServer,Requests 增加 1.25 CPU / 1.25Gi
- 建议 Quota 预留 20-30% 余量用于滚动更新等临时 Pod
相关代码索引
| 模块 | 路径 |
|---|---|
| TFRTenant 组件默认值 | internal/controller/infra/tenant/resources.go |
| ResourceQuota Deployable | internal/controller/infra/tenant/resource_quota.go |
| TFRTenant 自动填充逻辑 | internal/controller/infra/tfrtenant_controller.go:255-295 |
| TFRServer 容器默认值 | internal/controller/tfrobot/deployables/resources.go |
| TFRServer 自动填充逻辑 | internal/controller/tfrobot/tfrserver_controller.go:286-295 |
| ResourceQuota CRD 类型 | api/infra/v1/tfrtenant_types.go:316-329 |
| 容器资源 CRD 类型 | api/tfrobot/v1/tfrserver_types.go:401-418 |
| Options 定义 | internal/controller/infra/tenant/options.go |