8000 rkt fetch doesn't ever fetch updated image if download locally · Issue #2937 · rkt/rkt · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Feb 24, 2020. It is now read-only.

rkt fetch doesn't ever fetch updated image if download locally #2937

Closed
mtanski opened this issue Jul 15, 2016 · 9 comments
Closed

rkt fetch doesn't ever fetch updated image if download locally #2937

mtanski opened this issue Jul 15, 2016 · 9 comments

Comments

@mtanski
Copy link
mtanski commented Jul 15, 2016

Environment

root@flim-a31d7933:/opt/adfin/conf# rkt version
rkt Version: 1.10.0
appc Version: 0.8.5
Go Version: go1.6.2
Go OS/Arch: linux/amd64
Features: -TPM

Ubuntu 14.04

What did you do?

Trying to download an updated image using rkt fetch for a quay.io repo with a docker image. We label our images with stuff like a format like ${image}:${env} where env can be like prod, integration, dev. That way when somebody promotes an image (using the quay.io UI) and a period update task is run, the nodes update to the latest version of that environment's image.

We've come to expect that behavior previous when we were using docker.

I can get it to work by specifying --no-store, but i refetches all images including shared base images. (like the base JVM image we created)

What did you expect?

That default rkt fetch would see if there's an updated image and fetch the changed layers only. At the very least there should be a flag to do that.

Also rkt should return a status code that can be tested in the shell using $? to see if there has been change... so our further scripts can notice if they should bounce the container.

What did you see instead?

root@flim-a31d7933:/opt/adfin/conf# rkt --insecure-options=image fetch docker://quay.io/adfin/mr_jobs:dev
image: using image from local store for url docker://quay.io/adfin/mr_jobs:dev
root@flim-a31d7933:/opt/adfin/conf# rkt --insecure-options=image fetch --no-store docker://quay.io/adfin/mr_jobs:dev
image: remote fetching from URL "docker://quay.io/adfin/mr_jobs:dev"
Downloading sha256:203137e8afd [=============================] 65.7 MB / 65.7 MB
Downloading sha256:a3ed95caeb0 [=============================]       32 B / 32 B
Downloading sha256:a3ed95caeb0 [=============================]       32 B / 32 B
Downloading sha256:a3ed95caeb0 [=============================]       32 B / 32 B
Downloading sha256:f5fa265265c [=============================]   111 MB / 111 MB
Downloading sha256:a3ed95caeb0 [=============================]       32 B / 32 B
Downloading sha256:933ae248612 [=============================]     681 B / 681 B
Downloading sha256:a3ed95caeb0 [=============================]       32 B / 32 B
Downloading sha256:2ff1bbbe931 [=============================] 71.5 KB / 71.5 KB
Downloading sha256:02e725f9bcf [=============================]     115 B / 115 B
Downloading sha256:6b6fd37a445 [=============================]   110 MB / 110 MB
Downloading sha256:7db9cc08faf [=============================] 2.35 MB / 2.35 MB
Downloading sha256:b8602bd434c [=============================] 82.8 MB / 82.8 MB
root@flim-a31d7933:/opt/adfin/conf# rkt image list
ID          NAME                    IMPORT TIME LAST USED   SIZE    LATEST
sha512-7f3d5c757980 quay.io/adfin/flink:latest      3 hours ago 27 minutes ago  741MiB  true
sha512-24abc47982ec coreos.com/rkt/stage1-coreos:1.10.0 3 hours ago 3 hours ago 178MiB  false
sha512-7939cef320fd quay.io/adfin/mr_jobs:dev       16 minutes ago  16 minutes ago  814MiB  false
sha512-c76e02e48be0 quay.io/adfin/mr_jobs:dev       9 minutes ago   9 minutes ago   599MiB  false
@Andrei-Pozolotin
Copy link

+1

@sgotti
Copy link
Contributor
sgotti commented Jul 16, 2016

Thanks for reporting this. It was also discussed on irc some days ago.

I can see two primary issues:

  • Now docker registry images are converted to a squashed ACI using docker2aci. When rkt will support native oci/dockerv2 images it'll be able to store the different blobs instead of a single converted ACI and so fetch only the new blobs and update the ref to the new manifest. To fix this before this integration, also talking with @dgonyeo, a solution will be to pass the currently stored v1 imageID or v2 manifest digest to docker2aci so it should check if it's changed, if so it will rebuild the new ACI (but this will refetch all the required blobs).
  • I'm going to create a proposal (@lucab) to change the current image fetching logic to be more friendly (in a few words I'm going to propose to use rkt fetch to always update the current refs from the provided URL and fetch the required blobs, while rkt prepare/run will fetch only if the refs/blobs are missing)

@mtanski
Copy link
Author
mtanski commented Jul 18, 2016

@sgotti Thanks. I would say that having a exit status or some kind of way to tell if fetch updated the image would also be a "must have" for admins scripting their rkt workflows.

