prop/k8s/deployment-grid-rs.yaml

94 lines
3 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: prop-grid-rs
namespace: prop
# Phase 1 (shadow) default: write to /data/scores_shadow so Elixir keeps
# owning the live /data/scores tree. Flip PROP_SCORES_DIR to /data/scores
# at cutover after ShadowComparator shows < 0.5 mean delta for 72h.
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-1776633497-5692d50 # {"$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_shadow"
- name: RUST_LOG
value: "info"
- name: PROP_GRID_RS_PG_CONNS
value: "4"
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: 128Mi
limits:
cpu: "4"
memory: 512Mi
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