Skip to content

feat(platform): k8s manifests for QuanvNN MVP (Sprint 2C)#41

Merged
JackMaarek merged 7 commits into
mainfrom
feat/quanvnn-platform-infra-k8s
Apr 26, 2026
Merged

feat(platform): k8s manifests for QuanvNN MVP (Sprint 2C)#41
JackMaarek merged 7 commits into
mainfrom
feat/quanvnn-platform-infra-k8s

Conversation

@JackMaarek

@JackMaarek JackMaarek commented Apr 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Sprint 2C from roadmap.md — Kubernetes manifests + Helm chart only.
Five distinct commits, each addressing one Sprint 2C item.

Pre-flight: integrity review GO_WITH_WARNINGS, 0 blockers.

Commits

  • 7345510 fix(values): rename IRSA placeholder for QuanvNN
  • 94697b7 feat(argocd): NVIDIA device plugin ApplicationSet
  • 0d02210 feat(scheduling): GPU PriorityClasses + ApplicationSet
  • 0ec75cf feat(kyverno): allow public.ecr.aws/aws-cli for initContainers
  • a4d5980 feat(chart): conditional ExternalSecret for ghcr-pull-secret

Audit findings addressed

  • HIGH (audit §3.2): NVIDIA device plugin missing → ApplicationSet
    added at sync-wave 2.
  • MEDIUM (audit §3.6): chart references ghcr-pull-secret without an
    ExternalSecret template → conditional template added (opt-in).
  • Sprint 2C item 2.4: __IRSA_ROLE_ARN____QUANVNN_IRSA_ROLE_ARN__,
    aligning with platform-bot (PR [FEATURE] GPU node group — Terraform + NVIDIA device plugin + MIG time-slicing #7, ffd16f5).
  • Sprint 2C item 2.7: Kyverno allowlist extended for public.ecr.aws/aws-cli
    (Sprint 3 dataSync initContainer).

Identity chain (audit §6)

  • SA: quanvnn-sa in ml. Locked by chart helpers (verified via
    helm template in pre-2C integrity review).
  • IRSA placeholder: __QUANVNN_IRSA_ROLE_ARN__ (this PR).
  • Bucket placeholder: __QUANVNN_DATASETS_BUCKET_NAME__ (NOT consumed
    in this PR — Sprint 3 will use it). Note: canonical name uses NAME
    suffix and plural "datasets".

Validation

  • helm lint passes with quanvnn-dev.yaml (after C1 and after C5).
  • helm template renders zero ExternalSecret with chart defaults,
    exactly one when imagePullSecret.enabled=true.
  • helm template escape verification: rendered .dockerconfigjson
    body contains literal {{ .dockerconfig | toString }} for ESO to
    evaluate at sync time.
  • YAML structural validation via Ruby YAML.load_file on all new
    ApplicationSets and PriorityClass manifests.
  • No kubectl apply against a live cluster — Sprint 2 orchestration
    handles that via the bot.

Deviations from prompt — justified

  1. AS path: prompt said argocd/applicationsets/; the repo
    convention is argocd/platform/<domain>/<name>.yaml. Used
    argocd/platform/gpu/ for both new ASes (NVIDIA + PriorityClasses).
  2. imagePullSecret schema: prompt suggested new field names
    (create, name, secretStoreRef, remoteSecretKey); existing
    chart already had enabled, secretName, awsSecretPath. Reused
    the existing names, flipped default enabled: true → false (safer
    opt-in), added secretStoreRef only.

Follow-ups (separate sessions)

  • Sprint 2D (platform-bot): bot's internal/gitops/placeholders.go
    must learn versions.nvidia_device_plugin
    __NVIDIA_DEVICE_PLUGIN_VERSION__. Until shipped, the NVIDIA AS
    carries a literal placeholder and won't sync — flagged in commit
    message of 94697b7.
  • AWS SM seed (operator, manual): before bootstrap eks --env dev,
    seed the secret at platform/dev/ghcr-pull-token (or
    platform/ghcr-pull-token per current quanvnn-dev value) with a
    JSON object containing a dockerconfig key.

Out of scope

  • AWS Secrets Manager pre-seed (manual AWS CLI step — roadmap §2.9).
  • Bot orchestration: env hydrate → plan → apply --local → bootstrap
    eks → re-hydrate (roadmap §2.12-2.17).
  • Sprint 3 dataSync initContainer (consumes the bucket placeholder
    and the new Kyverno allowlist entry).

Review-driven follow-up commits

  • e402435 fix(argocd): extend platform project for Sprint 2C ASes
    (resolves F1 + F2 from PR_41_REVIEW.md — adds
    https://nvidia.github.io/k8s-device-plugin to sourceRepos and
    scheduling.k8s.io/PriorityClass to clusterResourceWhitelist on the
    platform AppProject).

Align with platform-bot mapping (PR #7, ffd16f5). The bot exposes
__QUANVNN_IRSA_ROLE_ARN__ resolved from terraform output
quanvnn_irsa_role_arn (k8s-platform PR #39). Without this rename, the
bot would not substitute the placeholder and the rendered ServiceAccount
annotation would carry a literal __IRSA_ROLE_ARN__ string — IRSA would
silently fail with assumeRoleWithWebIdentity errors at first run.

Identity chain: SA quanvnn-sa in ml namespace, derived from
nameOverride=quanvnn + releaseName=quanvnn + suffix '-sa'.
Resolves AUDIT_QUANVNN_MVP.md HIGH finding — the NVIDIA k8s-device-
plugin DaemonSet was not installed by any ApplicationSet. Without it,
the kubelet does not advertise nvidia.com/gpu, so GPU Jobs stay Pending
forever even after Cluster Autoscaler provisions a g4dn node.

- New ApplicationSet at sync-wave 2 (after istio-base/istiod/CNI).
- Targets kube-system, project: platform, releaseName: nvidia-device-plugin.
- Restricts the DaemonSet to nodes labelled node-group=gpu (matches
  terraform.tfvars node_groups.gpu.labels) — CPU nodes unaffected.
- Tolerates the GPU taint nvidia.com/gpu=true:NoSchedule.
- Pinned via __NVIDIA_DEVICE_PLUGIN_VERSION__ in platform.yaml (0.19.1).

Bot follow-up (Sprint 2D): platform-bot must learn to map
versions.nvidia_device_plugin → __NVIDIA_DEVICE_PLUGIN_VERSION__ in
internal/gitops/placeholders.go before this ApplicationSet can sync.
Platform-owned PriorityClasses for GPU workloads. They are cluster-
scoped resources, so they cannot live in the chart-owned ml AppProject
(whose clusterResourceWhitelist is empty). The platform AppProject
scope owns them, deployed via a dedicated ApplicationSet at sync-wave
-2 (parallels istio-base CRDs — no inter-dependency).

- gpu-high-priority (value: 1000) — inference, time-sensitive.
- gpu-batch-priority (value: 500)  — QuanvNN training (default for ML).

Workloads opt in via spec.priorityClassName in their pod template.
QuanvNN ml-batch-job chart will reference gpu-batch-priority in
Sprint 3 (chart values + template wiring).
Sprint 3 will introduce a dataSync initContainer using
public.ecr.aws/aws-cli to s3 sync the QuanvNN dataset from S3 to a PVC
before the main training container starts. Without this allowlist
entry, Kyverno would deny QuanvNN pods at admission time when policy
mode flips to Enforce.

The allowlist addition is conservative: the prefix
public.ecr.aws/aws-cli covers exactly the AWS CLI image and nothing
else under public.ecr.aws. No change to validationFailureAction —
Audit remains until the policy hardening sprint.
Resolves AUDIT_QUANVNN_MVP.md MEDIUM finding — the chart referenced
imagePullSecret.secretName 'ghcr-pull-secret' in job-cpu.yaml and
job-gpu.yaml but no template existed to provision it from AWS Secrets
Manager. Operators had to pre-create the Secret manually.

- New template templates/external-secret.yaml, conditional behind
  .Values.imagePullSecret.enabled (chart default flipped from true
  to false — opt-in is safer for existing consumers).
- Added .Values.imagePullSecret.secretStoreRef (name + kind) — defaults
  to the canonical ClusterSecretStore 'aws-secrets-manager'.
- API version external-secrets.io/v1beta1 — matches platform's pinned
  ESO 0.10.7 and the existing grafana-admin-externalsecret pattern.
- Target Secret type kubernetes.io/dockerconfigjson — matches the
  imagePullSecrets consumer in job templates.
- Schema extended to lock the new secretStoreRef shape.

Existing chart defaults render zero ExternalSecret (verified via
helm template). quanvnn-dev.yaml already opts in (enabled: true).
Resolves PR_41_REVIEW.md F1 + F2 (BLOCKERS).

Without this patch, the two new ApplicationSets shipped by PR #41
(nvidia-device-plugin + priority-classes) would be denied at sync
time by argocd-application-controller:

  F1: 'application repo https://nvidia.github.io/k8s-device-plugin
       is not permitted in project platform' — fixed by appending the
       chart repo to spec.sourceRepos.

  F2: 'cluster-scoped resource PriorityClass.scheduling.k8s.io is not
       permitted in project platform' — fixed by appending an entry
       to spec.clusterResourceWhitelist.

These were silent at chart-render time (helm lint, helm template,
yaml.safe_load all pass). They surface only at ArgoCD sync. A CI gate
diffing every new AS repoURL against the referenced project's
sourceRepos, and every new cluster-scoped GVK against the
clusterResourceWhitelist, would catch this pre-merge — tracked as a
Sprint 3 follow-up in the review report.
@JackMaarek
JackMaarek merged commit 1539df6 into main Apr 26, 2026
6 checks passed
@JackMaarek
JackMaarek deleted the feat/quanvnn-platform-infra-k8s branch April 26, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant