WSL and Docker both do not support systemd - is there any plan to refactor around this? Based on my research, relying on systemd is an anti-pattern for new developerments, and it appears it can be worked around with some moderate effort. I get why WSL isn’t prioritized but aren’t we bothered by not being able to support docker? This seems like a significant gap, and I really do hope there’s a plan to get this dependency removed. Overall, snap is an awesome platform but (with respect) there’s an opportunity for this to become a much more highly recommended/promoted platform if there was a path forward for docker adoption.
Bikeshedding aside, I’m assuming what you actually want is to run snaps inside of a Docker container? systemd is not a blocker for “Docker” support. It’s definitely possible to run systemd in OCI containers, Podman even has native support for it.
For reference; these are some of the earlier discussions about snapd in Docker.
I haven’t found a clear statement yet whether Docker support is out of the question entirely, so it would be nice to have someone from the snapd team comment on this.
Some level of Docker support would be nice, even if the snaps are unconfined, given that many build systems run builds inside of Docker containers and snapcraft
has required snap
support for a very long time.
@galgalesh - Thanks for your reply. While I appreciate the workarounds to perhaps be able to run snaps on a running container (albeit with workarounds the publishers warn shouldn’t be used in production), the bigger issue is not whether it can run in a container after it’s launched, but whether we can use snap to actually provision Docker images. The point is to run the container and it already have the requirements installed. If the Dockfile can’t actually install the needed software using snap, then we have to fall back to apt-get, yum, curling-to-bash, etc., because the priority over elegant design and easy-of-readability is to have the container start out already having everything installed.
Where there may be clever ways to get snap to work as if systemd were running, emulating it or hacking the kernel or whatnot, my understanding is that none of those workarounds will work in the case that we are still building the docker image, which is again the proper place for installs to happen.
I honestly don’t understand why we can’t work around this dependency and unblock the hundreds-of-thousands of Docker developers who would happily take advantage of this in their docker files if they could.
So, I want to ask again, with all respect, is there any plan of feasible way that snap installs can be performed without systemd running on the machine? Has anyone explored this in a robust way, and are their any articles or resources I can refer to so as to understand what the blockers and/or relative effort would be?
For reference, the 2019 stack overflow developer survey showed over a third (34%) of professional developers are building for the Docker platform, more than AWS, Android, or MacOS.
https://insights.stackoverflow.com/survey/2019#technology-_-platforms
I understand the desire to use snaps inside docker containers, but really the concept of a strictly confined snap is a bit at odds with docker best practices. A snap is itself basically already a container, but implemented in different ways that docker works and so to run snapd inside a docker container is basically to run dockerd inside a docker container which is an anti-pattern. Instead what most folks end up doing when they find themselves wanting to run docker-in-docker is really actually to mount the docker socket inside the docker container so that docker-in-docker really is talking to the host docker, bypassing all of the confinement of the docker container and also exposing a very large security hole, not to mention the ability for a docker container to modify the host system in arbitrary ways.
We do not have any plans to officially support running snaps inside docker because any such solution right now would effectively end up having snapd inside the docker container control/effect the host and that is not something we are interested in maintaining.
For a more concrete example, take something like the a mongodb snap. If we have a docker container running snapd that installs mongodb as a snap, it will try to load apparmor profiles for mongodb snap onto the host, and this will conflict with any potential mongodb snap that the user has installed on their host system outside of the container, this breaking one of the fundamental desirable properties of containers, that they are isolated from the host
Please note that the reason we do not support snapd inside a docker container is not just systemd but also the confinement as detailed above. Docker containers do not get run inside their own apparmor namespace, unlike LXD where LXD containers are run inside their own apparmor namespace allowing snapd to create and mutate apparmor profiles that are isolated from the host system.
And to be clear we have no such plans to work around systemd usage in snapd, but we are always open to patches from the community. It would be quite hard to handle from a pure code perspective given that snapd doesn’t just manage snaps on many different distros, it also is the central management piece of Ubuntu Core, which uses systemd, so you’d either need to maintain both two implementations or you’d somehow have to get Ubuntu Core to stop relying on systemd as well.
Speaking from experience, systemd is a difficult piece of software to work with, but it does solve many problems for us and to switch now from using it to something else completely would be an immense undertaking. The level of cross-distro support we currently have would basically be impossible if we didn’t rely on systemd to take care of many things with our current time allotment for various features.
If there was a switch to turn off all confinement of snaps, would this apparmor issue be solved? Or is an LSM also required for normal functioning of snaps?
Well another aspect of overall snap confinement is setting up mount namespaces for the snap, it’s not clear to me if using squash-fuse is sufficient for doing all of that setup within docker or not. If it’s not, then you would have to poke holes in the docker confinement which iirc would effectively mean that a snap inside a docker container could still trivially break out of docker’s confinement. I’m sure there are other such mechanisms which would be problematic for docker to allow snapd to do.
Thank you @ijohnson and @ijohnson the added background. This is incredibly helpful for my understanding. I see the barrier more clearly now - I did not realize previously the containerization-esque nature of the snap install
process, and I can better appreciate now (1) why a connection to systemd supports this paradigm and (2) why this is a large ask to be able to support “container in container” (or “container inception” ).
This said, I don’t believe that docker-in-docker or nested containerization should remain an anti-pattern for much longer. To keep this as an anti-pattern requires that we expect applications to “know” whether they are running in a container or not; this, I think, is the larger and more important anti-pattern. When I’m testing an app in my CI/CD pipeline, is that containerized? What about in production or on my workstation? Possibly “yes” to all three, but as a developer, I certainly can’t assume any one of them is not running a container since even if today they are running “native”, someone is likely to move any or all them to run on containers in the future. This is why I think we should support “docker in docker” and similar use cases as acceptable best practices, and keep up the hard work to streamline and harden the internals to make this possible.
Again, not to trivialize the effort in this vain; just to say, I hope is there’s a way forward we continue to pursue those paths.
These are just my own thoughts - again again, thanks much for your explanation. We can close this ticket or keep it open. Appreciate your support and I look forward to seeing the snap platform continue to grow.
We agree with this fully and there is some work to support “LSM stacking” where systems like AppArmor, etc. can work inside other LSMs, whether that be the same one like AppArmor or even a different one like SELinux, but this work is complicated and not close to being done. With this work however, we could envision a world where the confinement that snapd does to confine snaps is namespaced inside the LSMs that dockerd does to confine the docker container. Then a fully unconfined snap inside the docker container has no more permissions than the docker container itself has and that a strictly confined snap starts out with the same permissions that the docker container has and subtracts from that to get to the level of confinement that is expected of strictly confined snaps.