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
Linux containers on FreeBSD #7000
Conversation
Hi @akhramov. Thanks for your PR. I'm waiting for a containerd member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
0e57bf3
to
6726a95
Compare
oci/spec_opts.go
Outdated
//FreeBSD has support for running Linux binaries via syscall redirection, while that would be enough | ||
//for some binaries others depend on emulated linux file systems (procfs & sysfs). | ||
//So when we are running FreeBSD and our image OS is Linux we modify our mounts to mount the emulated | ||
//filesystems. | ||
//We do it here since here we have access to both the OCI spec & the image OS. | ||
if runtime.GOOS == "freebsd" && ociimage.OS == "linux" { | ||
freebsdLinuxEmulationMounts(s) | ||
} |
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.
Carrying over the comment I left on the previous PR:
I'd like to see this extracted out into a function like appendOSMounts
, which is then separately defined in each of spec_opts_freebsd.go
/spec_opts_linux.go
/spec_opts_windows.go
with whatever content is appropriate there. The Linux one would likely be empty, but I imagine there could be some use for this on Windows with the LCOW/WCOW work.
In addition to providing a possibly-reusable abstraction for FreeBSD and Windows to achieve similar goals, an advantage is keeping FreeBSD-specific filesystems like "linprocfs" and "linsysfs" out of the common file that is compiled for all operating systems.
I'd also like to see a WithLinuxEmulationMounts
functional option that clients of containerd can use without having to use WithImageConfig
/WithImageConfigArgs
or even having an image with a declared OS of "linux".
If you're not interested in doing that work, I can pick up and carry this PR.
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'd like to see this extracted out into a function like appendOSMounts
That makes a lot of sense, implemented. As for WithLinuxEmulationMounts
I'm not that familiar with the codebase yet, so I would defer it to you
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 works for me, I can pick up WithLinuxEmulationMounts
in a follow-up PR.
platforms/defaults_freebsd.go
Outdated
// The Variant field will be empty if arch != ARM. | ||
Variant: cpuVariant(), | ||
}) | ||
} |
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.
nit: can you add a newline at the end of this file?
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.
Nice catch, thanks!
6726a95
to
6487912
Compare
@@ -377,6 +377,7 @@ func WithImageConfigArgs(image Image, args []string) SpecOpts { | |||
return fmt.Errorf("unknown image config media type %s", ic.MediaType) | |||
} | |||
|
|||
appendOSMounts(s, ociimage.OS) |
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.
Looks like the linter is failing here because it's also attempting to lint & compile on MacOS (darwin), where this new function is not defined. My apologies for not realizing that in my original suggestion, but I think you can fix this by either (a) adding a new spec_opts_notfreebsd.go
and moving the definition for everything not-FreeBSD there (including Windows and Linux) or (b) additionally adding a spec_opts_darwin.go
for MacOS.
92f180e
to
e72aeaf
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 for continuing to work with me on this! I've got a few more questions and suggestions after looking at the code a bit more closely.
oci/spec_opts_freebsd.go
Outdated
Destination: "/proc", | ||
Type: "linprocfs", | ||
Source: "linprocfs", | ||
Options: []string{}, |
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.
In the in-place case above, we're adding "nosuid" and "noexec" as options, but in this case we're not. Is there any particular reason for the difference?
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 reason, we should have nosuid & noexec in both ases.
oci/spec_opts_freebsd.go
Outdated
mounts = append(mounts, specs.Mount{ | ||
Destination: "/sys", |
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.
Should we handle /sys
in-place like we're doing for /proc
and /dev/fd
too?
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 agree, but that is less relevant with the new approach I have taken. I will implement this if the approach does not work.
oci/spec_opts_freebsd.go
Outdated
|
||
if !haveDevFd { | ||
mounts = append(mounts, specs.Mount{ | ||
Destination: "/dev/fd", |
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.
Should we also be adding devfs for /dev
?
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 suspect we already have both from the default mounts:
containerd/oci/mounts_freebsd.go
Lines 23 to 38 in 78cd9d3
func defaultMounts() []specs.Mount { | |
return []specs.Mount{ | |
{ | |
Destination: "/dev", | |
Type: "devfs", | |
Source: "devfs", | |
Options: []string{"ruleset=4"}, | |
}, | |
{ | |
Destination: "/dev/fd", | |
Type: "fdescfs", | |
Source: "fdescfs", | |
Options: []string{}, | |
}, | |
} | |
} |
a5163d0
to
b9fcb18
Compare
@samuelkarp I drastically simplified the code. Let me know if I'm missing something. The reasoning is below. We should already have /dev & /dev/fd as default mounts: containerd/oci/mounts_freebsd.go Lines 23 to 38 in 78cd9d3
We need to provide /sys, /proc, and /dev/shm per https://wiki.freebsd.org/LinuxJails and https://github.com/opencontainers/runtime-spec/blob/1c3f411f041711bbeecf35ff7e93461ea6789220/config-linux.md#default-filesystems /sys and /proc are backed by their corresponding file-systems, which I include in /dev/shm is backed by the linuxulator kernel module (albeit the device is not whitelisted by devfs ruleset 4, but that's a separate issue). |
This allows running Linux containers on FreeBSD and modifies the mounts so that they represent the linux emulated filesystems, as per: https://wiki.freebsd.org/LinuxJails Co-authored-by: Gijs Peskens <gijs@peskens.net>, Samuel Karp <samuelkarp@users.noreply.github.com> Signed-off-by: Artem Khramov <akhramov@pm.me>
b9fcb18
to
ae22854
Compare
// Default returns the default matcher for the platform. | ||
func Default() MatchComparer { | ||
return Ordered(DefaultSpec(), specs.Platform{ | ||
OS: "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.
Because most containers image are for Linux today?
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 is ordered with default (FreeBSD) first and Linux as a fallback.
Alright, CI seems green 🎉 It seems like we are good to go. @samuelkarp is there any items I missed? |
@akhramov The previous approach modified the |
Aside from the question about mounts, I've tested this and it works!
|
Not really, but it is up to the runtime (us) to create mountpoints at these locations. Since we don't have these as default mountpoints, I don't expect them to exist at all. Uh, I hope I'm not missing anything. |
Mounts can be arbitrarily defined in the runtime configuration which is an argument to the functional option returned by |
@samuelkarp got it, thanks. So what should happen if a client overrides a default mountpoint? |
A client can choose which functional options to apply (including ones it supplies itself) and can also directly manipulate the object; ultimately the |
@samuelkarp I think the shadowing behavior is pretty much the same on FreeBSD as on Linux. @emaste, can you kindly confirm? |
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 @akhramov! If the shadowing behavior is roughly the same, I think we can go ahead and merge this and adjust to the more-complicated replace-in-place logic if we discover it being a problem.
LGTM!
That is my expectation. I asked some folks who would know for certain, but haven't heard back. |
@emaste Thanks! @akhramov and @gizahNL Thank you so much for working on this and pushing through! Now that containerd/project#90 is approved I'll go ahead and merge this myself. 😄 |
This allows running Linux containers on FreeBSD and modifies the
mounts so that they represent the linux emulated filesystems, as per:
https://wiki.freebsd.org/LinuxJails
Supersedes #5480 per convo with @gizahNL in OCI Slack chat