GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — WIP: Fix userns-remap with containerd image store by vvoland · Pull Request #54146 · moby/moby

Conversation

@vvoland

@vvoland vvoland commented Nov 6, 2026

Copy link
Copy Markdown
Contributor
  • fix: Unable to build a simple Dockerfile with buildx where userns-remap and the containerd backend is enabled #47377

Summary

With userns-remap, the daemon disabled the containerd image store because BuildKit builds failed with it.
The store itself handled remapping poorly too: layers were unpacked with container IDs, and the whole rootfs was chowned on every container create.
With overlayfs, that copied every image file into each container's upper dir.
It also left setuid binaries owned by host root in the snapshots.

This stores layers with the remapped host IDs like the graph drivers do:

  • With userns-remap, the daemon's containerd client uses a diff service that runs containerd's fs applier and walking differ in-process with ID mapping options.
    Applying a layer maps its owners to host IDs, and creating one maps them back to container IDs.
    Pulls, loads, commits and classic builds all go through it, and containers use image snapshots without any chown.
  • BuildKit's containerd worker gets the same diff service and a snapshotter with the ID mapping, so RUN steps work and exported layers keep container IDs.

The commits marked "(temporary)" patch vendored containerd and BuildKit:

  • containerd: archive and diff ID mapping options (apply to host IDs, write diffs back to container IDs, v3 file caps converted to v2).
  • BuildKit: map IDs in layers the cache manager computes without the differ (the overlay differ, and zstd/estargz/nydus or custom gzip levels).

These will be replaced by vendor bumps once the changes land upstream.

Release notes (optional)

Support the containerd image store with `--userns-remap`. New daemons with user namespace remapping now use the containerd image store by default.

A picture of a cute animal (not mandatory but encouraged)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
vvoland added 7 commits November 6, 2026 02:06
@vvoland
vendor: Draft containerd archive ID mapping options (temporary)
483e2e6
Draft of a containerd change to apply and write layer archives for a
user namespace remapped storage, so that snapshots can keep the
remapped host IDs while layers keep the container IDs.

Add archive.WithApplyIDMapping, which maps the owners of the entries
to the host IDs before they are created, and makes the root user of
the mappings own the root directory, which archives do not change, and
the parent directories created without attributes to inherit.
Add archive.WithWriteDiffIDMapping and
archive.WithChangeWriterIDMapping, which map the owners of the entries
back to the container IDs, keep whiteouts owned by ID 0, and convert
version 3 file capabilities, which store the host ID of the user
namespace root, to version 2.
Apply and WriteDiff refuse the mapping with custom apply and diff
functions, such as the Windows layer ones.
Add IDMap.ToContainer to the internal userns package.

This patches the vendored containerd until the change lands upstream.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
vendor: Draft containerd diff ID mapping options (temporary)
b40c42f
Draft of a containerd change to pass user namespace mappings to the
diff appliers and comparers, through the existing option plumbing of
unpacking and diffing.

Add diff.WithApplyIDMapping and diff.WithIDMapping, with the mappings
in ApplyConfig and Config.
The file system applier and the walking differ pass them to the
archive package.
The diff service proxy refuses them with ErrNotImplemented, as the
diff service API has no fields for them yet, and an older daemon would
ignore them.

This patches the vendored containerd until the change lands upstream.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
daemon/containerd: Store layers with the remapped IDs with userns-remap
1829e21
With userns-remap, the containerd image store unpacked layers with
their container IDs, and chowned the whole rootfs to the remapped IDs
when creating a container.
With overlayfs, the chown copied every file of the image up into the
upper directory of each container, and committing a container copied
its whole rootfs again to map the IDs back.
The image snapshots also kept files owned by host root, including
setuid binaries, protected only by the permissions of the snapshotter
directories.

Store layers with the remapped IDs instead, as the graph drivers do.
With userns-remap, the daemon's containerd client uses a diff service
which runs containerd's file system applier and walking differ in the
daemon process with the ID mapping options, as the containerd diff
service API does not take them.
Applying a layer maps the owners of its files to the host IDs, and
creating a layer maps them back to the container IDs.
All unpacks and diffs of the client, such as pulls, loads, commits
and classic builds, go through it.
Containers use the image snapshots as they are, and commits diff the
container snapshot directly.
Archives never change the root directory of a snapshot, so the applier
and the snapshots prepared without a parent make it owned by the
remapped root.

The daemon disables the containerd image store with userns-remap, so
no existing setups depend on the previous layout.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
vendor: Patch BuildKit to map IDs of layers it computes itself (tempo…
67a588f
…rary)

With a snapshotter with an ID mapping, BuildKit computed some layers
without the worker's differ, so they kept the remapped host IDs of the
snapshots: with the overlay differ, and for layers compressed with
zstd, estargz or nydus, or with a custom gzip level.

Patch the vendored BuildKit to map the owners of the tar entries back
to the container IDs of the snapshotter's ID mapping in both paths,
before compressing them and computing the diffID.

This is a temporary patch to validate the BuildKit change, which has
to land upstream instead.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
builder-next: Fix build steps with userns-remap and the containerd store
d5af3fb
With userns-remap and the containerd image store, BuildKit failed to
run build steps with errors like:

    error mounting ".../buildkit/executor/resolv.conf" to rootfs at "/etc/resolv.conf": ... permission denied

The containerd worker applied and created layers with the containerd
diff service, and its snapshotter had no ID mapping, so the rootfs of
build steps kept the container IDs, which the remapped root cannot
access.

Give the containerd worker the remapped diff service and snapshotter
of the image service, and the ID mapping, so that its snapshots have
the remapped IDs like the image snapshots they share, and file
operations, mounts and the layers it computes itself map the IDs.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
daemon/command: Allow the containerd image store with userns-remap
1fcd32d
With userns-remap, the daemon disabled the containerd image store, and
refused to start when it was explicitly enabled, because BuildKit
failed to run build steps with it.

The containerd image store now stores layers with the remapped IDs,
and BuildKit builds and exports layers with them, so remove the
restriction.
With userns-remap, the daemon picks the image store as without it: a
remapped root with graph driver data keeps using the graph driver, and
a new one uses the containerd image store.
Migrating to the containerd image store is still refused.

Remove the workaround of test daemons which set the overlay2 storage
driver with userns-remap, and run the tests skipped with userns-remap
because of the restriction.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
ci: Test userns-remap with the containerd image store
945ac25
The userns mode only ran with graph drivers, as userns-remap disabled
the containerd image store.
Run the integration tests in the userns mode with the containerd image
store too, and the integration-cli suites which pull and push images,
as the containerd image store remaps image layers when unpacking and
creating them.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland vvoland self-assigned this Nov 6, 2026
@github-actions github-actions Bot added area/builder Build area/builder/buildkit Build area/ci area/testing containerd-integration Issues and PRs related to containerd integration labels Nov 6, 2026
@vvoland vvoland added area/security/userns kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. and removed area/testing area/ci area/builder Build labels Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@vvoland vvoland

Labels

area/builder/buildkit Build area/security/userns containerd-integration Issues and PRs related to containerd integration kind/enhancement Enhancements are not bugs or new features but can improve usability or performance.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Unable to build a simple Dockerfile with buildx where userns-remap and the containerd backend is enabled

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@vvoland
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.