MatrixAI / Emergence

Distributed Infrastructure Orchestration
Apache License 2.0
1 stars 0 forks source link

Building artifacts #51

Open nzhang-zh opened 5 years ago

nzhang-zh commented 5 years ago

Provide capability to build OCI image based artefacts and Nix based artefacts.

nzhang-zh commented 5 years ago

There are multiple ways to construct an artefact with different level of sharing. 4 approaches are considered at this point as shown below, going from least shared to most shared.

nzhang-zh commented 5 years ago

Artefact

runc requires a container to be organised as a filesystem bundle shown below.

./rootfs/
config.json

Nix based artefact (complete share)

We could directly construct rootfs in the output of our nix derivation by mirroring a merged directory structure of all input packages with symbolic links.

For example, an artefact with bash and tree as input would have the following output

$ tree .
.
├── bin
│   ├── bash -> /nix/store/czx8vkrb9jdgjyz8qfksh10vrnqa723l-bash-4.4-p23/bin/bash
│   ├── sh -> /nix/store/czx8vkrb9jdgjyz8qfksh10vrnqa723l-bash-4.4-p23/bin/sh
│   └── tree -> /nix/store/bskfav26x2xify79w2kc824k3fiwyika-tree-1.7.0/bin/tree
├── lib
│   └── bash
│       ├── basename -> /nix/store/czx8vkrb9jdgjyz8qfksh10vrnqa723l-bash-4.4-p23/lib/bash/basename
│       ├── dirname -> /nix/store/czx8vkrb9jdgjyz8qfksh10vrnqa723l-bash-4.4-p23/lib/bash/dirname
│       ├── finfo -> /nix/store/czx8vkrb9jdgjyz8qfksh10vrnqa723l-bash-4.4-p23/lib/bash/finfo
│       ├── ...
└── share
    └── man
        └── man1
            └── tree.1.gz -> /nix/store/bskfav26x2xify79w2kc824k3fiwyika-tree-1.7.0/share/man/man1/tree.1.gz

Notice how bash, sh and tree (as well as bash libs) are all symbolic links to nix store which will be bind mounted by runc.

OCI image based artefact (full copy)

WIth Docker

This is the method shown by runc doc

# export busybox via Docker into the rootfs directory
docker export $(docker create busybox) | tar -C rootfs -xvf -

With pkgs.dockerTools

dockerTools.exportImage {
  fromImage = dockerTools.pullImage {
    imageName = "busybox";
    imageDigest = "sha256:2a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bddd8d92465812";
    sha256 = "<hash>";
  };
};

Note this outputs a tar archive.

With skopeo

skopeo --override-os "linux" --override-arch "amd64" copy "docker://busybox@sha256:2a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bddd8d92465812" "oci:busybox:<tag>"

This gives us an OCI image layout that needs to be further unpacked.

$ tree .
.
├── blobs
│   └── sha256
│       ├── 90e01955edcd85dac7985b72a8374545eac617ccdddcc992b732e43cd42534af
│       ├── b4f1424d3f12ec809dc268c6c87d25d8b3869813aea92c9dfaf7429de802030e
│       └── d98834fba17e4121dc21f65d6ddf2f648da119c86d72ffea8145e496bda621fd
├── index.json
└── oci-layout

To unpack, we could

nzhang-zh commented 5 years ago

With pure nix based artefacts, we could simply create symbolic links to outputs in nix store and mount host nix store into an automaton. This approach provides the highest level of sharing.

Bind mounting nix store directly into the container may not work well with some applications that require write access to its own directory. For example, by default nginx tries to write log files and temp files to /nix/store/<nginx-store-path>/. Nginx does support changing the default directory prefix, but this involves preparing a minimal directory structure elsewhere.

Instead, we could choose to mount host nix store with storage driver when preparing root filesystem. With OverlayFS, host nix store will be a lowerdir and application can make changes to the local nix store on the merged filesystem.

CMCDragonkai commented 5 years ago

That issue exists on NixOS anyway, no Nix packages should be configured to write to /nix/store as it's always immutable. So I don't think this is unique to bind mounting in containers.