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

Add Windows Instructions #579

Closed
wants to merge 2 commits into from
Closed

Conversation

slominskir
Copy link

Fixes #578

@adelton
Copy link
Collaborator

adelton commented Jan 12, 2024

I'm not fond of these detailed instructions -- they are bound to become a liability, getting obsolete, incomplete, or simply not working on specific combinations of WSL versions, WSL distributions, docker, and whatever else can impact the outcome. The instructions we have in https://github.com/freeipa/freeipa-container#running-freeipa-server-container are intentionally vague ("... may be necessary ...") because we simply cannot cover all the combinations and we leave it up to the person setting FreeIPA in their containerization environment to figure out the exact details and requirements with their vendor / community.

I do support the idea of making things easier for people trying this out on Windows. But if Microsoft already has a documentation we can refer to, we should just link to it. (Over the years people seemed to duplicate the instructions for running the FreeIPA containers on other sites and we then saw people struggling with obsolete guidance, missing the fact that our README got updated with latest understanding of working steps since those other sites put their content on. And yes, cgroups was the typical problematic area.)

I would go with a single sentence, something like

On Windows with Windows Subsystem for Linux (WSL) version 2, enabling systemd may be necessary in the WSL distro to turn on cgroups functionality.

Except:

  1. The - /sys/fs/cgroup:/sys/fs/cgroup:ro volume suggests that this uses cgroup v1. I wonder if we shouldn't be striving for v2, perhaps using cgroup_no_v1=all.
  2. Which might however require mount --move /sys/fs/cgroup/unified /sys/fs/cgroup or configuring the cgroup2 mountpoint in /etc/fstab.
  3. I also wonder if systemd is even needed in that WSL distro -- does it do anything for the container's benefit beyond mounting the /sys/fs/cgroup? Can't that be done manually or by /etc/fstab entry?

@slominskir
Copy link
Author

I agree maintaining good instructions is more work vs vague ones. No need to repeat Microsoft directions if we're keeping this short as a link will do. However, this project doesn't have a docker compose example so this PR text is a little more verbose than it otherwise would be to fill that gap. If someone is developing software with Docker containers they'll likely be using Docker Compose to avoid copy and pasting commands and managing multiple containers independently. Maybe the instructions could be shortened by simply taking the one-line sentence you propose and then appending the compose example?

I'm not sure which cgroup version is being used, but WSL distro config for systemd does appear to be required as the example doesn't work until you add it.

@adelton
Copy link
Collaborator

adelton commented Jan 13, 2024

The reason why we don't have a specific docker-compose configuration example is pretty much the same as for the other setup guidance "vagueness" I explained -- docker-compose is merely docker run parameters written in a different syntax, with the problem of subtle incompatibilities among versions / environments / who know what potentially ruining the experience.

For example, FreeIPA server really requires a FQDN hostname. We've had people using FQDN in hostname, we had people who had to use domainname to make things work, and we had people reporting that domainname actually does not work for them. I don't want to be on the hook trying to figure out which version / OS / something requires what.

Also, the docker-compose example that you show will likely not work on Linuxes with cgroupv2 ... meaning we'd immediately need to start showing multiple versions, repeating the "... may be necessary ...".

We can discuss adding docker-compose example in separate PR but I thought it might be fair to state my general position upfront. The change / example would need to be done in such a way that it does not become a maintenance burden down the road.

@adelton
Copy link
Collaborator

adelton commented Jan 13, 2024

I'm not sure which cgroup version is being used, but WSL distro config for systemd does appear to be required as the example doesn't work until you add it.

Can you figure out which cgroup version is used? What happens when you disable the v1 and just use v2? Is the /sys/fs/cgroup needed in that case, and with the :ro parameter?

I'm also afraid that you have the implication slightly reversed -- yes, adding systemd=true made things work on your setup but that does not mean this is the only way to do it and thus that this is required, if the real and only thing that you need to achieve is the cgroup filesystem mounted under /sys/fs. (Note: I don't know whether it's the only thing. But we should be sure before we update the documentation.)

If you have the Windows environment around, can you please test what gets or does not get mounted in the WSL environment without the systemd=true config? And if /sys/fs/cgroup is not mounted by default, would merely manually mounting it expose it for docker and therefore make the FreeIPA container work?

