ml

package
v1.801.477 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package ml is model serving: deploy a model behind an endpoint and call it.

The /v1/ml/* routes are a thin, tenant-scoped bridge that turns ONE kserve CustomResource into a small REST API. No ML logic is reimplemented here — kserve owns reconciliation; this subsystem only translates REST <-> the Kubernetes API and enforces tenant isolation.

One resource, one CRUD shape (kserve names are internal/opaque — the user-facing model catalog lives in the hub, never here, so no upstream model identity is ever introduced by this layer):

/v1/ml/models   InferenceService   serving.kserve.io/v1beta1

Plus one leaf surface: POST /v1/ml/models/{name}/predict proxies the request body to the model's kserve v2 data plane (/v2/models/{name}/infer at the InferenceService's cluster-internal address).

TRAINING IS NOT HERE. A /v1/train/* facade over the Kubeflow trainer (TrainJob) and katib (Experiment/Trial) CRDs used to sit beside this, and it is deleted: those CRDs are not served by the cluster, no caller ever created either resource, and the katib facade could not have worked at all (katib's admission webhook requires a namespace label this subsystem never wrote). Per-org model-shape SEARCH is /v1/risk/search, which runs natively in the org's own sandbox; fine-tuning is the hanzoai/ai broker at /v1/finetune/*. One door each — a second, degraded door is worse than none.

Tenancy: every request is scoped to the gateway-minted org (X-Org-Id / c.Org()) narrowed by the org SUB-SCOPE (X-Project-Id / principal.Project), and lands in a PER-ORG(+PROJECT) Kubernetes namespace: "ml-"<org> for the default project (the backward-compatible single-project shape) and "ml-"<org>"-"<project> for a non-default one. The namespace IS the tenant boundary — a tenant physically cannot name into, list, read, mutate or predict against another org's (or project's) resources because the dynamic client is always pinned to the caller's namespace. Both org and project are validated against strict DNS-label regexes (no lossy sanitize), so the (org, project)->namespace map is injective: two distinct scopes can never fold onto one namespace. Empty org is rejected 403 unless the caller is a gateway-minted admin (bucketed under the literal "ml-admin" namespace).

k8s client: built in-process from the in-cluster service account (rest.InClusterConfig) with a KUBECONFIG fallback for local/dev. It is NOT hung off the shared cloud.Deps: a raw Kubernetes client has none of the in-process/ZAP-RPC duality the Deps inter-subsystem clients model, and it is used by exactly this one subsystem — so it stays self-contained here, the same way provisioning builds its own backend clients. When no kubeconfig is resolvable the subsystem mounts anyway and every endpoint fails closed: mutating routes return 503 and the health routes report status "degraded" with the real init error (never a fake success).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mount

func Mount(app cloud.Router, deps cloud.Deps) error

Mount wires the /v1/ml/* surface onto app per HIP-0106. The "compute"-product meter, the k8s client bring-up and the shared fleet registry make this a direct construction (cloud.NewBase), not cloud.Mount.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL