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

nixos/dockerPreloader: preload docker images #49379

Merged
merged 1 commit into from Nov 3, 2018

Conversation

nlewo
Copy link
Member

@nlewo nlewo commented Oct 29, 2018

This module permits to preload Docker image in a VM in order to reduce
OIs on file copies. This module has to be only used in testing environments,
when the test requires several Docker images such as in Kubernetes
tests. In this case, virtualisation.dockerPreloader.images can
replace the services.kubernetes.kubelet.seedDockerImages options.

The idea is to populate the /var/lib/docker directory by mounting QCOW
files (we use QCOW files to avoid permission issues) that contain images.

For each image specified in
config.virtualisation.dockerPreloader.images:

  1. The image is loaded by Docker in a VM
  2. The resulting /var/lib/docker is written to a QCOW file

This set of QCOW files can then be used to populate the
/var/lib/docker:

  1. Each QCOW is mounted in the VM
  2. Symlink are created from these mount points to /var/lib/docker
  3. A /var/lib/docker/image/overlay2/repositories.json file is generated
  4. The docker daemon is started.
Motivation for this change

Speed up tests that require Docker images.

I have several Kubernetes tests that take more than 3min just to load Docker images (seedDockerImages k8s options). With this module, once QCOWs have been created, Docker images are immediately available in the test VMs (no more Docker load).

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

@nlewo nlewo force-pushed the docker-preload-images branch 5 times, most recently from 4092e12 to 5582ec9 Compare October 29, 2018 09:41
@nlewo
Copy link
Member Author

nlewo commented Oct 29, 2018

@GrahamcOfBorg test docker-preloader

@GrahamcOfBorg
Copy link

No attempt on aarch64-linux (full log)

The following builds were skipped because they don't evaluate on aarch64-linux: tests.docker-preloader

Partial log (click to expand)

Cannot nix-instantiate `tests.docker-preloader' because:
error: syntax error, unexpected INT, at /var/lib/gc-of-borg/nix-test-rs-24/repo/38dca4e3aa6bca43ea96d2fcc04e8229/builder/grahamc-aarch64-community-24/nixos/release.nix:271:1

@GrahamcOfBorg
Copy link

No attempt on x86_64-linux (full log)

The following builds were skipped because they don't evaluate on x86_64-linux: tests.docker-preloader

Partial log (click to expand)

Cannot nix-instantiate `tests.docker-preloader' because:
error: syntax error, unexpected INT, at /var/lib/gc-of-borg/.nix-test-rs/repo/38dca4e3aa6bca43ea96d2fcc04e8229/builder/rbvermaa-spot/nixos/release.nix:271:1

@nlewo
Copy link
Member Author

nlewo commented Oct 29, 2018

@GrahamcOfBorg test docker-preloader

@GrahamcOfBorg
Copy link

Success on aarch64-linux

Attempted: tests.docker-preloader

No partial log is available.

@GrahamcOfBorg
Copy link

Success on x86_64-linux (full log)

Attempted: tests.docker-preloader

Partial log (click to expand)

docker: exit status 1
syncing
docker: running command: sync
docker: exit status 0
test script finished in 36.01s
cleaning up
killing docker (pid 597)
vde_switch: EOF on stdin, cleaning up and exiting
vde_switch: Could not remove ctl dir '/build/vde1.ctl': Directory not empty
/nix/store/a175r0302l5l3gb9wwyvppj1a039bk1x-vm-test-run-docker-preloader

This module permits to preload Docker image in a VM in order to reduce
OIs on file copies. This module has to be only used in testing
environments, when the test requires several Docker images such as in
Kubernetes tests. In this case,
`virtualisation.dockerPreloader.images` can replace the
`services.kubernetes.kubelet.seedDockerImages` options.

The idea is to populate the /var/lib/docker directory by mounting qcow
files (we uses qcow file to avoid permission issues) that contain images.

For each image specified in
config.virtualisation.dockerPreloader.images:
1. The image is loaded by Docker in a VM
2. The resulting /var/lib/docker is written to a QCOW file

This set of QCOW files can then be used to populate the
/var/lib/docker:
1. Each QCOW is mounted in the VM
2. Symlink are created from these mount points to /var/lib/docker
3. A /var/lib/docker/image/overlay2/repositories.json file is generated
4. The docker daemon is started.
@nlewo
Copy link
Member Author

nlewo commented Oct 29, 2018

cc @srhb @johanot @offlinehacker

Copy link
Member

@zimbatm zimbatm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice. It's adding a bit of complications but it will be useful in various scenarios.

# If docker.storageDriver is null, Docker choose the storage
# driver. So, in this case, we cannot be sure overlay2 is used.
assertion = cfg.dockerPreloader.images == []
|| cfg.docker.storageDriver == "overlay2"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is "overlay2" not compatible with overlay2?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is compatible. The assertion is true if the storageDriver is overlay2.


$docker->waitForUnit("sockets.target");
$docker->succeed("docker run nix nix-store --version");
$docker->succeed("docker run bash bash --version");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we guaranteed that the VM won't access the network to fetch the image?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I don't think it's possible to disable remote registries in the Docker configuration. But this is guaranteed thanks to our sandbox.

Copy link
Contributor

@srhb srhb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful!

@zimbatm zimbatm merged commit 3fb4eb1 into NixOS:master Nov 3, 2018
nlewo added a commit to nlewo/nixpkgs that referenced this pull request Nov 12, 2018
This module permits to preload Docker image in a VM in order to reduce
OIs on file copies. This module has to be only used in testing
environments, when the test requires several Docker images such as in
Kubernetes tests. In this case,
`virtualisation.dockerPreloader.images` can replace the
`services.kubernetes.kubelet.seedDockerImages` options.

The idea is to populate the /var/lib/docker directory by mounting qcow
files (we uses qcow file to avoid permission issues) that contain images.

For each image specified in
config.virtualisation.dockerPreloader.images:
1. The image is loaded by Docker in a VM
2. The resulting /var/lib/docker is written to a QCOW file

This set of QCOW files can then be used to populate the
/var/lib/docker:
1. Each QCOW is mounted in the VM
2. Symlink are created from these mount points to /var/lib/docker
3. A /var/lib/docker/image/overlay2/repositories.json file is generated
4. The docker daemon is started.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants