-
Notifications
You must be signed in to change notification settings - Fork 611
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
Add Windows Hostprocess flag #795
Add Windows Hostprocess flag #795
Conversation
bacdd4c
to
98a1c37
Compare
README.md
Outdated
@@ -370,6 +370,7 @@ Security flags: | |||
- :whale: `--cap-add=<CAP>`: Add Linux capabilities | |||
- :whale: `--cap-drop=<CAP>`: Drop Linux capabilities | |||
- :whale: `--privileged`: Give extended privileges to this container | |||
- :blue_square: :nerd_face: `--host-process`: Allow running Host Process containers on Windows. Inherits permissions from containerd process unless `--user` is specified then will start with user specified. The user specified must be present on the host. Requires Containerd 1.6+. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about calling this --isolation=host
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that idea, follows with what folks would be used to for process/hyper-v
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has grown on me overnight. I do have a concern on naming... Right now we call this hostprocess
containers in kubernetes and job
containers in hcsshim and we would be adding another slightly different way of referencing this concept. I think it is a minor difference but thought to bring it up. thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'job containers' name was supposed to be just for the devs on hcsshim as it was what we got accustomed to when referring to it internally, although it does kind of suck that the name leaks out in some error strings. That should maybe get addressed/cleaned up. If that was touched up would that alleviate some of the concern on the three way split @jsturtevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel like the UX is a bit improved if all the Windows folks need to remember is --isolation and its three options vs. --isolation and then an option off to the side that also dramatically reduces the amount of isolation you have. Also might simplify the case where both are specified (--isolation and --host-process) as ideally we should error out if they are as they're conflicting options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a minor concern. Just wanted to call it out. Anytime we refer to the same thing multiple ways it adds complexity to understanding.
That said thinking about hostprocess as an --isolation
resonates with me. and keeps it simple from the cli UX perspective.
This brings up one more thought, As of right now hostprocess doesn't not support hyper-v containers. Is it possible in the future it could? Does that even make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question.. I could imagine a world where we could get it to work, but I'm not sure what use it would bring off the top of my head. I don't know if its worth putting too much brain power into thinking of at the moment though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to make sure we don't back our selves into a naming thing. If it was a thing, would naming for isolation be something like hyperv-host
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're able to specify --isolation twice (e.g. --isolation host --isolation hyper-v
) would that suffice? We'd just need to short circuit on if someone specified process and a second option as that doesn't make sense. Or your idea of a fourth hyperv-host option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds like we have some options. I don't think we need to solve it right now.
The test failed with
I am guessing the containerd process isn't running with high enough privileges in the CI environment as this passes locally with containerd installed with a similar script. @dcantah do you know if there is another built in user we could use here? |
1d5b38f
to
2d1613d
Compare
README.md
Outdated
Isolation flags: | ||
- :whale: :blue_square: :nerd_face: `--isolation=(default|host)`: Used on Windows to change process isolation level. Valid values are `default` and `host`. `default` runs process isolated containers. `host` runs Host Process containers. Host process containers inherit permissions from containerd process unless `--user` is specified then will start with user specified. The user specified must be present on the host. `host` requires Containerd 1.6+. Not implemented for Linux. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't the Docker option for process isolated "process"? I think for Docker Desktop it defaulted to hyper-v if you didn't supply anything, and on server it defaulted to process. Regardless of that we should probably stick to the same naming as docker (unless I missed the discussion for naming this default 😆)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I should probably have process
as an explicit support flag but since hyper-v isn't really support fully in containerd we can default that.
The default
flag uses whatever was set on the docker daemon via --exec-opt isolation=hyperv
option: https://docs.docker.com/engine/reference/commandline/run/#specify-isolation-technology-for-container---isolation
I don't think containerd has this setting but the equivalent would be default_runtime_name
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the logic here. I am not sure if I got it right... There seems to be a couple way to get hyper-v, one by setting the oci spec field hyper-v
to not nil
. Another is to set an option on the shimoptions
needs rebase |
ea27336
to
2437d14
Compare
Added a logging statement for the who the hostprocess container to see what it thinks it is running as and it is coming back as
@dcantah I would think that since it is system it should be able to start |
Yea this is really odd.. The only thing I can think of is there's something blocking logging in users in this environment. The cri-integration tests in Containerd have tests that login as different service accounts https://github.com/containerd/containerd/blob/5162238c7da04d6bdd771d0aa43f8e34c91ea2ca/integration/windows_hostprocess_test.go#L38 |
What's current status? |
2437d14
to
f3af71a
Compare
I refreshed the PR. It is still failing when running in CI though it works locally, I thought it might be a Cirrus vs github actions thing but doesn't look like it. I will need to dig deeper, as it is working locally when I test it. |
debugging a different problem and got some insight from @marosset, It might be because I am not passing the user name info through on the config. going to try that and see I can get this working. better late than never 🙈 |
I think that will fix the issue |
Nice. We didn't allow a blank username for CRI either, right? That's probably the right way.. defaulting to SYSTEM is kinda scary |
Hmm.. if the username string is empty we should error a bit earlier https://github.com/microsoft/hcsshim/blob/6547959343d65e0cf431dd9d589f45ee2b98172c/internal/jobcontainers/logon.go#L109. Maybe it's filling in container-user/container-admin from the image? 🤷♂️ |
The windows tests are passing. Ends up the |
4f0eb6b
to
bebfc3f
Compare
@AkihiroSuda this is finally ready for review. I did move the Windows CI from Cirrus to Github actions during my debugging, I can either drop that commit or move it to a separate PR but I think I prefer GitHub UI for debugging and it aligns better with rest of the tests. |
If Cirrus supports nested virt it might be worth staying on it, otherwise we won't be able to test hyper-v isolation on GHA (unless they made progress on offering this..) |
@@ -395,6 +395,10 @@ Init process flags: | |||
Please make sure the binary exists in your `PATH`. | |||
- Default: `tini` | |||
|
|||
Isolation flags: | |||
- :whale: :blue_square: :nerd_face: `--isolation=(default|process|host)`: Used on Windows to change process isolation level. `default` will use the runtime options configured in `default_runtime` in the [containerd configuration](https://github.com/containerd/containerd/blob/master/docs/cri/config.md#cri-plugin-config-guide) which is `process` in containerd by default. `process` runs process isolated containers. `host` runs Host Process containers. Host process containers inherit permissions from containerd process unless `--user` is specified then will start with user specified and the user specified must be present on the host. `host` requires Containerd 1.6+. Not implemented for Linux. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No support for the Hyper-V mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a separate change, reason being is the way Windows launches the VM in the containerd-shim is a bit different than how it was done for docker (in terms of the resources assigned to the VM). It'd be a bit more than just filling in the hyper-v field on the runtime spec I imagine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was also thinking this would be a separate changeset as the hyper-v support in containerd was only recently added.
I had a couple of suggestions for the usage but overall LGTM |
cmd/nerdctl/run_windows.go
Outdated
switch isolation { | ||
case "host": | ||
hpAnnotations := map[string]string{} | ||
hpAnnotations[hostProcessContainer] = "true" | ||
|
||
// If user is set we will attempt to start container with that user (must be present on the host) | ||
// Otherwise we will inherit permissions from the user that the containerd process is running as | ||
user, err := cmd.Flags().GetString("user") | ||
if err != nil { | ||
return nil, err | ||
} | ||
if user == "" { | ||
hpAnnotations[hostProcessInheritUser] = "true" | ||
} | ||
|
||
opts = append(opts, oci.WithAnnotations(hpAnnotations)) | ||
case "default": | ||
// no op | ||
// use containerd's default runtime options | ||
case "process": | ||
opts = append(opts, WithWindowsProcessIsolated()) | ||
default: | ||
// no op | ||
// use containerd's default | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should combine default and process cases and get rid of the WithWindowsProcessIsolated option as the spec is only going to have that filled in if we set it anyways which would seem like a bug.
switch isolation { | |
case "host": | |
hpAnnotations := map[string]string{} | |
hpAnnotations[hostProcessContainer] = "true" | |
// If user is set we will attempt to start container with that user (must be present on the host) | |
// Otherwise we will inherit permissions from the user that the containerd process is running as | |
user, err := cmd.Flags().GetString("user") | |
if err != nil { | |
return nil, err | |
} | |
if user == "" { | |
hpAnnotations[hostProcessInheritUser] = "true" | |
} | |
opts = append(opts, oci.WithAnnotations(hpAnnotations)) | |
case "default": | |
// no op | |
// use containerd's default runtime options | |
case "process": | |
opts = append(opts, WithWindowsProcessIsolated()) | |
default: | |
// no op | |
// use containerd's default | |
} | |
switch isolation { | |
case "host": | |
hpAnnotations := map[string]string{ | |
hostProcessContainer: "true", | |
} | |
// If user is set we will attempt to start container with that user (must be present on the host) | |
// Otherwise we will inherit permissions from the user that the containerd process is running as | |
user, err := cmd.Flags().GetString("user") | |
if err != nil { | |
return nil, err | |
} | |
if user == "" { | |
hpAnnotations[hostProcessInheritUser] = "true" | |
} | |
opts = append(opts, oci.WithAnnotations(hpAnnotations)) | |
case "default", "process": | |
// no op | |
// use containerd's default runtime options | |
default: | |
return nil, fmt.Errorf("unknown isolation value %q. valid values are 'host', 'process' or 'default'", isolation) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, on docker this flag was defined globally I believe and would error on Linux for an invalid value, should we do some validations for linux as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I remember why I did it this way now.
If the default_runtime
is set in the config.toml
to be hyper-v don't we need to override the default runtime settings? aka, blank out hyper-v part of the spec?
Maybe I don't quite understand it properly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much we could do it seems as hyperv is set in the shim itself if that's the case https://github.com/microsoft/hcsshim/blob/b295b1a866b1263ddede4f00dddf7a129b96c114/cmd/containerd-shim-runhcs-v1/service_internal.go#L109-L116
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, missed that 😬 But there's no point in clearing the spec I think, as if they have runhcs-hypervisor as the default runtime the shim will set the hyperv section back anyways. We're setting all of this up before the shims launched so it seems moot
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But there's no point in clearing the spec I think, as if they have runhcs-hypervisor as the default runtime the shim will set the hyperv section back anyway
So this means if the default runtime is hyperv then you can't run process isolated? I not sure we can handle this from here. doing nothing when process
and hyperv
is the default runtime would be bad experience as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this back... Let me know what you think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait now that I'm thinking about it, isn't the default_runtime_name a CRI field? That shouldn't matter or get read here right? @AkihiroSuda
You can change the runtime as a whole via --runtime (although process, hyperv and LCOW are all wrapped up in the same shim on Windows so it doesn't matter really). The shim options would have to change for this to matter, and it seems like the only runtime whose options are configured is runc https://github.com/containerd/nerdctl/blob/main/cmd/nerdctl/run_runtime.go#L34-L63. But regardless, nil'ing out hyperv is still not needed, as we're the ones controlling the spec here. If the shim ends up setting it for some reason (like here) it's irrelevant what we do here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the shim ends up setting it for some reason (like here) it's irrelevant what we do here
So this means if the default runtime is hyperv
and the user runs nerdctl --isolation process
the user won't get a process isolated container? Or is it only if sim options are set?
great point, It does look like the I will drop this commit. |
a2da3a3
to
8706e3d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after those test renames (and assuming CI is green)
8706e3d
to
2f3aa59
Compare
Sweet! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, could you consider squashing commits
curl.exe -L https://github.com/containerd/containerd/releases/download/v$version/containerd-$version-windows-amd64.tar.gz -o containerd-windows-amd64.tar.gz | ||
tar xvf containerd-windows-amd64.tar.gz | ||
tar.exe xvf containerd-windows-amd64.tar.gz |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not strictly necessary but makes it explicit we are using the tar.exe shipped with Windows vs a powershell alias.
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
ee6d724
to
391bb6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
Fixes: #518
Still needs: