Open dweomer opened 3 years ago
This seems to point at a fundamental flaw in the rudimentary image sync algorithm which merely walks the content in a created/updated image and copies it from the buildkit
namespace to the k8s.io
namespace.
See https://github.com/rancher/kim/blob/v0.1.0-beta.5/pkg/server/agent_linux.go#L137-L150:
func copyImageContent(ctx context.Context, ctr *containerd.Client, name string, fn func(context.Context, images.Store, images.Image) error) error {
imageStore := ctr.ImageService()
img, err := imageStore.Get(ctx, name)
if err != nil {
return err
}
contentStore := ctr.ContentStore()
toCtx := namespaces.WithNamespace(ctx, "k8s.io")
handler := images.Handlers(images.ChildrenHandler(contentStore), copyImageContentFunc(toCtx, contentStore, img))
if err = images.Walk(ctx, handler, img.Target); err != nil {
return err
}
return fn(toCtx, imageStore, img)
}
See https://github.com/rancher/kim/blob/v0.1.0-beta.5/pkg/server/agent_linux.go#L152-L182:
func copyImageContentFunc(toCtx context.Context, contentStore content.Store, img images.Image) images.HandlerFunc {
return func(fromCtx context.Context, desc ocispec.Descriptor) (children []ocispec.Descriptor, err error) {
logrus.Debugf("copy-image-content: media-type=%v, digest=%v", desc.MediaType, desc.Digest)
info, err := contentStore.Info(fromCtx, desc.Digest)
if err != nil {
return children, err
}
ra, err := contentStore.ReaderAt(fromCtx, desc)
if err != nil {
return children, err
}
defer ra.Close()
wopts := []content.WriterOpt{content.WithRef(img.Name)}
if _, err := contentStore.Info(toCtx, desc.Digest); errdefs.IsNotFound(err) {
// if the image does not already exist in the target namespace we supply the descriptor here so as to
// ensure that it is created with proper size information. if the image already exist the size for the digest
// for the to-be updated image is sourced from what is passed to content.Copy
wopts = append(wopts, content.WithDescriptor(desc))
}
w, err := contentStore.Writer(toCtx, wopts...)
if err != nil {
return children, err
}
defer w.Close()
err = content.Copy(toCtx, w, content.NewReader(ra), desc.Size, desc.Digest, content.WithLabels(info.Labels))
if err != nil && errdefs.IsAlreadyExists(err) {
return children, nil
}
return children, err
}
}
A workaround is to have a RUN
directive in the Dockerfile:
FROM percona/percona-server-mongodb-operator:1.9.0
USER 1001
RUN id
kim build -f Dockerfile.test --tag dweomer/percona:test --progress=plain .
#1 [internal] load build definition from Dockerfile.test
#1 sha256:e899eddf2a025e0edadf47253d2b96ab5d4f05181b46d0ae0cc3f3bbaa02c016
#1 transferring dockerfile: 110B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:d38cc1dc6ad2d5a4a22102c441ff305138cc745e4152ec56b3637cae1f229492
#2 transferring context: 34B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/percona/percona-server-mongodb-operator:1.9.0
#3 sha256:e314c9794ecaf251ad137db369128a8817a757f629ed4736a9a794c3535009fe
#3 DONE 0.8s
#4 [1/2] FROM docker.io/percona/percona-server-mongodb-operator:1.9.0@sha256:2daab5999a3a5bc407cc63ce8ae4d18d985f636685273c6678b118d770c3c014
#4 sha256:89ba0a95a16bf5536ac30e9b799eb70ef1435df4158b17f7c6ffdef9d6994487
#4 resolve docker.io/percona/percona-server-mongodb-operator:1.9.0@sha256:2daab5999a3a5bc407cc63ce8ae4d18d985f636685273c6678b118d770c3c014 0.0s done
#4 sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac 0B / 14.82MB 0.2s
#4 sha256:27e66ff83bb0524210035fc9362818531250f57d6cf65a5b8377cd4cd956b148 0B / 1.90kB 0.2s
#4 sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0 0B / 32.32MB 0.2s
#4 sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac 5.24MB / 14.82MB 0.3s
#4 sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0 10.49MB / 32.32MB 0.5s
#4 sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0 24.12MB / 32.32MB 0.6s
#4 extracting sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0
#4 extracting sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0 0.5s done
#4 extracting sha256:27e66ff83bb0524210035fc9362818531250f57d6cf65a5b8377cd4cd956b148 0.0s done
#4 extracting sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac
#4 extracting sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac 0.2s done
#4 DONE 1.5s
#5 [2/2] RUN id
#5 sha256:74e2fb596a0d1abd84ae491a7ae0629cf39bdfabc979566afdabe75d09d5d7b5
#5 0.107 uid=1001 gid=0(root) groups=0(root)
#5 DONE 0.3s
#6 exporting to image
#6 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00
#6 exporting layers
#6 exporting layers 0.2s done
#6 exporting manifest sha256:e1e2da8c0e71923c7a31c520ec40275d4ce69db61133c8a103fd5d66d429bb3f 0.0s done
#6 exporting config sha256:3602fdbf7a7edc1c8ae94b17e577a81a65b406b453dd160b0c6d78cf9937f073 0.0s done
#6 naming to docker.io/dweomer/percona:test done
#6 DONE 0.3s
kubectl logs -n kube-image ds/builder -c agent
time="2021-09-01T18:30:22Z" level=debug msg="image-update: docker.io/dweomer/percona:test"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.distribution.manifest.v2+json, digest=sha256:e1e2da8c0e71923c7a31c520ec40275d4ce69db61133c8a103fd5d66d429bb3f"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.container.image.v1+json, digest=sha256:3602fdbf7a7edc1c8ae94b17e577a81a65b406b453dd160b0c6d78cf9937f073"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:27e66ff83bb0524210035fc9362818531250f57d6cf65a5b8377cd4cd956b148"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac"
time="2021-09-01T18:30:22Z" level=debug msg="image-create: docker.io/dweomer/percona:test@sha256:e1e2da8c0e71923c7a31c520ec40275d4ce69db61133c8a103fd5d66d429bb3f"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.distribution.manifest.v2+json, digest=sha256:e1e2da8c0e71923c7a31c520ec40275d4ce69db61133c8a103fd5d66d429bb3f"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.container.image.v1+json, digest=sha256:3602fdbf7a7edc1c8ae94b17e577a81a65b406b453dd160b0c6d78cf9937f073"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:d36999869101f0eb4f0e44cd9cdc06c46a045104c85c3de632e93384f25949c0"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:27e66ff83bb0524210035fc9362818531250f57d6cf65a5b8377cd4cd956b148"
time="2021-09-01T18:30:22Z" level=debug msg="copy-image-content: media-type=application/vnd.docker.image.rootfs.diff.tar.gzip, digest=sha256:47d6186ae09ffb53eda51c58d832fbcfecd1bd0e75c6a2373fe1751ba8089eac"
A workaround is to have a
RUN
directive in the Dockerfile:FROM percona/percona-server-mongodb-operator:1.9.0 USER 1001 RUN id
Now revert back to the original Dockerfile and the image gets built and synced correctly:
FROM percona/percona-server-mongodb-operator:1.9.0
USER 1001
kim build -f Dockerfile.test --tag dweomer/percona:test --progress=plain --no-cache .
#1 [internal] load build definition from Dockerfile.test
#1 sha256:e34a3c88a7621753ed687673036e06796fce9113cfa9aa1fa03ddfae97cba916
#1 transferring dockerfile: 36B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:073b387bcf57c83ae785b00d1172658250c1f16ea9f75218c34f3f7a8337a633
#2 transferring context: 34B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/percona/percona-server-mongodb-operator:1.9.0
#3 sha256:e314c9794ecaf251ad137db369128a8817a757f629ed4736a9a794c3535009fe
#3 DONE 0.8s
#4 [1/1] FROM docker.io/percona/percona-server-mongodb-operator:1.9.0@sha256:2daab5999a3a5bc407cc63ce8ae4d18d985f636685273c6678b118d770c3c014
#4 sha256:89ba0a95a16bf5536ac30e9b799eb70ef1435df4158b17f7c6ffdef9d6994487
#4 resolve docker.io/percona/percona-server-mongodb-operator:1.9.0@sha256:2daab5999a3a5bc407cc63ce8ae4d18d985f636685273c6678b118d770c3c014 0.0s done
#4 CACHED
#5 exporting to image
#5 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00
#5 exporting layers done
#5 exporting manifest sha256:f8c0e35e65ef1770ebac5d4cabbec86fe7b68ab1200304140df059c81ffe6b73 done
#5 exporting config sha256:859b8dd6aaa7ab1d9628e31cc7d746cad6d66f86de9c6adb056d0d0795da3891 done
#5 naming to docker.io/dweomer/percona:test done
#5 DONE 0.0s
kim image ls | grep percona
dweomer/percona:test <none> 3602fdbf7a7ed 47.1MB
dweomer/percona test 859b8dd6aaa7a 47.1MB
Originally reported in the Rancher Users Slack: https://rancher-users.slack.com/archives/C01RSL4GQN8/p1630483761016500
When using a very light/simple Dockerfile, the built image does not show up via
kim image ls -a
:kim build -f Dockerfile.test --tag dweomer/percona:test --progress=plain .
kim image ls -a
kubectl logs -n kube-image ds/builder -c agent
(subsequent build attempts)