Mount the publish image¶
A job saves and resolves checkpoints with go/dispatch's publish binary, which the job's own
command runs. The training image stays yours, so the adapter delivers the binary separately, to
/opt/dispatch/publish in the trainer container, by one of two routes.
The image that holds the binary, registry.gitlab.com/phpboyscout/go/dispatch/publish, is described
in go/dispatch's publish image reference:
its tags, its layout and how to read a release's digest. This page does not repeat it.
Route 1: an image volume (the default)¶
Set publish.image to the image, pinned by digest:
{
"publish": {
"image": "registry.gitlab.com/phpboyscout/go/dispatch/publish@sha256:<64 hex digits>"
}
}
A reference with a tag, or without @sha256: and 64 lower-case hex digits, is refused when the
settings are parsed.
For each job, the adapter's runtime patch then adds a volume named dispatch-publish with an
image source, pullPolicy: IfNotPresent, and mounts it read-only on the node container at
/opt/dispatch. The image holds one file at its root, so the binary is at /opt/dispatch/publish.
Requirements:
- Kubernetes with image volumes enabled. They are on by default in 1.37, the version tested, and need no configuration there.
- A container runtime that mounts them without
noexec. This was observed with containerd on kind; on other runtimes, test it. - Nodes that can pull the image.
Refer to the binary by its full path in the job's command:
/opt/dispatch/publish resolve -checkpoint "$CKPT"
/opt/dispatch/publish watch -checkpoint "$CKPT" -framework hf &
Route 2: an init container your runtime defines¶
Where image volumes are unavailable, set publish.via to initContainer:
{
"publish": {
"image": "registry.gitlab.com/phpboyscout/go/dispatch/publish@sha256:<64 hex digits>",
"via": "initContainer",
"initContainer": "dispatch-publish"
}
}
initContainer is the name of an init container that the runtime must already define. Its
default is dispatch-publish. A runtime patch cannot set a container's image, so the image of that
init container is whatever the runtime says, and publish.image is checked for its shape but not
placed on the pod. Because the publish image has no shell and no cp, the init container's image
needs a copy tool. The test harness's dispatch-kind-init runtime shows the shape of the runtime
side only: its init container runs true and copies nothing.
This route has not been run end to end. The kind suite checks that Start refuses a runtime
without the named init container, and its preflight probe creates a gated TrainJob with the init
container's patch on dispatch-kind-init, but no pod on this route has ever started and found the
binary. Test it on your cluster before you rely on it.
For each job, the adapter's runtime patch:
- adds an
emptyDirvolume nameddispatch-publish; - sets
DISPATCH_PUBLISH_DEST=/opt/dispatchon the named init container and mounts the volume there; - mounts the volume read-only on the
nodecontainer at/opt/dispatch.
Your init container must copy the binary to $DISPATCH_PUBLISH_DEST, as publish, so that the job
still finds it at /opt/dispatch/publish.
Trainer does not check that the init container exists: a patch naming a missing one is accepted and
the job then holds quota with no pods. The adapter therefore checks the runtime itself, and
Start refuses a runtime without the named init container with ErrUnsupported, before creating
anything. See runtime requirements.
Things to avoid¶
- No credential may be mounted at or under
/opt/dispatch. Acredentials[].mountPaththat overlaps it is refused when the settings are parsed. initContaineris only valid withvia: initContainer. Naming it under the default route is refused.- Publishing is optional. With no
publishsection the adapter mounts nothing at/opt/dispatch.
Configuration reference lists the publish keys.