Skip to content

feat(atelet): pull actor images with dockerconfigjson Secrets - #540

Merged
teemow merged 3 commits into
giantswarmfrom
fork/atelet-dockerconfig-keychain
Oct 23, 2026
Merged

teemow merged 3 commits into
giantswarmfrom
fork/atelet-dockerconfig-keychain

Conversation

@teemow

@teemow teemow commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Problem

atelet pulls an actor's image itself, with the kubelet credential providers of its node (--image-credential-provider-config) or anonymously. There is no imagePullSecret path: a registry that hands out static credentials needs a provider binary on every node just to read a username and a password, and a cluster whose node image cannot change cannot pull a session's private tool images at all.

Proposed solution

The cherry-pick (-x) of the upstream-ready commit on branch upstream/atelet-dockerconfig-keychain:

  • atelet reads .dockerconfigjson files (a kubernetes.io/dockerconfigjson Secret's content) through the repeatable --image-pull-secret-file flag. Credentials are matched like the kubelet matches a Pod's imagePullSecrets (the same URL globbing, most specific key first, Docker Hub's aliases folded onto index.docker.io) and tried before the credential providers', as the kubelet tries pull secrets before the node's credentials (credentialprovider.Chain).
  • Every lookup re-reads the files, so a rotated Secret takes effect without a restart; a file that does not parse at start-up is fatal, one that goes bad later is logged and skipped.
  • Chart value atelet.imagePullSecrets ([{name: <secret>}], release namespace): each Secret mounted read-only at /run/image-pull-secrets/<name> (no subPath, so rotation reaches the pod) and passed as a flag. Separate from imagePullSecrets, which pull the chart's own pods.
  • No persisted format changes: nothing is stored, no migration needed.

Acceptance criteria

  • Unit tests: go test -race ./cmd/atelet/internal/credentialprovider/ (matching, auth decoding, file order and dedup, colliding keys, rotation, bad files, chain order) and go test -run TestHelm ./cmd/atelet/ (flags, mounts, volumes, a nameless entry refused).
  • The default render of the substrate chart is byte-identical to giantswarm's: inert until a consumer sets the value.
  • golangci-lint clean on ./cmd/atelet/....
  • Ledger file fork/atelet-dockerconfig-keychain.md (to-file, branch upstream/atelet-dockerconfig-keychain); ledger-header.sh --complete clean.

@teemow
teemow requested a review from a team as a code owner October 23, 2026 09:32
atelet pulls an actor's image itself, with the kubelet credential
providers of its node or anonymously. A registry that hands out static
credentials, as most private registries do, needs a provider binary on
every node just to read a username and a password, and a cluster whose
node image cannot be changed has no way to pull from it at all.

atelet now also reads .dockerconfigjson files, the content of a
kubernetes.io/dockerconfigjson Secret, through the repeatable
--image-pull-secret-file flag. Their credentials are matched to an image
like the kubelet matches a Pod's imagePullSecrets (the same URL globbing,
most specific key first, Docker Hub's aliases folded onto index.docker.io)
and are tried before the credential providers', as the kubelet tries a
Pod's pull secrets before the node's credentials. Every lookup reads the
files again, so a rotated Secret takes effect without a restart; a file
that does not parse at start-up is fatal, one that goes bad later is
logged and skipped.

The chart's atelet.imagePullSecrets takes the Secrets by name
([{name: ...}]), mounts each one read-only and passes its file. It is
separate from imagePullSecrets, which pull the chart's own pods.

Signed-off-by: Timo Derstappen <teemow@gmail.com>
(cherry picked from commit 999409c)
Signed-off-by: Timo Derstappen <teemow@gmail.com>
Signed-off-by: Timo Derstappen <teemow@gmail.com>
@teemow
teemow force-pushed the fork/atelet-dockerconfig-keychain branch from efefc7f to 0cc0a45 Compare October 23, 2026 09:55
@teemow
teemow merged commit c076823 into giantswarm Oct 23, 2026
20 checks passed
@teemow
teemow deleted the fork/atelet-dockerconfig-keychain branch October 23, 2026 10:13
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