From 66dd0c9ff5dfcea47789bdc1ef7cd7f33d72c9b7 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Wed, 3 Sep 2025 15:45:49 +0100 Subject: [PATCH] feat(supervisor): add configurable resource requests --- apps/supervisor/src/env.ts | 4 ++++ .../src/workloadManager/kubernetes.ts | 21 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/apps/supervisor/src/env.ts b/apps/supervisor/src/env.ts index 074c18ad74..99cb16425b 100644 --- a/apps/supervisor/src/env.ts +++ b/apps/supervisor/src/env.ts @@ -85,6 +85,10 @@ const Env = z.object({ KUBERNETES_EPHEMERAL_STORAGE_SIZE_LIMIT: z.string().default("10Gi"), KUBERNETES_EPHEMERAL_STORAGE_SIZE_REQUEST: z.string().default("2Gi"), KUBERNETES_STRIP_IMAGE_DIGEST: BoolEnv.default(false), + KUBERNETES_CPU_REQUEST_MIN_CORES: z.coerce.number().min(0).default(0), + KUBERNETES_CPU_REQUEST_RATIO: z.coerce.number().min(0).max(1).default(0.75), // Ratio of CPU limit, so 0.75 = 75% of CPU limit + KUBERNETES_MEMORY_REQUEST_MIN_GB: z.coerce.number().min(0).default(0), + KUBERNETES_MEMORY_REQUEST_RATIO: z.coerce.number().min(0).max(1).default(1), // Ratio of memory limit, so 1 = 100% of memory limit // Placement tags settings PLACEMENT_TAGS_ENABLED: BoolEnv.default(false), diff --git a/apps/supervisor/src/workloadManager/kubernetes.ts b/apps/supervisor/src/workloadManager/kubernetes.ts index b38e6c5b46..55281c56a6 100644 --- a/apps/supervisor/src/workloadManager/kubernetes.ts +++ b/apps/supervisor/src/workloadManager/kubernetes.ts @@ -20,6 +20,12 @@ export class KubernetesWorkloadManager implements WorkloadManager { private namespace = env.KUBERNETES_NAMESPACE; private placementTagProcessor: PlacementTagProcessor; + // Resource settings + private readonly cpuRequestMinCores = env.KUBERNETES_CPU_REQUEST_MIN_CORES; + private readonly cpuRequestRatio = env.KUBERNETES_CPU_REQUEST_RATIO; + private readonly memoryRequestMinGb = env.KUBERNETES_MEMORY_REQUEST_MIN_GB; + private readonly memoryRequestRatio = env.KUBERNETES_MEMORY_REQUEST_RATIO; + constructor(private opts: WorkloadManagerOptions) { this.k8s = createK8sApi(); this.placementTagProcessor = new PlacementTagProcessor({ @@ -63,6 +69,10 @@ export class KubernetesWorkloadManager implements WorkloadManager { return imageRef.substring(0, atIndex); } + private clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max); + } + async create(opts: WorkloadManagerCreateOptions) { this.logger.log("[KubernetesWorkloadManager] Creating container", { opts }); @@ -295,9 +305,16 @@ export class KubernetesWorkloadManager implements WorkloadManager { } #getResourceRequestsForMachine(preset: MachinePreset): ResourceQuantities { + const cpuRequest = preset.cpu * this.cpuRequestRatio; + const memoryRequest = preset.memory * this.memoryRequestRatio; + + // Clamp between min and max + const clampedCpu = this.clamp(cpuRequest, this.cpuRequestMinCores, preset.cpu); + const clampedMemory = this.clamp(memoryRequest, this.memoryRequestMinGb, preset.memory); + return { - cpu: `${preset.cpu * 0.75}`, - memory: `${preset.memory}G`, + cpu: `${clampedCpu}`, + memory: `${clampedMemory}G`, }; }