k8s-github-robot pushed a commit to kubernetes/kubernetes that referenced this issue Aug 26, 2016
Automatic merge from submit-queue

rkt: Force `rkt fetch` to fetch from remote to conform the image pull policy.

Fix #27646

Use `--no-store` option for `rkt fetch` to force it to fetch from remote.
However, `--no-store` will fetch the remote image regardless of whether the content of the image has changed or not. 
This causes performance downgrade when the image tag is ':latest' and the image pull policy is 'always'. 
The issue is tracked in rkt/rkt#2937.
@jonboulle jonboulle added this to the v1.21.0 milestone Nov 23, 2016
@squeed squeed modified the milestones: v1.22.0, v1.21.0 Dec 8, 2016
@lucab
Copy link
Member
lucab commented Jan 5, 2017

To fix this before this integration, also talking with @dgonyeo, a solution will be to pass the currently stored v1 imageID or v2 manifest digest to docker2aci so it should check if it's changed, if so it will rebuild the new ACI (but this will refetch all the required blobs).

Braindump: this can be exposed to the user via a --pull-policy=value flag:

  • always - equivalent to current --no-store (but updating the store)
  • never - equivalent to current --store-only
  • new - only pull if image is not present in the store
  • update - only pull if image in store is stale or missing

I would say that having a exit status or some kind of way to tell if fetch updated the image would also be a "must have" for admins scripting their rkt workflows.

That is perhaps a bit less straightforward for compatibility reasons, as a non-zero exit status is normally interpreted as an error by the shell. But the same scripting features can be achieved just with a boolean exit status and the above pull-policy.

@lucab lucab modified the milestones: v1.23.0, v1.22.0 Jan 5, 2017
@cgonyeo
Copy link
Member
cgonyeo commented Jan 18, 2017

Here's a potential plan, that I'll get started on if no one objects:

I can implement the --pull-policy flag @lucab described. It'll default to new, unless the command being called is rkt fetch, in which case it will default to update.

For ACIs, I think the implementation will be fairly straightforward, but it's a little messier with docker images. Ideally rkt would only fetch docker layers that have changed, but since today rkt has docker2aci squash layers that's not really possible. rkt can't just update the modified layers above a large ubuntu base layer, because it can't separate the thing in its store out into the different layers after it's been squashed.

rkt could instead tell docker2aci to not squash the layers, and put each separately in its store. In AppC land the layers (dependencies) are stored separately already, so this doesn't seem too crazy to me. docker2aci would have to add an annotation to the top layer marking it as such, so that when rkt is told to run docker://python it can look for images that match registry-01.docker.io/library/python-*, filter down to images marked as top layers, and run the one with the latest imported timestamp.

With this change, rkt could then pass a list of hashes (determined by pattern matching on image names in its store) to docker2aci when it asks it to fetch an image, and docker2aci would only need to fetch and save out any missing layers for the image its told to fetch.

One downside to this would be polluting the image store with a bunch of hashes not really intended for humans to read, but rkt could filter out images from a docker source not marked as top layers (again determined by manifest annotations).

@s-urbaniak
Copy link
Contributor

@dgonyeo That sounds like a fair plan. Extending the current store to also store intermediate layer hashes seems necessary anyways for efficient handling of OCI images.

The only small concern from my side is that your outlined plan would also involve converting each intermediate layer to the current ACI format. This would solve this issue in the short-term, but this logic would only live as long as we don't land support for foreign image formats in the store as outlined in https://github.com/coreos/rkt/blob/v1.22.0/Documentation/proposals/oci.md.

@s-urbaniak s-urbaniak modified the milestones: v1.24.0, v1.23.0 Jan 19, 2017
@euank
Copy link
Member
euank commented Jan 19, 2017

@dgonyeo there's another solution that I think is both simpler to implement and reason about. It isn't as ideal, but I think it gets the 90%.

I think it would be enough for rkt fetch to pass the sha256 it knows about for a given image tag to docker2aci. docker2aci could then avoid doing network traffic if no layers at all changed, but if any layer changed it would redownload all of them.

This would let us defer proper layer semantics a bit further while fixing the most painful/common cases of redownload.

My concerns about each layer -> aci is that we're working on getting OCI support (layers and all I assume) as a first class citizen without integration, so the work on docker2aci there might be wasted.

WDYT @dgonyeo?

@lucab
Copy link
Member
lucab commented Jan 19, 2017

I agree with @euank's comment above, that's also what I had in mind.

Other things to mention:

  1. Our doc on this topic is wrong, at least on the caching side.
  2. I was looking into unifying pull-policy, no-store and store-only. Situation seems to be a bit messy, it looks like it grew without order from aggregation of appc and docker2aci. It could be useful to sum up an put order in the new design first.
  3. @euank pointed out that always is probably a dumb value, and doesn't fully reflect no-store. Not sure whether it makes sense to keep it.

@lucab
Copy link
Member
lucab commented Feb 1, 2017

Fixed by #3554

@lucab lucab closed this as completed Feb 1, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants
0