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

Support --pid=container:xxx for nerdctl run cmd #1411

Merged
merged 1 commit into from
Oct 21, 2022
Merged

Support --pid=container:xxx for nerdctl run cmd #1411

merged 1 commit into from
Oct 21, 2022

Conversation

minuk-dev
Copy link
Contributor

@minuk-dev minuk-dev commented Oct 4, 2022

#1293
Signed-off-by: Min Uk Lee minuk.dev@gmail.com

Changes

  • support --pid=container:xxx for nerdctl run command
  • extract generatePIDOpts() function for pid
  • (Updated) update setPlatformOptions()
  • (Updated) add setPlatformContainerOptions() - Details 1
  • (Updated) add PIDContainer label - Details 2

Details

1. add setPlatformContainerOptions()

  • Some functions only works on a specific platform (mostly linux). For persistency, they need to save information into container's labels.
  • Previously, it was processed on runtime. (e.g. hostname, logURI). It caused too many number of withInternalLabels()'s parameters
  • In my opinion, to keep up with it, if the number of retrun values ​​of setPlatformOptions() increase, it would be difficult to maintain the code quality.
  • Therefore, I suggest adding addPlatformContainerOptions().

2. add PIDContainer label

Thanks, but we need to deal with shared container restarts, it will change pid namesapce.

  • For --pid flag's persistency, save the based container's id into the shared container's label.
  • When the container restart, reconfigPIDContainer() will recover it in startContainer()

a difference with docker

  • Because docker supports to isolate a container with a user namespace, it should share user namespace between containers when containers share their pid namespace.
  • But, nerdctl does not support the user ns isolation.

references

cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
Copy link
Member

@junnplus junnplus left a comment

Choose a reason for hiding this comment

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

Thanks, but we need to deal with shared container restarts, it will change pid namesapce.

And please update the doc.

@minuk-dev

This comment was marked as resolved.

@junnplus
Copy link
Member

junnplus commented Oct 4, 2022

Could I get an usecase for it? I could not find it because of my little knowledge.
In my opinion, if containers restart, their namespaces should be reset, isn't it?

You can test restart the base container and then restart the shared container.

cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
@AkihiroSuda AkihiroSuda added this to the v0.23.1 milestone Oct 6, 2022
@minuk-dev minuk-dev changed the title support --pid=container:xxx for nerdctl run cmd WIP: support --pid=container:xxx for nerdctl run cmd Oct 9, 2022
@minuk-dev
Copy link
Contributor Author

Could I get an usecase for it? I could not find it because of my little knowledge.
In my opinion, if containers restart, their namespaces should be reset, isn't it?

You can test restart the base container and then restart the shared container.

I fixed it using labels at 7a6d425.

Summary of updates:

Can you review it again? @junnplus

trivial: I updated the doc of pr. It is marked as updated.

@minuk-dev minuk-dev changed the title WIP: support --pid=container:xxx for nerdctl run cmd Support --pid=container:xxx for nerdctl run cmd Oct 10, 2022
@fahedouch fahedouch self-requested a review October 10, 2022 12:21
cmd/nerdctl/run_linux.go Outdated Show resolved Hide resolved
}

containerName := parsed[1]
walker := &containerwalker.ContainerWalker{
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to find again?

cOpts = append(cOpts, containerd.WithAdditionalContainerLabels(map[string]string{
labels.PIDContainer: containerName,
}))
Copy link
Member

Choose a reason for hiding this comment

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

We already have withInternalLabels, should be put together

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When a new label is needed, the best way is to add a new parameter of withInternalLabels()?
And if so, --pid flags is processed in setPlatformOptions(). In order to pass into the withInternalLabels(), the number of setPlatformOptions()'s return value should be increased.

Copy link
Member

Choose a reason for hiding this comment

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

When a new label is needed, the best way is to add a new parameter of withInternalLabels()?

Uniformity is better than fragmentation.

Copy link
Member

Choose a reason for hiding this comment

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

And if so, --pid flags is processed in setPlatformOptions().

I think the --pid flags should be platform independent, why not consider moving it out of setPlatformOptions?

Copy link
Contributor Author

@minuk-dev minuk-dev Oct 18, 2022

Choose a reason for hiding this comment

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

Previsouly, --pid only works on linux.

pidNs = strings.ToLower(pidNs)
if pidNs != "" {
if pidNs != "host" {
return nil, fmt.Errorf("invalid pid namespace. Set --pid=host to enable host pid namespace")
} else {
opts = append(opts, oci.WithHostNamespace(specs.PIDNamespace))
if rootlessutil.IsRootless() {
opts = append(opts, withBindMountHostProcfs)
}
}

The reason, why it only works on the linux, is that it's too sensitive with namespace suppport.

nerdctl/cmd/nerdctl/run.go

Lines 1184 to 1187 in d15ada7

ns := specs.LinuxNamespace{
Type: specs.PIDNamespace,
Path: fmt.Sprintf("/proc/%d/ns/pid", task.Pid()),
}

// WithHostNamespace allows a task to run inside the host's linux namespace
func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		setLinux(s)
		for i, n := range s.Linux.Namespaces {
			if n.Type == ns {
				s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
				return nil
			}
		}
		return nil
	}
}

To avoid a compile error, I placed reconfigPIDContainer() in cmd/nerdctl/start.go but I think it caused confusing.
So, I added a condition to check runtime os now.

if runtime.GOOS != "linux" {

Anyway, in my opinion, --pid currently can work on linux only.
Because of it, --pid should be processed in setPlatformOptions(). But, I really agree with you. setPlatformContainerOptions() can make a fragmentation and cause to find a target container twice.
I tried to find a better way to improve it according to your review, but I couldn't. I'm really sorry.


I think the --pid flags should be platform independent, why not consider moving it out of setPlatformOptions?

And I don't understand how to move it out?

Copy link
Member

Choose a reason for hiding this comment

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

The PID namespace (as well as other namespaces) is specific to Linux.
I don't think it will ever be platform-independent in the foreseeable future.

Copy link
Member

@junnplus junnplus left a comment

Choose a reason for hiding this comment

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

Please squash commits

Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

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

Thanks

@minuk-dev
Copy link
Contributor Author

Thanks

I'm sorry that I didn't apply reviews from jun. I'm looking forward the better way than setplatformcontaineropts().
In my opinion, that's too hard to me now.
So, could you decide how to deal with this pr (e.g. because of low code quality, just close).
If pr is closed, then I'll try to improve the quality and retry pr.

Copy link
Member

@junnplus junnplus left a comment

Choose a reason for hiding this comment

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

Sorry, no LGTM, I guess the code can be optimized again.

cOpts = append(cOpts, containerd.WithAdditionalContainerLabels(map[string]string{
labels.PIDContainer: containerName,
}))
Copy link
Member

Choose a reason for hiding this comment

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

And if so, --pid flags is processed in setPlatformOptions().

I think the --pid flags should be platform independent, why not consider moving it out of setPlatformOptions?

- Add context and client to `setPlatformOptions()`
- Add branch for platform-specific container opts
- Add PIDContainer label into container's labels. It only works on linux
platform.
- Add reconfigPIDContainer() into container's start process. It recovers
the pid namespace from its PIDContainer label.

Signed-off-by: Min Uk Lee <minuk.dev@gmail.com>
@AkihiroSuda
Copy link
Member

@junnplus LGTY?

@AkihiroSuda
Copy link
Member

Let me merge this, as I don't think the --pid flag can be platform-independent in the foreseeable future, but please feel free to submit follow-up issues/PRs.

Thank you @minuk-dev @junnplus 👍

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.

None yet

4 participants