Another thing to figure out are user namespaces. On Linuxes with cgroups v2, docker seems to only configure proper cgroup delegation when userns-remap is used. That is actually a good thing -- people are pushed to run the FreeIPA container rootless. What is the situation under WSL? Incidently -- what is podman situation under WSL? (containers/podman#3288 suggests user namespaces might be possible ...)

@slominskir
Copy link
Author

I think having the simplest possible working example is ideal for getting people up and running fast and it's going to hard to find a faster or simpler container quick start than docker compose up.

It isn't clear what domainname is really for, which is even more reason for this freeipa container project to figure it out so each user doesn't have to. Some suggest it is only needed for NIS, which if true would mean not it's not necessary I think (I assume yp is optional in freeipa).

The hostname and domainname behavior depends on networking mode. The current freeipa container README doesn't mention this. The default (and likely safest) network mode is bridge mode and that's a good target for a quick start compose demo. Regardless of Docker Compose vs Docker run the hostname/domainname issue needs to be explicitly explained.

In my example above I assume I'm using cgroup v1, but it appears both V1 and V2 are installed on my Ubuntu distro (though only as single /sys/fs/cgroup path):

ryans@COMPUTER:/sys/fs$ mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc)

I think a cgroup v2 example is a good idea if it's different. Having two examples is more maintenance, but may be needed since cgroups V1 presumably isn't always available. I'll need to do some more testing to see if there are other combinations that work (and try to figure out how to use cgroup V2). If I remove systemd=true from wsl.conf and restart WSL then systemctl command no longer works as expected, but the /sys/fs/cgroup path still exists inside the WSL ubuntu distro.

@abbra
Copy link

abbra commented Jan 16, 2024

From my old investigation when Fedora was thinking to remove NIS tools:

FreeIPA does depend on nisdomainname utility (part of hostname package).

SUDO depends on the correct value returned from getdomainname() in order to support netgroups in LDAP-stored SUDO rules. Same rules are implemented by FreeIPA and SSSD.

However, I think this is not deprecated technology question. Domain name information is the part of UTS information in the kernel.

According to glibc implementation, getdomainname() pulls the domain name from uname() syscall:
https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/getdomain.c;h=09bb3b0e2cc214b406387294ad90b3c01e2d9a71;hb=HEAD

where 'domainname' is GNU extension. It represents a name of the domain this host belongs to. Note that the domain name itself is not a DNS domain name as it represents a higher abstraction level entity which can be roughly mapped to a whole IPA or AD domain. This is how we actually are using it in FreeIPA.

Someone has to set the domain name upon startup. So far, only nisdomainname tool was doing that. If that is removed, then SUDO will definitely break.

This does not require presence of NIS infrastructure but does require properly configured NIS domain name on each client. Which means we must be able to continue configuring NIS domain name.

@slominskir
Copy link
Author

My example above doesn't set domainname in Docker and appears to work. Setting domainname might be handled by the freeipa container entrypoint (given hostname) or possibly the -r argument to the ipa-server-install setup script?

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

If I remove systemd=true from wsl.conf and restart WSL then systemctl command no longer works as expected, but the /sys/fs/cgroup path still exists inside the WSL ubuntu distro.

So what is the output of mount | grep cgroup on WSL where the systemd=true is not present?

@slominskir
Copy link
Author

slominskir commented Jan 16, 2024

The output of mount | grep cgroup is identical regardless if whether systemd=true in wsl.conf. Since WSL distro mounts != Docker in-container mounts I wonder if Docker engine blocks mounts unless systemd=true. Will test.

Edit:
The output isn't identical, but close. Diff:

< tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
---
> tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
18d17
< cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

Actually, in an unprivileged container we just block out domainname and nisdomainname with https://github.com/freeipa/freeipa-container/blob/master/hostnamectl-wrapper. We assume the domain name (that may or may not include the NIS domain) got set when the container was being created, for docker run/podman run that would be with the -h FQDN value.

We don't assume any sudo operations happening in the FreeIPA container, so this was not really a problem (IIRC).

Anyway, let's keep this PR on the core "run FreeIPA in WSL, by primarily focusing on cgroups" issue, and perhaps let's have separate issue about the hostnames / domainnames.

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

@slominskir Could you use microsoft/WSL#6662 (comment) and see if you get cgroupsv2 mounted directly on /sys/fs/cgroup and what effect it has on the docker behaviour?

Based on the note in microsoft/WSL#10877 that /etc/fstab might not even be needed if you are on WSL 2.

That kernelCommandLine = cgroup_no_v1=all likely needs to go to the [wsl2] section in .wslconfig.

@slominskir
Copy link
Author

@adelton If I add kernelCommandLine = cgroup_no_v1=all and restart everything then mount looks like:

ryans@COMPUTER:/mnt/c/Users/RyanS$ mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)

Docker Desktop starts, but then freeipa compose example fails (regardless of systemd=true existence). Might need to move mount or something. Looks like:

C:\Users\RyanS\IdeaProjects\pam>docker compose -f ipa.yml up
[+] Running 2/2
 ✔ Network pam_default  Created                                                                                    0.0s
 ✔ Container ipa        Created                                                                                    0.1s
