---
id: w1/m3/t002
title: KubeScheduler MostAllocated profile (density)
worker: worker1
status: done
estimate: 30m
depends_on: [w1/m3/t001]
---

## Objective

Default kube-scheduler _spreads_ pods; bex wants it to _pack_ onto the fullest node so empty nodes free up for scale-down. Configure a `MostAllocated` scoring profile.

## Context

- `KubeSchedulerConfiguration` profile: plugin `NodeResourcesFit`, `scoringStrategy.type: MostAllocated`.
- Delivered via the KubeadmControlPlane scheduler `--config` in the CAPH overlay.
- No visible effect until multi-node (single node today).

## Files

- `infra/clusterapi/overlays/hetzner-caph/cluster.yaml` (KCP)

## Acceptance criteria

- [x] On a multi-node cluster, new pods land on the most-allocated node (verified in m3/t005). _Met 2026-07-09:_ `scripts/verify-elastic.sh` pack check — probe chose the 9350m-requests worker over the 6550m one on the CAPD mock. Config delivered in both overlays; on the live mock the scheduler runs with `--config=/etc/kubernetes/scheduler-config.yaml`. Gotcha fixed en route: the local ClusterClass `podSecurityStandard` patch did `add /files` (RFC 6902 replace) and clobbered the scheduler file — now appends via `/files/-`.

## Out of scope

- Autoscaler (t003/t004); idle-evict is the other half of the allocator (m4).
