How I shrunk a Docker image by 98.8% – featuring fanotify
21–30 of 51 posts
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#22Isn't the point of running an application in a container, or any chrooted environment, to only isolate the application from the rest of the operating system? Then why would you start out with a complete extra operating system in there? Why not just put the application and its dependencies in there? To strip non-dependencies from an complete operating system sounds like a very failure prone way to accomplish almost th…
1. "run-time dependencies" — package B needs package A installed because a binary from B actually makes use of a file from A when it runs.
2. "install-time dependencies" — package B needs package A installed because B is effectively a "plugin" for A. B is theoretically useless to the OS, except when used in the context of a sane A-like environment. This usually also implies that B, when installing itself, will run a script provided by A, usually to register itself in a database that A owns. This doesn't at all imply, though, that you couldn't just directly call the binary contained in the A package for a useful effect.
3. "asynchronous/maintenance-time dependencies" — package B needs package A because B does something to increase the system's entropy, and is written to assume that the system will compensate for this by having A running.
Docker images really only need type-1 dependencies, but as you dig toward the core of a package dependency graph, you start to see a lot more of type-2 and type-3 dependencies. If you execute a "debootstrap --variant=minbase", pretty much everything in there is there for type-2 or type-3 reasons.
A Docker container doesn't need to be a maintainable or autonomous OS distribution. It doesn't need grub, it doesn't need mkfs or fsck, it doesn't need mkinitramfs or the HAL hwdb; it doesn't need localegen, or debconf, or even apt itself. It needs to be a baked, static collection of files related to the application's run-time needs. But there's no demand you can make of apt or yum or even debootstrap that will spit out such a thing.
There was a project somewhat in this vein a long time ago, for embedded systems, called "Emdebian Baked"[1]. It was a misstep, I think, because it focused on creating variants of packages and a secondary dependency graph; rather than being a transformation one could apply to existing packages and the existing graph.
I've worked on and off on creating a transformation tool—effectively, a combination of a dependency graph "patch" that contains empty virtual-packages for many essential-package dependencies, a file filter/blacklist, and a final package whose installation burns away the whole package-management infrastructure from the chroot this is executing in. I haven't been happy with any of the results yet, though. Would anyone be interested in collaborating on such a thing as an open-source project?
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#23The other interesting thing to try, if your app's problem isn't so much library-dependencies but instead Unix shell dependencies, is to use a Busybox base image. Apps whose runtimes are already sandboxed VMs, especially, usually work great under Busybox: the JVM, Erlang's BEAM VM, etc.
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#24I don't think there is any way to prove that this found all the required files. The more paths through the code, each with its own potential file accesses that can't be predicted with out run time information, the more likely one will be missed in this optimization stage.
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#25Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#26I don't think there is any way to prove that this found all the required files. The more paths through the code, each with its own potential file accesses that can't be predicted with out run time information, the more likely one will be missed in this optimization stage.
You could argue that that can still be fooled by, e.g., making the software dlopen the argument given to it at which point that codepath would have different dependencies each time it was hit, but that argument quickly devolves. That same argument says that when I run `ls /tmp/file` that makes `/tmp/file` a dependency of ls and thus I must include every file in the image else it will have different behavior.
I think intelligent fuzzing + high branch coverage can prove that you have found all required files.
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#27Isn't the point of running an application in a container, or any chrooted environment, to only isolate the application from the rest of the operating system? Then why would you start out with a complete extra operating system in there? Why not just put the application and its dependencies in there? To strip non-dependencies from an complete operating system sounds like a very failure prone way to accomplish almost th…
> Then why would you start out with a complete extra operating system in there? Why not just put the application and its dependencies in there? Packaging is hard. Let's go shopping!
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#28Does CAP_SYS_ADMIN still leak out of containers? I know at some point running with that meant you were root on the host...
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#29Earlier quoted context omitted.
Do Docker images really have to contain an entire bloated Linux distro? Even for Xen, which, as a hypervisor, provides fewer services than Docker, it's possible to write applications which run directly under Xen.
They don't have to, one can run static binary without any problems. It's just that most people keep throwing in a whole distro...
Re: How I shrunk a Docker image by 98.8% – featuring fanotify
#30Isn't the point of running an application in a container, or any chrooted environment, to only isolate the application from the rest of the operating system? Then why would you start out with a complete extra operating system in there? Why not just put the application and its dependencies in there? To strip non-dependencies from an complete operating system sounds like a very failure prone way to accomplish almost th…
Any Unix-ish application (i.e. one that shells out to do something at some point) will have a package dependency tree that ends up transitively closing over the "base"/"essential" package-set of the OS. "Dependency" has three meanings, to a packaging system, even though at run-time only one of them is relevant. There are: 1. "run-time dependencies" — package B needs package A installed because a binary from B actuall…
Anyhow, even a large-ish application such as Oracle or a control system doesn't actually use ping or dd or troff, or most parts of what a modern unix-OS is comprised of. Most things suid are usually unnecessary, which if nothing else does decrease the attack surface.
Most web apps probably needs nothing unix-ish at all. A chrooted PHP app mounted noexec makes me sleep better than one running in a complete operating system. And most server side Java apps re-invents everything unix anyway, from mail processing to cron jobs, so they generally don't shell out as often as you'd think.
So I would argue it's actually pretty common that your applications have a limited set of dependencies. Especially compared to the hundreds of packages in any minimal modern unix install.