regclient / regclient

Docker and OCI Registry Client in Go and tooling using those libraries.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Can I export local image to .tar file within podman?

TyeolRik opened this issue · comments

Thanks for providing good program!
among 3 packages, crane, skopeo, regctl, only your program works well on my system!

Question

Can I export local image to .tar file? (I am currently using podman)

I want to preserve my Digests or RepoDigests (whatever at least one) for closed network system. I successed with below commands

# origin node
$ ./regctl image export <IMAGE_NAME>@sha256:<IMAGE_DIGEST> ./regctl.tar
$ scp ./regctl.tar <ANOTHER_NODE>

# another node
$ podman load -i regctl.tar
$ podman run -it <IMAGE_NAME>@sha256:<IMAGE_DIGEST> # SUCCESS!

But the thing is, above commands only works when online (internet connected). I am looking for export command if there is no internet connection. Is it possible?

Version

$ ./regctl version
VCSTag:     v0.5.6
VCSRef:     c848ed2ec4c23f88a7e1a96f75270ad416671eb3
VCSCommit:  c848ed2ec4c23f88a7e1a96f75270ad416671eb3
VCSState:   clean
VCSDate:    2023-12-24T14:14:41Z
Platform:   linux/amd64
GoVer:      go1.21.5
GoCompiler: gc

$ podman -v
podman version 4.6.1

Environment

  • Running as binary or container: binary
  • Host platform: x86_64, CentOS 8 Stream, podman (v4.6.1)
  • Registry description: nothing. only local in closed network with some tar files. (podman save -o)

regctl can read/write from registries, an OCI layout, and an export to a tar file with either the OCI Layout or Docker archive format. So in this case, you would run a podman save ... to output to any of those formats (their docs describe the ability to output to multiple formats), and then either podman load to import that save on another machine, or a regctl image import or regctl image copy ocidir://$path/to/dir $dest to work with the Docker archive or OCI Layout.

Note that regclient doesn't talk directly to podman, docker, containerd, kubernetes, or any other container runtimes directly. The furthest it goes is the Docker archive tar file.

I am so sorry, but, due to my lack of English, you didn't understand what I am talking about. Please let me explain the question again.

For example, There is a situation that host1 save the image to .tar file and send to host2.

  • Please be aware that host2 has no internet connection. only connect available with host1.

there is the ubi 9.3 image. Its digest is 6b95efc1. From host1, the image is pulled, saved, and sent to host2.

[host1]$ podman pull registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
[host1]$ podman image inspect --format {{.Digest}} registry.access.redhat.com/ubi9/ubi:9.3-1361.1699548029
sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359

# And doing podman save as you said.
[host1]$ podman save -o ubi.tar registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359

# Send to host2
[host1]$ scp ubi.tar root@host2:/root/

host2 get the image file. podman load -i. Now the problem happened. Host2 can't run the image because digest is broken (changed).

[host2]$ podman load -i ubi.tar
Getting image source signatures
Copying blob 584953c6b22f done
Copying config 2a2c2b7af8 done
Writing manifest to image destination
Loaded image: sha256:2a2c2b7af8db0755dce3da01d17da4eef17841d6ebebdb201ecd5a88629457ce

# Now the image digest is changed. No longer sha256:6b95efc1 anymore.
[host2]$ podman images --digests
REPOSITORY                    TAG         DIGEST                                                                   IMAGE ID      CREATED      SIZE
<none>                        <none>      sha256:125e16dd5f58c761f66a603b8184b353bc3f8659be320e6972aa25cb234a8441  2a2c2b7af8db  8 weeks ago  219 MB

# So, according to changed digest, I can't use image with digest.
[host2]$ podman run -it registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359 /bin/bash
Trying to pull registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359...
WARN[0000] Failed, retrying in 1s ... (1/3). Error: initializing source docker://registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359: pinging container registry registry.access.redhat.com: Get "https://registry.access.redhat.com/v2/": dial tcp 127.0.0.1:443: connect: connection refused
WARN[0001] Failed, retrying in 1s ... (2/3). Error: initializing source docker://registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359: pinging container registry registry.access.redhat.com: Get "https://registry.access.redhat.com/v2/": dial tcp 127.0.0.1:443: connect: connection refused
WARN[0002] Failed, retrying in 1s ... (3/3). Error: initializing source docker://registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359: pinging container registry registry.access.redhat.com: Get "https://registry.access.redhat.com/v2/": dial tcp 127.0.0.1:443: connect: connection refused
Error: initializing source docker://registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359: pinging container registry registry.access.redhat.com: Get "https://registry.access.redhat.com/v2/": dial tcp 127.0.0.1:443: connect: connection refused

**I want to preserve the digest when copying from host1 local image to host2. **

I also tried to docker-archive or oci-archive but doesn't work. Is that because I am using not docker but podman?

[host1]$ regctl image export docker-archive:2a2c2b7af8db test.tar
WARN[0001] Failed to get manifest                        err="failed to get manifest docker.io/library/docker-archive:2a2c2b7af8db: unauthorized" ref="docker.io/library/docker-archive:2a2c2b7af8db"
failed to get manifest docker.io/library/docker-archive:2a2c2b7af8db: unauthorized
[host1]$ regctl image export oci-archive:2a2c2b7af8db test.tar
WARN[0001] Failed to get manifest                        err="failed to get manifest docker.io/library/oci-archive:2a2c2b7af8db: unauthorized" ref="docker.io/library/oci-archive:2a2c2b7af8db"
failed to get manifest docker.io/library/oci-archive:2a2c2b7af8db: unauthorized

