Logic for checking isImageSharable creating performance delays due to tarball generation
Discussed in https://github.com/containerd/nerdctl/discussions/2808
Originally posted by Shubhranshu153 February 7, 2024
Running command:
nerdctl build . --platform
Checking the logic of:
executor == "containerd" && containerdUUID == uuid && containerdNamespace == namespace && workerSnapshotter == snapshotter && len(platform) == 0, nil
is it possible this is mapping too many conditional for is-shareable? This is creating some unintended behavior and delays due to tar creation
Logic in docker for setting exporter type to "image"
switch len(opt.Exports) {
case 1:
// valid
case 0:
if nodeDriver.IsMobyDriver() && !noDefaultLoad() {
// backwards compat for docker driver only:
// this ensures the build results in a docker image.
opt.Exports = []client.ExportEntry{{Type: "image", Attrs: map[string]string{}}}
}
default:
return nil, nil, errors.Errorf("multiple outputs currently unsupported")
}
Thank You
I don't think the conditions can be reduced ?
As per the comment it seems the platform option is the driving factor for this.
// NOTE: It's possible that BuildKit doesn't download the base image of non-default platform (e.g. when the provided
// Dockerfile doesn't contain instructions require base images like RUN) even if --output type=image,unpack=true
// is passed to BuildKit. Thus, we need to use type=docker or type=oci when nerdctl builds non-default platform
// image using platform option.
isImageShareable it seems if the image build is shareable among runtimes. Not sure the purpose so here is what i am thinking:
- executor== containerd, if other executor it is not shareable as the build image is specific to containerd. Hence needed
- containerdUUID == uuid : not sure how this is getting used. if the first one is true then the containedUUID need not match?
- workerSnapshotter == snapshotter : same question as above.
- containerdNamespace == namespace: same question as above.
- len(platform) ==0: This one i think we might want to check if the platform is actually different, if not we can use the type=image.
1, 2, and 3 are hard requirements because containerd can't see images built by BuildKit otherwise. The same applies to 4, but this could be potentially optimized by adding some API to containerd to allow sharing an image across namespaces. 5 might be potentially optimizable too.
Thanks for the response, did some testing to understand the logic: So executor, uuid and namespace need to be same for able to share images. (some optimization possible but thats fine and makes sense why they are required)
Snapshotter option
I was not clear on snapshotter though: The snapshotter is one need not match, but if they dont match containerd wont be able to run images and wont be able to push images? But then its a bigger problem as we wont be able to do anything with the image built. So if the snapshotter doesnt match do we raise an error instead?
Platform option
Once can pass multiple platform too, in that case probably we would just create in type docker, if we are certain its 1 and its of the expected platform type we can optimize it -> confirming the optimization suggestion.