From 403d368e8ef368b7ab4c843cbc88564966fdb3ab Mon Sep 17 00:00:00 2001 From: George Hong Date: Mon, 8 Jun 2026 17:54:45 -0700 Subject: [PATCH 1/3] Update [ghstack-poisoned] --- osdc/modules/nfd/deploy.sh | 48 +++++++++++++++ osdc/modules/nfd/helm/values.yaml | 57 ++++++++++++++++++ osdc/modules/numa-scheduler/deploy.sh | 61 ++++++++++++++++++++ osdc/modules/numa-scheduler/helm/values.yaml | 57 ++++++++++++++++++ 4 files changed, 223 insertions(+) create mode 100755 osdc/modules/nfd/deploy.sh create mode 100644 osdc/modules/nfd/helm/values.yaml create mode 100755 osdc/modules/numa-scheduler/deploy.sh create mode 100644 osdc/modules/numa-scheduler/helm/values.yaml diff --git a/osdc/modules/nfd/deploy.sh b/osdc/modules/nfd/deploy.sh new file mode 100755 index 00000000..7e13d5f0 --- /dev/null +++ b/osdc/modules/nfd/deploy.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail +# +# Deploy NFD topology-updater for NUMA-aware scheduling. +# Called by: just deploy-module nfd +# +# Args: $1=cluster-id $2=cluster-name $3=region +# +# Installs the Node Feature Discovery Helm chart with only the +# topology-updater enabled. This publishes NodeResourceTopology CRDs +# that the numa-scheduler reads to make NUMA-aware placement decisions. + +CLUSTER="$1" +_CNAME="$2" # unused but required by deploy-module interface +_REGION="$3" # unused but required by deploy-module interface +MODULE_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="${OSDC_ROOT:-$(cd "$MODULE_DIR/../.." && pwd)}" +UPSTREAM_ROOT="${OSDC_UPSTREAM:-$REPO_ROOT}" + +# shellcheck source=/dev/null +source "$UPSTREAM_ROOT/scripts/mise-activate.sh" +# shellcheck source=/dev/null +source "$UPSTREAM_ROOT/scripts/helm-upgrade.sh" + +CFG="$UPSTREAM_ROOT/scripts/cluster-config.py" + +# --- Check if enabled --- +ENABLED=$(uv run "$CFG" "$CLUSTER" nfd.enabled "false") +if [[ "$ENABLED" != "true" ]]; then + echo "NFD disabled for cluster $CLUSTER, skipping." + exit 0 +fi + +NFD_VERSION=$(uv run "$CFG" "$CLUSTER" nfd.version "0.17.1") +NFD_UPDATE_INTERVAL=$(uv run "$CFG" "$CLUSTER" nfd.update_interval "15s") + +echo "Installing NFD topology-updater v${NFD_VERSION}..." +helm_upgrade_if_changed nfd nfd \ + --create-namespace \ + --history-max 3 \ + -f "$MODULE_DIR/helm/values.yaml" \ + --set topologyUpdater.updateInterval="${NFD_UPDATE_INTERVAL}" \ + --timeout 5m \ + --wait \ + oci://ghcr.io/kubernetes-sigs/charts/node-feature-discovery \ + --version "${NFD_VERSION}" + +echo "NFD topology-updater deployed." diff --git a/osdc/modules/nfd/helm/values.yaml b/osdc/modules/nfd/helm/values.yaml new file mode 100644 index 00000000..45fe4d72 --- /dev/null +++ b/osdc/modules/nfd/helm/values.yaml @@ -0,0 +1,57 @@ +# Node Feature Discovery — topology-updater only +# Chart: https://github.com/kubernetes-sigs/node-feature-discovery/tree/master/deployment/helm/node-feature-discovery +# +# We only need the topology-updater component, which publishes +# NodeResourceTopology CRDs per node. The NFD worker (feature detection) +# and master (label reconciliation) are disabled — we don't need node +# feature labels, just per-NUMA-zone resource visibility for the +# numa-scheduler. + +master: + enable: false + +worker: + enable: false + +topologyUpdater: + enable: true + + # Poll kubelet PodResources API every 15s (default 60s). Needs to be + # faster than the ARC capacity provisioner interval (30s) so NRT + # objects reflect current GPU allocations before placeholder pods are + # evaluated by the NUMA-aware scheduler. + updateInterval: 15s + + # Only run on GPU nodes — non-GPU nodes don't have NUMA topology + # concerns and don't need NRT objects. + nodeSelector: + nvidia.com/gpu: "true" + + # Tolerate all GPU node taints so the topology-updater schedules + # at provisioning time, same as other GPU-node DaemonSets. + tolerations: + - key: nvidia.com/gpu + operator: Exists + effect: NoSchedule + - key: node-fleet + operator: Exists + effect: NoSchedule + - key: instance-type + operator: Exists + effect: NoSchedule + - key: git-cache-not-ready + operator: Exists + effect: NoSchedule + + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +# The topology-updater needs the NRT CRD. The NFD chart installs it +# when topologyUpdater is enabled. +topologyGC: + enable: true diff --git a/osdc/modules/numa-scheduler/deploy.sh b/osdc/modules/numa-scheduler/deploy.sh new file mode 100755 index 00000000..64fedb7f --- /dev/null +++ b/osdc/modules/numa-scheduler/deploy.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail +# +# Deploy NUMA-aware secondary scheduler (scheduler-plugins). +# Called by: just deploy-module numa-scheduler +# +# Args: $1=cluster-id $2=cluster-name $3=region +# +# Downloads the scheduler-plugins Helm chart from the GitHub release +# and installs it as a secondary scheduler named "numa-scheduler" with +# NodeResourceTopologyMatch enabled. Pods that set +# schedulerName: numa-scheduler get NUMA-aware placement. + +CLUSTER="$1" +_CNAME="$2" # unused but required by deploy-module interface +_REGION="$3" # unused but required by deploy-module interface +MODULE_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="${OSDC_ROOT:-$(cd "$MODULE_DIR/../.." && pwd)}" +UPSTREAM_ROOT="${OSDC_UPSTREAM:-$REPO_ROOT}" + +# shellcheck source=/dev/null +source "$UPSTREAM_ROOT/scripts/mise-activate.sh" +# shellcheck source=/dev/null +source "$UPSTREAM_ROOT/scripts/helm-upgrade.sh" + +CFG="$UPSTREAM_ROOT/scripts/cluster-config.py" + +# --- Check if enabled --- +ENABLED=$(uv run "$CFG" "$CLUSTER" numa_scheduler.enabled "false") +if [[ "$ENABLED" != "true" ]]; then + echo "numa-scheduler disabled for cluster $CLUSTER, skipping." + exit 0 +fi + +CHART_VERSION=$(uv run "$CFG" "$CLUSTER" numa_scheduler.chart_version "0.34.7") +SCHEDULER_REPLICAS=$(uv run "$CFG" "$CLUSTER" numa_scheduler.replicas "2") + +# --- Download chart from GitHub release --- +CHART_TGZ="scheduler-plugins-${CHART_VERSION}.tgz" +CHART_DIR=$(mktemp -d) +trap 'rm -rf "$CHART_DIR"' EXIT + +if [[ ! -f "${CHART_DIR}/${CHART_TGZ}" ]]; then + echo "Downloading scheduler-plugins chart v${CHART_VERSION}..." + gh release download "v${CHART_VERSION}" \ + --repo kubernetes-sigs/scheduler-plugins \ + --pattern "${CHART_TGZ}" \ + --dir "$CHART_DIR" +fi + +echo "Installing numa-scheduler (scheduler-plugins v${CHART_VERSION})..." +helm_upgrade_if_changed numa-scheduler numa-scheduler \ + --create-namespace \ + --history-max 3 \ + -f "$MODULE_DIR/helm/values.yaml" \ + --set scheduler.replicaCount="${SCHEDULER_REPLICAS}" \ + --timeout 5m \ + --wait \ + "${CHART_DIR}/${CHART_TGZ}" + +echo "numa-scheduler deployed." diff --git a/osdc/modules/numa-scheduler/helm/values.yaml b/osdc/modules/numa-scheduler/helm/values.yaml new file mode 100644 index 00000000..c5fb3858 --- /dev/null +++ b/osdc/modules/numa-scheduler/helm/values.yaml @@ -0,0 +1,57 @@ +# Scheduler-plugins — NUMA-aware secondary scheduler +# Chart source: https://github.com/kubernetes-sigs/scheduler-plugins +# (vendored from manifests/install/charts/as-a-second-scheduler/) +# +# Deploys a second kube-scheduler named "numa-scheduler" with the +# NodeResourceTopologyMatch plugin enabled. Pods that set +# schedulerName: numa-scheduler will be filtered/scored by per-NUMA-zone +# resource availability (read from NodeResourceTopology CRDs published +# by the NFD topology-updater). +# +# Nothing uses this scheduler until runner definitions set +# scheduler_name: numa-scheduler — deploying it is a no-op. + +scheduler: + name: numa-scheduler + image: registry.k8s.io/scheduler-plugins/kube-scheduler:v0.34.7 + replicaCount: 2 + leaderElect: true + + # Run on base-infrastructure nodes alongside other control plane components. + nodeSelector: + role: base-infrastructure + + tolerations: + - key: CriticalAddonsOnly + operator: Equal + value: "true" + effect: NoSchedule + + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# The controller is needed for Coscheduling/CapacityScheduling plugins. +# We only use NodeResourceTopologyMatch, so disable it. +controller: + replicaCount: 0 + +# Only enable NodeResourceTopologyMatch — we don't need Coscheduling, +# CapacityScheduling, or other plugins. +plugins: + enabled: + - NodeResourceTopologyMatch + disabled: [] + +pluginConfig: + - name: NodeResourceTopologyMatch + args: + scoringStrategy: + # Pack pods onto already-busy NUMA zones so other zones stay + # fully free for large (4-GPU) requests. Without this, small + # pods spread across sockets and fragment both. + type: MostAllocated From 8d3917e4c6f844b5d3158d6884dcb28982c33798 Mon Sep 17 00:00:00 2001 From: George Hong Date: Mon, 8 Jun 2026 18:18:25 -0700 Subject: [PATCH 2/3] Update [ghstack-poisoned] --- osdc/modules/numa-scheduler/deploy.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osdc/modules/numa-scheduler/deploy.sh b/osdc/modules/numa-scheduler/deploy.sh index 64fedb7f..3e7bd5de 100755 --- a/osdc/modules/numa-scheduler/deploy.sh +++ b/osdc/modules/numa-scheduler/deploy.sh @@ -40,13 +40,11 @@ CHART_TGZ="scheduler-plugins-${CHART_VERSION}.tgz" CHART_DIR=$(mktemp -d) trap 'rm -rf "$CHART_DIR"' EXIT -if [[ ! -f "${CHART_DIR}/${CHART_TGZ}" ]]; then - echo "Downloading scheduler-plugins chart v${CHART_VERSION}..." - gh release download "v${CHART_VERSION}" \ - --repo kubernetes-sigs/scheduler-plugins \ - --pattern "${CHART_TGZ}" \ - --dir "$CHART_DIR" -fi +echo "Downloading scheduler-plugins chart v${CHART_VERSION}..." +gh release download "v${CHART_VERSION}" \ + --repo kubernetes-sigs/scheduler-plugins \ + --pattern "${CHART_TGZ}" \ + --dir "$CHART_DIR" echo "Installing numa-scheduler (scheduler-plugins v${CHART_VERSION})..." helm_upgrade_if_changed numa-scheduler numa-scheduler \ From 3719c31717393dd5c3d25f2411b1fce9d1136eee Mon Sep 17 00:00:00 2001 From: George Hong Date: Wed, 10 Jun 2026 15:00:59 -0700 Subject: [PATCH 3/3] Update [ghstack-poisoned] --- osdc/modules/nfd/deploy.sh | 13 ++----------- osdc/modules/numa-scheduler/deploy.sh | 13 ++----------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/osdc/modules/nfd/deploy.sh b/osdc/modules/nfd/deploy.sh index 8a3fa95b..841c8c49 100755 --- a/osdc/modules/nfd/deploy.sh +++ b/osdc/modules/nfd/deploy.sh @@ -11,26 +11,17 @@ set -euo pipefail # that the numa-scheduler reads to make NUMA-aware placement decisions. CLUSTER="$1" -_CNAME="$2" # unused but required by deploy-module interface -_REGION="$3" # unused but required by deploy-module interface +export CNAME="$2" +export REGION="$3" MODULE_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="${OSDC_ROOT:-$(cd "$MODULE_DIR/../.." && pwd)}" UPSTREAM_ROOT="${OSDC_UPSTREAM:-$REPO_ROOT}" - # shellcheck source=/dev/null source "$UPSTREAM_ROOT/scripts/mise-activate.sh" # shellcheck source=/dev/null source "$UPSTREAM_ROOT/scripts/helm-upgrade.sh" - CFG="$UPSTREAM_ROOT/scripts/cluster-config.py" -# --- Check if enabled --- -ENABLED=$(uv run "$CFG" "$CLUSTER" nfd.enabled "false") -if [[ "$ENABLED" != "true" ]]; then - echo "NFD disabled for cluster $CLUSTER, skipping." - exit 0 -fi - NFD_VERSION=$(uv run "$CFG" "$CLUSTER" nfd.version "0.17.1") NFD_UPDATE_INTERVAL=$(uv run "$CFG" "$CLUSTER" nfd.update_interval "15s") diff --git a/osdc/modules/numa-scheduler/deploy.sh b/osdc/modules/numa-scheduler/deploy.sh index a39bec01..a5ca18e1 100755 --- a/osdc/modules/numa-scheduler/deploy.sh +++ b/osdc/modules/numa-scheduler/deploy.sh @@ -12,26 +12,17 @@ set -euo pipefail # schedulerName: numa-scheduler get NUMA-aware placement. CLUSTER="$1" -_CNAME="$2" # unused but required by deploy-module interface -_REGION="$3" # unused but required by deploy-module interface +export CNAME="$2" +export REGION="$3" MODULE_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="${OSDC_ROOT:-$(cd "$MODULE_DIR/../.." && pwd)}" UPSTREAM_ROOT="${OSDC_UPSTREAM:-$REPO_ROOT}" - # shellcheck source=/dev/null source "$UPSTREAM_ROOT/scripts/mise-activate.sh" # shellcheck source=/dev/null source "$UPSTREAM_ROOT/scripts/helm-upgrade.sh" - CFG="$UPSTREAM_ROOT/scripts/cluster-config.py" -# --- Check if enabled --- -ENABLED=$(uv run "$CFG" "$CLUSTER" numa_scheduler.enabled "false") -if [[ "$ENABLED" != "true" ]]; then - echo "numa-scheduler disabled for cluster $CLUSTER, skipping." - exit 0 -fi - CHART_VERSION=$(uv run "$CFG" "$CLUSTER" numa_scheduler.chart_version "0.34.7") SCHEDULER_REPLICAS=$(uv run "$CFG" "$CLUSTER" numa_scheduler.replicas "2")