Files
foxhunt/infra/modules/kapsule/main.tf
jgrusewski 86de265fc8 infra(kapsule): add ci-compile-cpu-hm pool for 9-quarter fxcache
Two 9-quarter precompute_features runs OOM-killed on the existing
ci-compile-cpu pool (POP2-HC-32C-64G, 56Gi cgroup limit):
  - train-wq8b8: exit 137 ~12s after "OFI computed" at ~57Gi
  - train-2l6p4: exit 137 ~12s after "OFI computed" at ~52Gi peak
    (despite the into_iter + drop(feature_vectors) +
    normalize_in_place refactors landed in a27cb40a9 + 623ebfcf7,
    which trimmed ~12GB of avoidable retention)

The remaining ~52-60GB peak is the irreducible working set at the
post-OFI / pre-alpha-pipeline step:
  - 9-quarter MBP-10 snapshots (~10GB)
  - 199M front-month trades as Mbp10Trade (~13GB)
  - 17.8M bars × features + targets + OFI buffers (~14GB)
  - alpha_snapshots (move-handoff from all_snapshots, ~10GB)
  - feature/target Vecs (~7GB) + Rust allocator overhead

Adds a dedicated high-memory pool sized for this rare path:

- New scaleway_k8s_pool.ci_compile_cpu_hm (POP2-HM-32C-256G,
  32 vCPU + 256GB RAM) with size=0 + min_size=0 autoscaling. Costs
  zero when idle; autoscaler provisions one node when a pod targets
  `nodeSelector: ci-compile-cpu-hm`.
- New variables: enable_ci_compile_cpu_hm_pool,
  ci_compile_cpu_hm_type (default POP2-HM-32C-256G),
  ci_compile_cpu_hm_max_size (default 1).
- terragrunt.hcl: enable the pool, max_size=1.
- train-template.yaml: ensure-fxcache nodeSelector pinned to
  ci-compile-cpu-hm; memory limit raised 56Gi → 200Gi. The
  ci-compile-cpu pool stays as the standard CI compile target for
  ensure-binary + every other CPU-heavy task.

Apply with:
  cd infra/live/production/kapsule
  terragrunt apply -target=module.kapsule.scaleway_k8s_pool.ci_compile_cpu_hm
  kubectl apply -n foxhunt -f ../../../../infra/k8s/argo/train-template.yaml

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:13:03 +02:00

190 lines
5.9 KiB
HCL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
resource "scaleway_vpc_private_network" "foxhunt" {
name = "${var.cluster_name}-pn"
region = var.region
}
# VPC Public Gateway — provides NAT (masquerade) for private nodes
# and DHCP with default route propagation to prevent DNS deadlock.
# See incident_dns_deadlock.md for why this is critical.
resource "scaleway_vpc_public_gateway" "foxhunt" {
name = "${var.cluster_name}-gw"
type = "VPC-GW-S"
zone = "${var.region}-2"
bastion_enabled = true
bastion_port = 61000
}
resource "scaleway_vpc_public_gateway_dhcp" "foxhunt" {
subnet = "172.16.0.0/22"
push_default_route = true
push_dns_server = true
zone = "${var.region}-2"
}
resource "scaleway_vpc_gateway_network" "foxhunt" {
gateway_id = scaleway_vpc_public_gateway.foxhunt.id
private_network_id = scaleway_vpc_private_network.foxhunt.id
dhcp_id = scaleway_vpc_public_gateway_dhcp.foxhunt.id
enable_masquerade = true
zone = "${var.region}-2"
}
resource "scaleway_k8s_cluster" "foxhunt" {
name = var.cluster_name
version = var.k8s_version
cni = "cilium"
region = var.region
delete_additional_resources = true
private_network_id = scaleway_vpc_private_network.foxhunt.id
auto_upgrade {
enable = true
maintenance_window_start_hour = 4
maintenance_window_day = "sunday"
}
autoscaler_config {
disable_scale_down = false
scale_down_delay_after_add = "10m"
scale_down_unneeded_time = "10m"
estimator = "binpacking"
ignore_daemonsets_utilization = true
}
}
# Platform pool — runs everything: app services, databases, GitLab, monitoring
resource "scaleway_k8s_pool" "platform" {
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "platform"
node_type = var.platform_type
size = 1
min_size = 1
max_size = var.platform_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# L40S training pool (48GB VRAM, CUDA CC 89 — hyperopt + supervised training)
resource "scaleway_k8s_pool" "ci_training_l40s" {
count = var.enable_ci_training_l40s_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-training-l40s"
node_type = var.ci_training_l40s_type
size = 1
min_size = 0
max_size = var.ci_training_l40s_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# H100 training pool (80GB VRAM, CUDA CC 90 — RL hyperopt)
resource "scaleway_k8s_pool" "ci_training_h100" {
count = var.enable_ci_training_h100_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-training-h100"
node_type = var.ci_training_h100_type
size = 1
min_size = 0 # Scale to zero when idle. Cold start: ~15 min NVIDIA driver install.
max_size = var.ci_training_h100_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# H100x2 training pool (2x 80GB VRAM — multi-GPU parallel hyperopt)
resource "scaleway_k8s_pool" "ci_training_h100x2" {
count = var.enable_ci_training_h100x2_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-training-h100x2"
node_type = var.ci_training_h100x2_type
size = 1
min_size = 0
max_size = var.ci_training_h100x2_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# H100-SXM training pool (2x 80GB SXM VRAM — NVLink multi-GPU)
resource "scaleway_k8s_pool" "ci_training_h100_sxm" {
count = var.enable_ci_training_h100_sxm_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-training-h100-sxm"
node_type = var.ci_training_h100_sxm_type
size = 1
min_size = 0
max_size = var.ci_training_h100_sxm_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# CPU compile pool (POP2-HC — high CPU, no GPU, for cargo check/build)
resource "scaleway_k8s_pool" "ci_compile_cpu" {
count = var.enable_ci_compile_cpu_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-compile-cpu"
node_type = var.ci_compile_cpu_type
size = 1
min_size = 0
max_size = var.ci_compile_cpu_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}
# High-memory CPU compile pool (POP2-HM — same CPU count as ci-compile-cpu
# but 4× the RAM; reserved for rare full-rebuild precompute_features runs
# that can't fit on the standard 64GB nodes). min_size=0 + size=0 initial
# so the pool costs nothing when idle — autoscaler provisions one node
# only when a pod targets `nodeSelector: ci-compile-cpu-hm`.
resource "scaleway_k8s_pool" "ci_compile_cpu_hm" {
count = var.enable_ci_compile_cpu_hm_pool ? 1 : 0
cluster_id = scaleway_k8s_cluster.foxhunt.id
name = "ci-compile-cpu-hm"
node_type = var.ci_compile_cpu_hm_type
size = 0
min_size = 0
max_size = var.ci_compile_cpu_hm_max_size
autoscaling = true
autohealing = true
public_ip_disabled = var.public_ip_disabled
region = var.region
lifecycle {
ignore_changes = [size]
}
}