Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for userns #3941

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Shubhranshu153
Copy link
Contributor

Adds support for running containers with custom user namespace mappings through
the --userns flag in 'run' and 'create' commands.

Key Features:

  • Parse and utilize UID/GID mappings from /etc/subuid and /etc/subgid
  • Support multi-entry mappings for user namespace configurations
  • Integrate with containerd's remapping capabilities

Technical Details:

  • Depends containerd.WithUserNSRemapperLabels for namespace configuration. So containerd mainline is required to compile. It can be run on containerd 1.7 if snapshotter support remap-ids.
  • For native snapshotter overlay snapshotter with remapping support is added in containerd 2.x (>2.0.x)

Dependencies:

  • Requires containerd with UserNSRemapperLabels support
  • Compatible with overlay snapshotter in containerd mainline

Testing:

  • Added unit tests for mapping configurations
  • Added integration tests for container isolation

This enhancement improves container isolation by providing
flexible user namespace mapping capabilities.

Size: XL

Signed-off-by: Shubharanshu Mahapatra <[email protected]>
Setup: func(data test.Data, helpers test.Helpers) {
data.Set("validUserns", "nerdctltestuser")
data.Set("expectedHostUID", "123456789")
// need to be compiled with containerd version >2.0.2 to support multi uidmap and gidmap.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change comment to 2.1.x

return nil
}

func addUser(username string, hostId string) error {
Copy link
Member

@AkihiroSuda AkihiroSuda Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is scary to run by default. Needs to have an opt-in flag like -test.allow-modify-user

Similar:

flag.BoolVar(&flagTestKillDaemon, "test.allow-kill-daemon", false, "enable tests that kill the daemon")

}

newContent := strings.ReplaceAll(string(content), entry, "")
if err := os.WriteFile(file, []byte(newContent), 0644); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is scary too. Needs to be opt-in.

Also, the content of /etc/subuid and /etc/subgid has to be backed up and has to be restored with defer()

}

func delUser(username string) error {
cmd := exec.Command("sudo", "userdel", username)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sudo shouldn't be needed when the test is running as the root

github.com/containerd/cgroups/v3 v3.0.5
github.com/containerd/console v1.0.4
github.com/containerd/containerd/api v1.8.0
github.com/containerd/containerd/v2 v2.0.2
github.com/containerd/containerd/v2 v2.0.1-0.20250211161307-525332b29211
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to cherry-pick the relevant commit to v2.0?

@@ -264,6 +264,9 @@ type ContainerCreateOptions struct {

// ImagePullOpt specifies image pull options which holds the ImageVerifyOptions for verifying the image.
ImagePullOpt ImagePullOptions

// Userns name for user namespace mapping of container
Userns string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Userns string
UserNS string

Because Userns looks like Users

@@ -185,6 +185,27 @@ func Create(ctx context.Context, client *containerd.Client, args []string, netMa
opts = append(opts, rootfsOpts...)
cOpts = append(cOpts, rootfsCOpts...)

if options.Userns != "" {
if runtime.GOOS != "linux" || rootlessutil.IsRootless() {
return nil, generateRemoveStateDirFunc(ctx, id, internalLabels), errors.New("userns is only supported on linux")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is confusing when running in rootless mode on linux

@@ -279,6 +279,7 @@ func setCreateFlags(cmd *cobra.Command) {
cmd.Flags().String("ipfs-address", "", "multiaddr of IPFS API (default uses $IPFS_PATH env variable if defined or local directory ~/.ipfs)")

cmd.Flags().String("isolation", "default", "Specify isolation technology for container. On Linux the only valid value is default. Windows options are host, process and hyperv with process isolation as the default")
cmd.Flags().String("userns", "", "Support idmapping of containers. This options is only supported on linux. If `host` is passed, no idmapping is done. if a user name is passed, it does idmapping based on the uidmap and gidmap ranges specified in /etc/subuid and /etc/subgid respectively")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add docs/command-reference.md.

Also, the command line seems incompatible with Docker?
Docker doesn't accept a username here, and the name is hardcoded to "dockremap".
Maybe we should have its equivalent as "nerdremap"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Podman accepts --subuidname string --subgidname string to specify a custom user name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants