Set up S3 checkpoint credentials¶
A job whose checkpoint is an s3://bucket/prefix URL publishes its checkpoints with go/dispatch's
publish helper. The helper needs credentials. dunscaith keeps them out of the job script and the
job's environment: the script carries only a reference to where the credentials are, and the helper
reads them there.
Not wired in this build
This build has no cluster adapter, so it cannot generate a job script. s3 login and s3 secret
work, and checkpoint.s3.credentials is validated against the schema, but nothing yet turns the
setting into the helper's -creds argument. Set these up now and they will apply when the
adapter lands.
Credential sources¶
checkpoint.s3.credentials is an ordered list. The helper tries each source in turn. There are
three kinds:
| Kind | Reads credentials from | Use when |
|---|---|---|
file |
~/.config/dunscaith/s3/<profile>/ |
Your home is visible to the compute nodes. This is the default. |
secret |
A directory a Kubernetes Secret is mounted at | Jobs run in pods. |
vault |
A HashiCorp Vault path | Your site runs Vault. |
If you set nothing, the list is [{kind: file, profile: default}].
Write a file source with s3 login¶
--store is the checkpoint root dunscaith probes with the credentials once they are written. If
you always publish to the same root, set it once in configuration and leave --store off:
--store overrides checkpoint.s3.root. With neither, s3 login stops before asking for
anything. It prompts for each value, without echoing the secrets:
access_key_id: ...
secret_access_key:
session_token (optional):
endpoint (optional):
region (optional):
It then writes ~/.config/dunscaith/s3/default/, directory mode 0700, one file per value with mode
0600, and probes the store: a conditional write, a rewrite and a delete under the root. It prints
wrote <dir> and probed <store>.
Use --profile <name> for more than one set of credentials. A profile name is letters, digits,
., _ and -, up to 64 characters, starting with a letter or digit.
If an existing profile is readable by anyone but you, or holds a file it should not, s3 login
refuses before it asks for anything. Fix the modes (chmod 0700 the directory, chmod 0600 the
files) and rotate the keys if others could have read them. If the probe fails, the profile stays
written, and the error names the store that refused it.
Without a terminal¶
s3 login needs a terminal to prompt. In a script, name the environment variables that hold each
value with --from-env field=VARIABLE:
dunscaith s3 login --store s3://my-bucket/checkpoints \
--from-env access_key_id=AWS_ACCESS_KEY_ID,secret_access_key=AWS_SECRET_ACCESS_KEY
The fields are access_key_id and secret_access_key (both required), and session_token,
endpoint and region (optional). A required variable that is unset or empty is an error.
Put the credentials in Kubernetes with s3 secret¶
If jobs run in pods, copy a file profile into a Secret. dunscaith runs your own kubectl with your
own kubeconfig; it links no Kubernetes client.
This renders the Secret from the profile directory (kubectl create secret generic ... --dry-run)
and applies it. The values reach kubectl as file paths, so none is on a command line. The Secret is
named dunscaith-s3-<profile>. The command then prints the volume and mount your worker or job pods
need, which you must add yourself:
volumes:
- name: dunscaith-s3-default
secret:
secretName: dunscaith-s3-default
defaultMode: 0400
containers:
- volumeMounts:
- name: dunscaith-s3-default
mountPath: /var/run/secrets/dunscaith/s3/default
readOnly: true
The mount path is /var/run/secrets/dunscaith/s3/<profile>. The command also prints, as YAML ready
to paste into your configuration, the secret source that names it:
--profile chooses the file profile to copy. On a Soperator site add --soperator: the command then
warns that a Secret mounted on shared worker pods is readable by every job there, so treat it as a
team credential.
Vault sources¶
With Kubernetes auth, the job's pod presents its service-account token and logs in under role:
checkpoint:
s3:
credentials:
- kind: vault
addr: https://vault.example.org:8200
auth: kubernetes
role: training
path: s3/training
With AppRole, the helper reads role_id and secret_id from files in approleDir, a directory
the compute nodes see. Keep it as private as a file profile (0700, files 0600): on bare-metal Slurm
it is no stronger than a file source.
checkpoint:
s3:
credentials:
- kind: vault
addr: https://vault.example.org:8200
auth: approle
approleDir: /home/you/.config/dunscaith/vault
mount: kv
path: s3/training
addr is http(s)://host[:port] with no path. mount is the KV v2 mount, secret when left
out, and path is the secret's path within it: s3/training, not secret/data/s3/training.
kubernetes needs role and takes no approleDir; approle needs approleDir and takes no
role.
The job script carries the source as the publish helper's location, for example
vault:https://vault.example.org:8200/s3/training?approle=%2Fhome%2Fyou%2F.config%2Fdunscaith%2Fvault&auth=approle&mount=kv.
Reach S3 or Vault through a proxy¶
The publish helper ignores HTTPS_PROXY, HTTP_PROXY and NO_PROXY in the job's environment and
connects directly. If your compute nodes reach the store or Vault only through a proxy, name it in
configuration, separately for each:
checkpoint:
s3:
proxy: http://proxy.example.org:3128
credentials:
- kind: vault
addr: https://vault.example.org:8200
auth: kubernetes
role: training
path: s3/training
proxy: http://proxy.example.org:3128
checkpoint.s3.proxy is the store's, and reaches the helper as -proxy http://proxy.example.org:3128.
A vault source's proxy is for that Vault server only, and joins its location as
proxy=http%3A%2F%2Fproxy.example.org%3A3128. Leave either out to connect directly. file and
secret sources make no network call and take no proxy.
A proxy is http:// or https://, a host and an optional port. A user name or password in it is
refused, because it would be written into the job script; use a proxy that admits the compute
nodes by address. There is no exclusion list: a proxy named is used for every request to that
server.
s3 login probes the store from the login node, not from a compute node, and ignores the proxy
variables in its own environment too. If the login node reaches the store only through a proxy,
name that one separately; it is used for the probe and never written into a job:
It follows the same form rule as the others. Leave it out and the probe connects directly, even
when checkpoint.s3.proxy is set.
Rules the setting follows¶
- A
filesource takes onlyprofile; asecretsource onlypath; avaultsourceaddr,auth,path,mount,proxy, androleorapproleDiras itsauthneeds. Any other key is refused. - A
secretsource'spathand avaultsource'sapproleDirmust be absolute and contain no,. Each is the path as the compute node sees it. - A source may not repeat. An empty list is refused; leave the key out for the default.
Run the files and checks above on a machine where $HOME is the same directory the compute nodes
see, or the file source will point at a path they cannot read.