prop/k8s/deployment-grid-rs.yaml

109 lines
3.9 KiB
YAML
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.

apiVersion: apps/v1
kind: Deployment
metadata:
name: prop-grid-rs
namespace: prop
# Phase 2 cutover: Rust writes directly to /data/scores. Elixir only
# runs the f00 analysis-hour step (which carries enrichment Rust
# doesn't own yet — native-level duct merge, NEXRAD composite,
# commercial-link degradation, ProfilesFile write). f01..f18 land
# here from the Rust worker.
spec:
replicas: 1
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
selector:
matchLabels:
app: prop-grid-rs
template:
metadata:
labels:
app: prop-grid-rs
tier: grid-rs
spec:
# Pin to talos5 — the 32 GB NUC with NVMe. The worker peaks at ~500 Mi
# steady-state but benefits from local NVMe for the NFS scores-dir
# writes (faster fsync) and from never sharing the node with a hot
# Elixir pod. Label talos5 with `prop-grid-rs=primary` and taint it
# `workload=grid-rs:NoSchedule` to enforce this.
nodeSelector:
prop-grid-rs: "primary"
tolerations:
- key: workload
operator: Equal
value: grid-rs
effect: NoSchedule
imagePullSecrets:
- name: forgejo-registry
securityContext:
runAsUser: 65534
runAsNonRoot: true
fsGroup: 65534
seccompProfile:
type: RuntimeDefault
containers:
- name: prop-grid-rs
# Image built by a new CI pipeline from rust/prop_grid_rs/.
# Multi-arch (amd64 + arm64) — reuses the repo's existing
# buildx wiring.
image: git.mcintire.me/graham/prop-grid-rs:main-1776637891-022e692 # {"$imagepolicy": "flux-system:prop-grid-rs"}
imagePullPolicy: IfNotPresent
env:
# Elixir secrets bundle carries DATABASE_URL already. Rust
# reads it directly (sqlx connects with the same URL).
- name: HRRR_BASE_URL
value: "http://skippy.w5isp.com:8080"
- name: PROP_SCORES_DIR
value: "/data/scores"
- name: RUST_LOG
value: "info"
# talos5 is 4c/4t (i5-7260U). Claiming 4 forecast hours in
# parallel drops full-chain wall time from ~18 min serial to
# ~5 min. Each concurrent task peaks around 250 Mi after the
# streamed-bands refactor; 4×250 ≈ 1 Gi is comfortably under
# the 2 Gi memory limit.
- name: PROP_GRID_RS_PARALLELISM
value: "4"
# Pool size = parallelism + 2 (NOTIFY + retry slack). Kept in
# sync with PROP_GRID_RS_PARALLELISM when either changes.
- name: PROP_GRID_RS_PG_CONNS
value: "6"
envFrom:
- secretRef:
name: prop-secrets
# No HTTP surface. Liveness is "the process is still running";
# let the kubelet restart us if we crash. Claiming work from
# grid_tasks is the implicit readiness signal — an idle pod is
# still healthy (the queue is simply empty).
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: "4"
# OOM at 1 Gi during active chain work (92k points × 23
# bands ≈ 2.1M scores, plus decoded GRIB2 buffers, plus
# wgrib2 subprocess memory). 2 Gi leaves headroom; we're
# still an order of magnitude below the 6 Gi Elixir budget.
memory: 2Gi
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 65534
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
nfs:
server: 10.0.15.103
path: /data