Apologies, I misinterpreted your question. I thought you were asking if regctl can talk directly to podman (which it doesn't). From the errors shown, I believe the issue is that the image is not being tagged in podman. From containers/podman#2210 I believe you can explicitly tag the image by running:

podman load -i ubi.tar registry.access.redhat.com/ubi9/ubi:9.3-1361.1699548029

There's also multiple digests here, which gets confusing. First, there's the index that holds the platform specific manifests. The index/manifest list has it's own digest that you were using:

$ regctl manifest get registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
Name:        registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
MediaType:   application/vnd.docker.distribution.manifest.list.v2+json
Digest:      sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
             
Manifests:   
             
  Name:      registry.access.redhat.com/ubi9/ubi@sha256:5dc85ec81a0d2cc5d19164f80b8d287b176483fd09a88426ca2f698bb2bd09de
  Digest:    sha256:5dc85ec81a0d2cc5d19164f80b8d287b176483fd09a88426ca2f698bb2bd09de
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64
             
  Name:      registry.access.redhat.com/ubi9/ubi@sha256:113204124d07727303e50b2e6b87a01784180c187043f842a1af92e4f389c0e5
  Digest:    sha256:113204124d07727303e50b2e6b87a01784180c187043f842a1af92e4f389c0e5
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64
             
  Name:      registry.access.redhat.com/ubi9/ubi@sha256:15098e9778f5502d928d8b0e5df356e4ffa53cb8c9356d57e12b60873f4b47b7
  Digest:    sha256:15098e9778f5502d928d8b0e5df356e4ffa53cb8c9356d57e12b60873f4b47b7
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/ppc64le
             
  Name:      registry.access.redhat.com/ubi9/ubi@sha256:8466c9efca1a9342ba174e9540cf939d0538adc46c2b93255567025a07a0f33b
  Digest:    sha256:8466c9efca1a9342ba174e9540cf939d0538adc46c2b93255567025a07a0f33b
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/s390x

But when podman imports it, it may need the platform specific manifest digest, and it will display that platform's config digest in various references the image:

$ regctl manifest get registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359 --platform linux/amd64
Name:        registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
MediaType:   application/vnd.docker.distribution.manifest.v2+json
Digest:      sha256:5dc85ec81a0d2cc5d19164f80b8d287b176483fd09a88426ca2f698bb2bd09de
Total Size:  78.772MB
             
Config:      
  Digest:    sha256:2a2c2b7af8db0755dce3da01d17da4eef17841d6ebebdb201ecd5a88629457ce
  MediaType: application/vnd.docker.container.image.v1+json
  Size:      6409B
             
Layers:      
             
  Digest:    sha256:b824f4b30c465e487e640bdc22e46bafd6983e4e0eabf30085cacf945c261160
  MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
  Size:      78.772MB

And the blob digest comes from the uncompressed blob, which can be seen in the rootfs section of the config:

$ regctl image config registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359 --platform linux/amd64
...
  "rootfs": {                                     
    "type": "layers",                                                                                                                                                                                              
    "diff_ids": [        
      "sha256:584953c6b22faba1a93fb106297d108abefed3b1866099baa8cc6b0ab92bc47a"
    ]
  }, 
...

I believe podman is working similar to docker here, where only a single platform image is imported. When a single platform manifest is exported in regctl, both the OCI layout and docker archive format are included in the same tar, which may give podman the metadata it needs to automatically tag the image, e.g.:

regctl image export --platform linux/amd64 <IMAGE_NAME>@sha256:<IMAGE_DIGEST> ./regctl.tar
...
podman load -i regctl.tar 

Exporting a single platform, if you don't need the multi-platform manifest, can save you a lot of download time and disk space. But realize the digest will be the platform specific digest and not the manifest list digest.

Without testing, I can't say if podman would use the image name from the docker archive, or if it prefers the OCI Layout since both are included that regctl export. If none of the above help, podman may include additional metadata it their own export that regclient can include. To see what they are creating, try the following:

# this should output the image in the ubi directory if I'm reading their documentation correctly
podman save --format oci-dir -o ubi registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
jq . <ubi/index.json

I'd be interested in seeing if they include any annotations in there pointing to registry.access.redhat.com/ubi9. If so, that's something I can easily add to regclient.

Thanks for your kind reply.

However, I tried as you said,

[host1]$ podman save --format oci-dir -o ubi registry.access.redhat.com/ubi9/ubi@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
[host1]$ scp -r ubi host2:/root/

[host2]$ podman load -i /root/ubi
[host2]$ podman image inspect localhost/ubi:latest
[
     {
          "Id": "2a2c2b7af8db0755dce3da01d17da4eef17841d6ebebdb201ecd5a88629457ce",
          "Digest": "sha256:19cf2549663ac9e7dead59a723dfd2e2ae9f861efbe65335623094a0d2373044",
          "RepoTags": [
               "localhost/ubi:latest"
          ],

Doesn't work as I wanted.. :( Image digest always changed..

Thanks for trying to help. I think I have to do something with opening local registry for solving this problem :(