Attaching to ipa
ipa exited with code 255

You may be on to something with theory that systemd=true may not actually be required. I removed it from distro wsl.conf and removed kernelCommandLine = cgroup_no_v1=all from user global .wslconfig and yet now example compose works. Scratching my head as to why. Maybe first time it runs it configures distro cgroups or something and the cgroups config isn't rolled back when systemd=true removed from wsl.conf? Microsoft released Windows 11 patches in the last few days that my machine automatically applied too, so could be that, but unlikely. I really don't want to uninstall WSL and re-install it to test that theory, but might be needed unless someone else has Windows test box.

@slominskir
Copy link
Author

Looks like getting cgroups V2 to work with Docker is tricky even directly on some Linux distros (no WSL): #429.

There is a ton of complexity in this project due to freeipa running multiple services inside a single container via systemd and that turns out to not be very portable (and apparently not even possible in many environments until recently). Is it possible to separate the 389 LDAP server, Apache httpd web server, Tomcat PKI CA app server, and MIT Kerberos KDC service, and anything else I'm forgetting into separate containers that communicate through ports and are all launched via a Docker Compose? This would presumably side-step this entire systemd / cgroups hassle and be more portable.

In my particular use case we use a cluster of yum installed Red Hat Identity Manager on RHEL servers in production and I'm simply attempting to have a test/dev freeipa server spin up in a container so I can develop apps that interface with freeipa in isolation from prod and avoid a dedicated test VM subnet. I actually only need the 389 LDAP server at the moment so spinning up that server in a container and applying the freeipa flat LDAP schema appears to be the way to go.

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

For Linux and cgroupsv2 and docker, the #429 (comment) guidance is in the README since August 2022 (9f7e452#diff-2b7814d3fca2e99e56c51b6ff2aa313ea6e9da6424804240aa8ad891fdfe0900) and I don't remember anyone reporting a problem with that.

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

If you have access to RHEL / RHEL-like platforms, I'd strongly suggest to just go with podman or docker there, rather than the WSL thing. I don't think we heard reports of anyone else trying things on Windows.

@adelton
Copy link
Collaborator

adelton commented Jan 16, 2024

There is a ton of complexity in this project due to freeipa running multiple services inside a single container via systemd and that turns out to not be very portable (and apparently not even possible in many environments until recently). Is it possible to separate the 389 LDAP server, Apache httpd web server, Tomcat PKI CA app server, and MIT Kerberos KDC service, and anything else I'm forgetting into separate containers that communicate through ports and are all launched via a Docker Compose? This would presumably side-step this entire systemd / cgroups hassle and be more portable.

Sure it is theoretically possible and you are welcome to try that.

But note that you will be re-implementing large portions of the ipa-server-install / ipa-replica-install utilities to get everything properly setup.

To copy my response from #386 (comment):

I'm not particularly happy that freeipa-container depends on systemd but the proper solution would be to make FreeIPA itself configurable across multiple hosts / VMs, in other words FreeIPA natively offering itself for containerized split, including any configuration and setup tools. In freeipa-container project we just consume FreeIPA in the way matching its deployment on hosts (outside of containers), based on packaging for the specific OS versions (RHEL, CentOS, Fedora).

@slominskir
Copy link
Author

Windows still makes up majority of desktop and laptop OSes I believe so simply not recommending/supporting their use with freeipa container isn't a great option. Plus many people have Windows gaming machines at home that double as great container hosts!

Each upstream service that makes up freeipa is likely to eventually land on having a container option anyways if it hasn't already simply for ease of testing, development, and demos. I guess at that point it will be easier for freeipa to adopt the one service per container design.

Docker Compose examples are a great additional form of documentation: an easily launched working example cleanly modularized that can be easily interrogated is very valuable. It's also a great way to recreate bugs and communicate them to devs via a relatively small package. Modular also means users can work with only the portion needed (in my case just 389 LDAP). These benefits are really only true if the containers work easily and portably and that may require the software within to be made such that it works well in-container and is portable.

The freeipa project that integrates all theses services could separate the setup scripts into modules, one per service such that they could be run separately. It appears there are some IPC mechanisms currently required as well that would need to be configurable to optionally use ports instead. A lot of the updating probably involves making hard-coded assumptions configurable and organizing modularly.

In the meantime, I guess we can close this PR and just wait and see what develops in the container world. I'm not sure how to reliably run freeipa in a container on Windows at this point. I got it working with trial and error. I thought it was simply systemd=true, but after poking around a little I'm not convinced either. It appears things are evolving still as well, especially with cgroups2.

@slominskir slominskir closed this Jan 17, 2024
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.

Docker Compose Example for Windows
3 participants