Skip to content

[Feature]: MONAI Label deployment in the Kubernetes trust chart - #950

Merged
atriaybagur merged 1 commit into
947-publish-monailabel-image-prod-composefrom
948-k8s-monailabel-deployment
Aug 12, 2026
Merged

[Feature]: MONAI Label deployment in the Kubernetes trust chart#950
atriaybagur merged 1 commit into
947-publish-monailabel-image-prod-composefrom
948-k8s-monailabel-deployment

Conversation

@atriaybagur

@atriaybagur atriaybagur commented Aug 12, 2026

Copy link
Copy Markdown
Member

Description

Adds the optional MONAI Label server to the Kubernetes trust chart, mirroring the compose deployment. Stacked on #949 (merge order: #945#949 → this; GitHub retargets on each merge).

  • templates/monailabel.yaml — Deployment + Service + weights PVC + scoped NetworkPolicy, all gated on monailabel.enabled (default false; the default render is byte-identical bar a comment-only document).
  • Archive access: read-only mount of xnat-web's data PVC (archive subPath). With the default ReadWriteOnce storage the pod is pinned to xnat-web's node via required podAffinity (coScheduleWithXnat: true); RWX storage classes can turn that off.
  • monailabel.publicUrl is required when enabled: XNAT hands it to the OHIF viewer, which calls it from the clinician's browser — never proxied — so the chart cannot derive it and a wrong default fails only at click time. CI asserts the guard fires.
  • Exposure: NodePort (default 30030) + a NetworkPolicy opening exactly that port on exactly this pod through the namespace's default-deny ingress. The API is unauthenticated (matches the compose posture, where the port is host-published) — documented, restrict at the network layer.
  • CI: render coverage added to the helm-template job (enabled render asserts resources exist; a render without publicUrl must fail). Deliberately not in ci/test-values.yaml — the kind job installs those values and waits for pod readiness, which a ~10.4 GB GPU image can never satisfy in kind.
  • Unlike the compose trust, the chart's XNAT already ships the ohif-viewer plugin in its roster, so there is no plugin step and no trust XNAT: bulk image-pull wedges permanently — Reactor EventBus ring-buffer livelock (OHIF listener) + restart strands directArchive #662 exclusion decision here.

Linked Issues

Fixes #948

Checklist

  • Follows the project's coding conventions and style guide
  • Updates documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Type of Change

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • New tests added to cover the changes.

Testing

Additional Notes

Live K8s verification (register → deepedit_seg/sam_2d masks in the viewer) is the remaining acceptance criterion on #948 and should follow once #949's image is published.

Acceptance Criteria

Imported from issue #948

  • helm lint and helm template pass with monailabel.enabled=true (CI values) and default values.
  • With monailabel.enabled=false (default) the rendered chart is unchanged.
  • On a GPU node with the trust chart deployed: server registers with XNAT, deepedit_seg and sam_2d produce masks in the OHIF viewer against archive data.

Follow-up to #55 / PR #945. Depends on the published image from the image-publishing issue.

Mirrors the compose overlay: Deployment + Service + weights PVC, gated on
monailabel.enabled (default false — the default render is proven unchanged,
comment-only delta). The chart's XNAT already ships the ohif-viewer plugin in
its roster, so unlike compose there is no plugin step and no FLIP#662
exclusion to weigh here.

Chart-specific decisions:

- The XNAT archive is read straight off xnat-web's data PVC (read-only
  `archive` subPath). That PVC is ReadWriteOnce by default, so the pod is
  pinned to xnat-web's node via required podAffinity
  (monailabel.coScheduleWithXnat, default true); RWX storage classes can
  disable it.
- monailabel.publicUrl is `required` when enabled rather than defaulted: XNAT
  hands it to the OHIF viewer, which calls it from the clinician's browser —
  the chart cannot derive an outside-the-cluster URL, and a wrong default
  fails only at click time. The helm-template CI job asserts the guard fires.
- Exposed as NodePort (default 30030) plus a scoped NetworkPolicy opening
  exactly that port on exactly this pod through the namespace's default-deny
  ingress (service.allowExternalIngress).
- Startup probe allows 30 minutes: first start on a cold volume downloads
  pretrained weights including the ~900MB SAM checkpoint.
- Render coverage lives in the helm-template job, NOT ci/test-values.yaml:
  the kind install deploys those values and waits for pod readiness, which a
  ~10.4GB GPU image can never satisfy there.

Signed-off-by: at24_bioeng625-pc <alexandre.triay_bagur@kcl.ac.uk>
@github-actions github-actions Bot changed the title Add optional MONAI Label deployment to the Kubernetes trust chart [Feature]: MONAI Label deployment in the Kubernetes trust chart Aug 12, 2026
@github-actions

Copy link
Copy Markdown

✅ Acceptance criteria have been automatically imported from the linked issue(s) and added to the PR description.

@atriaybagur
atriaybagur marked this pull request as ready for review August 12, 2026 14:32
@atriaybagur
atriaybagur merged commit 54c1caf into 947-publish-monailabel-image-prod-compose Aug 12, 2026
6 of 7 checks passed
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