-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
dockerTools: add streaming image support, improve speed and reduce IO #91084
Conversation
I guess there aren't really any user-facing changes are there? Which means there is no documentation that needs to be updated, unless there is documentation with implementation details. |
since they avoid realizing the image tarball in the Nix store, which is desirable in some cases. |
d371ec9
to
1619952
Compare
Ack 👍 That'd be really nice :-) |
Hi @adrian-gierakowski -- co-author of the change here. I'm a Mac guy, and I can't get linuxkit to work for me on Catalina, so I'm working on getting access to a Linux build machine for testing purposes. Here's my take on what you're seeing: in the let
linuxPkgs = import <nixpkgs> { system = "x86_64-linux"; };
hostPkgs = import <nixpkgs> {};
in
hostPkgs.dockerTools.streamLayeredImage {
name = "hello";
contents = [ linuxPkgs.hello ];
config = {
Cmd = [ "${linuxPkgs.hello}/bin/hello" ];
};
} |
…(MacOS) to avoid error described in NixOS/nix#3321 (comment) the problem manifests itself when building streamLayeredImage in single user mode on MacOS using method described in NixOS#91084 (comment) (via a remote builder)
@purcell That worked, thanks! I did have to jump through a bunch of hoops though to make it work as a few things turned out to be broken on MacOS. All of the fixes below are needed to create an image on MacOS with the new implementation:
And somehow unrelated, Thanks for the great work! |
Needed to allow running image as non root user. Fixes a regression introduced by NixOS#91084
Needed to allow running image as non root user. Fixes a regression introduced by NixOS#91084
Another regression is that Having the |
That is interesting. As far as I can see |
Running the following:
results in
The main difference is that previously, the layer tar is made as part of the |
Oh, right. Thanks @thatsmydoing . I'll fix it tomorrow, probably by making the customisation layer derivation create a tar archive instead of a directory. |
…rball This fixes as issue described here[1], where permissions set by 'extraCommands' were ignored by Nix. [1] NixOS#91084 (comment)
…rball This fixes as issue described here[1], where permissions set by 'extraCommands' were ignored by Nix. [1] NixOS#91084 (comment) (cherry picked from commit ae82f81)
…rball This fixes as issue described here[1], where permissions set by 'extraCommands' were ignored by Nix. [1] #91084 (comment) (cherry picked from commit ae82f81)
Apologies for digging up a closed PR. I wasn't quite sure where to ask the question. I'm looking to load some images built with dockerTools.buildLayeredImage into Bazel, but if the intermediate layers are compressed, the load is faster. From what I can gather from the awful specs, is that I'm looking for OCI compatible images that are: From what I can ascertain, the default for Docker is to export images with compressed layers. It seems to be the default, but it doesn't seem to be required or recommended from what I can see. Is there a reason why the |
Hi @groodt,
I am not super familiar with OCI compatible images, so I don't know if they are compatible/similar to what is implemented; or even possible to implement this with our unusual appraoch.
The reason I can think of is that,
If it ends up as a performance gain (smaller images, faster image creation etc.), I don't see why it wouldn't be accepted. As for the direction, it's pretty much modifying
To be honest, that sounds like the easiest. Likely something like |
We've written our own image building tools that generate OCI here https://github.com/iknow/nix-utils/tree/master/oci if you're interested (we also don't compress them though). The paradigm works a bit differently from That said, based on my experience, it probably wouldn't be too hard to port |
Isn't there already a separate |
Thanks for the replies everyone. There's a lot for me to look at. It does appear that OCI is the best-bet for longer-term compatibility and that Docker is now using https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-2.md @purcell I think |
Yeah, that could well be. Like I say, we overhauled dockerTools, but it was only just after ociTools was added IIRC. |
Motivation for this change
In the context of client work, we (@utdemir and myself) have been producing large (multi-GB) docker images with Nix. These images work nicely once produced, with the obvious limitations of unwieldy images, but the machinery for producing them via Nix is costly in a couple of senses:
skopeo
, butdockerTools
always realises them into the Nix store, where they will be included in binary caches and generally take up lots of disk space, particularly in a CI environment.We set about addressing both of these costs, by using the following scheme:
streamLayeredImage
function, analogous tobuildLayeredImage
, but which produce as their outputs scripts which - when run - write the corresponding docker image tostdout
, streaming directly from the underlying layer content store paths. For many users, this will be all they need.buildLayeredImage
uses the newstreamLayeredImage
machinery to realise the image tarballs into the Nix store as before, for those users who still want this functionality.Our results have been encouraging locally. Given the following example large image definition:
building after these changes takes 1m33s vs 5m58s with the previous code. Additionally, with the
streamLayeredImage
function, the same image can be piped todocker load
in 2 minutes 30 seconds.We're presenting these changes for feedback on API and approach. Some further notes:
tarsum
. We believe that the newer standard - which has been supported since Docker 1.12 - should be fine for all reasonable real-world uses.buildImage
does not usebuildLayeredImage
to build a one-layered image, since previously those two functions had parallel implementations. We have not changed this, but there is an opportunity to do so.Thanks!
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)