skopeo icon indicating copy to clipboard operation
skopeo copied to clipboard

RFE: create multi-arch manifests

Open terinjokes opened this issue 4 years ago • 42 comments

I created a multi-image OCI path, and can see these have been properly merged in the index

$ skopeo copy docker-archive:./save1.tar.gz oci:manifest
$ skopeo copy docker-archive:./save2.tar.gz oci:manifest
# manifest/index.js
{
  "schemaVersion": 2,
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:5cb5de57b9476b44186e34c5520ce550ee840b9d9bf4a2cf55c9f69a92a8bd63",
      "size": 1446
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:67a7232cc67fda26632946325ada75c35b60eca578c9cfcaca6e3d98a4094562",
      "size": 974
    }
  ]
}

I am, however, unable to push this to Docker Hub to use as a multi-arch image.

$ skopeo copy --all --format v2s2 oci:./manifest docker://terinjokes/test123:skopeo
FATA[0000] Error initializing source oci:./manifest:: more than one image in oci, choose an image

terinjokes avatar Dec 17 '20 07:12 terinjokes

For completion, I also tried copying the different style of OCI list generated in containers/buildah#2858, but got the same error message.

terinjokes avatar Dec 17 '20 07:12 terinjokes

Thanks for your report. The copy pipeline in skopeo copy copies a single (possibly multi-arch) image, so this seems to work as currently designed at a first glance. (That said, it should be possible to work with multi-arch images, so the Buildah issue might be a real bug.)

mtrmac avatar Dec 19 '20 19:12 mtrmac

Looking further, if the destination is docker://…test123:skopeo, how would you expect the two images to be represented? That command just doesn’t make much sense to me.

You can copy one image at a time, currently only if they have different tags; https://github.com/containers/image/pull/1072 will add a way to reference unnamed images in an OCI index.

mtrmac avatar Dec 19 '20 19:12 mtrmac

@mtrmac my goal is to make a multi-architecture image. I expect them to appear as such on Docker Hub. As far as I can tell, there is no way to create a proper multi-architecture image with skopeo, though the tooling gets very close.

terinjokes avatar Dec 19 '20 19:12 terinjokes

Both Buildah and Podman have a manifest subcommand intended for creating such images, so it seems superfluous to provide that functionality in Skopeo.

mtrmac avatar Dec 19 '20 20:12 mtrmac

Both of those require user namespace support, and a fully setup /etc/containers and storage engines. Those are very different requirements than Skopeo, and I should be able to create multi-arch manifests from existing images without them.

Skopeo already generates the OCI directory merged from multiple images. It just generates the wrong type of JSON manifest.

terinjokes avatar Dec 19 '20 20:12 terinjokes

I wanted to be able to copy an image from dockerhub and import it into my private repo including all multi-arch refs. Skopeo seemed like a logical choice.

However in alignment with this issue it seems skopeo (I am running latest version 1.2.0) cannot write/read dockerhub multi-arch manifests. I first started trying to just read the manifest but ran into the following (see Observations below).

Perhaps I am doing something wrong?

Would be great if skopeo did get multi-arch support with ARM based processors becoming more prominent now but more so in the future.

Observations

skopeo inspect docker://ubuntu:21.04
FATA[0003] Error parsing manifest for image: Error choosing image instance: no image found in manifest list for architecture amd64, variant "", OS darwin

However when you add the --raw command line switch it pulls the manifest. So seems to be skopeo cannot parse this format.

skopeo inspect --raw docker://ubuntu:21.04 | jq

Output:

{
  "manifests": [
    {
      "digest": "sha256:eb9086d472747453ad2d5cfa10f80986d9b0afb9ae9c4256fe2887b029566d06",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      },
      "size": 943
    },
    {
      "digest": "sha256:017b74c5d97855021c7bde7e0d5ecd31bd78cad301dc7c701bb99ae2ea903857",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm",
        "os": "linux",
        "variant": "v7"
      },
      "size": 943
    },
    {
      "digest": "sha256:bb48336f1dd075aa11f9e819fbaa642208d7d92b7ebe38cb202b0187e1df8ed4",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm64",
        "os": "linux",
        "variant": "v8"
      },
      "size": 943
    },
    {
      "digest": "sha256:29c2f09290253a0883690761f411cbe5195cd65a4f23ff40bf66d7586d72ebb7",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "ppc64le",
        "os": "linux"
      },
      "size": 943
    },
    {
      "digest": "sha256:e8e0c3580fc5948141d8f60c062e0640d4c7e02d10877a19a433573555eda25b",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "s390x",
        "os": "linux"
      },
      "size": 943
    }
  ],
  "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
  "schemaVersion": 2
}

If you inspect an image that does not support multi-arch then the manifest returned is different in how it is presented.

skopeo inspect --raw docker://jenkins/jenkins:latest | jq

Output:

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 16488,
      "digest": "sha256:f98e5f96106f5484d49bd725e1bac1fa92974ec2688783b153ef815a33680f70"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 45380658,
         "digest": "sha256:3192219afd04f93d90f0af7f89cb527d1af2a16975ea391ea8517c602ad6ddb6"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 10797219,
         "digest": "sha256:17c160265e75550c2ed099aa7d3906b3fef0bf046a2aeead136f8e587a015159"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 4340216,
         "digest": "sha256:cc4fe40d0e618e3319afb689c3570bb87e8e8cf51bca080364d1552317bc66c2"
      },
     ... redacted for brevity
   ]
}

darktempla avatar Jan 01 '21 12:01 darktempla

@darktempla It does know how to read the from the registry, but it resolves to a specific OS and architecture: by default your local one. Ubuntu doesn't have an amd64/darwin build, so there's no image that matches your local architecture. Try using --override-os and --override-arch.

I can't remember if skopeo-sync handles all architectures or not. You might want to give that a try.

terinjokes avatar Jan 01 '21 19:01 terinjokes

@darktempla Yeah, you’re basically running into an artifact of skopeo inspect being created before multi-arch images, so it continues to report single-image data.

It’s certainly plausible to have a multi-arch inspect/format/… feature, but --raw has so far apparently been good enough that I am not aware of even a request for that, so far.


Returning to your original request to copy a multi-arch image, both skopeo copy and skopeo sync have an --all option.

mtrmac avatar Jan 04 '21 13:01 mtrmac

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jun 04 '21 00:06 github-actions[bot]

Is there any resolution for this?

rverma-dev avatar Jun 25 '21 12:06 rverma-dev

@rverma-nsl The current recommendation is to use {podman,buildah} manifest. It does have more system requirements than Skopeo, but seems to me that building multi-arch images usually immediately follows building single-arch images, so requiring tools that can build images is not usually too much to ask.

I can certainly imagine exceptions (and it would be interesting to hear about them), so this issue is not closed yet, but it’s not something we are too likely to work on soon.

(I’d certainly not want for Skopeo to have and maintain an independent reimplementation of the manifest building logic; the existing one should be shared, possibly after being made more general.)

mtrmac avatar Jun 25 '21 12:06 mtrmac

@mtrmac, not necessarily. It is quite typical to build images in GitLab CI using Kaniko, in a setup that cannot run docker or podman. Once images are built, there needs to be a way to assemble them into a multi-arch image, and requiring docker or podman is quite limiting.

andrewshadura avatar Feb 16 '22 09:02 andrewshadura

@mtrmac, not necessarily. It is quite typical to build images in GitLab CI using Kaniko, in a setup that cannot run docker or podman. Once images are built, there needs to be a way to assemble them into a multi-arch image, and requiring docker or podman is quite limiting.

Yeah we are facing the same issue right now. We would as well build in GitLab CI using Kaniko. Afterwards assemble them in a multi-arch image. And we do not want / are not able to provide extended permissions to use e.g. docker, buildah, podman.

bastianbeier avatar Feb 21 '22 15:02 bastianbeier

Same here. Our images are build on a specifically protected infrastructure and the resulting images end up in an intermediate registry. We now search for a valuable solution to generate a multi-arch image from arising separate images that are even build on physically separated machines. The general CI/CD infrastructure is using containers as they are perfectly suited for task isolation. This infrastructure does not allow privileged execution. Right now we use skopeo in this infrastructure to publish images from intermediate internal registry to various endpoints. It would be perfect if this step could also include to combine images from different architectures into a single multi-arch image using skopeo. Thus, please consider this valuable user story.

epDHowwD avatar Mar 10 '22 19:03 epDHowwD

I've got a similar use case. Two archives with x86_64 & aarch64 images. I can publish them via:

skopeo copy docker-archive:path-x86_64.tar.gz docker://index.docker.io/foo/bar:latest-x86_64
skopeo copy docker-archive:path-aarch64.tar.gz docker://index.docker.io/foo/bar:latest-aarch64

As a final step, one has to create manifest & push it:

export DOCKER_CLI_EXPERIMENTAL=enabled
docker manifest create --insecure latest --amend latest-x86_64 --amend latest-aarch64
docker manifest push --insecure -p latest

Would be nice if skopeo can do the final step too. docker requires Docker engine, which is not available in some environments (or is "hard" to set up, Docker inside Docker ...).

zrzka avatar May 05 '22 04:05 zrzka

Maybe https://github.com/estesp/manifest-tool#createpush is an option for this use case.

manifest-tool is a command line utility used to view or push multi-platform container image references located in an OCIv1 or Docker v2.2 compatible container registry. Manifest creation is also a use case on this tool.

epDHowwD avatar May 05 '22 06:05 epDHowwD

You can also use buildah, as mentioned way up thread.

buildah manifest create example
buildah manifest add example docker-archive:./docker-amd64
buildah manifest add example docker-archive:./docker-arm64
buildah manifest push --all -f v2s2 example docker://terinjokes/example:latest

terinjokes avatar May 05 '22 08:05 terinjokes

Thanks, aware of buildah, manifest-tool, ... I'm not a big fan of yet another dependency. Quite a big one (buildah) for what I need. I've ended up with a couple of HEAD, GET requests followed by final PUT for the manifest list. It's not that hard to assemble a manifest list by myself. The Service I'm building is a publisher, which just consumes Docker image archives (built elsewhere, one archive per architecture) and distributes them to Docker Hub, AWS ECR, Google Cloud, ... as multi-arch images.

zrzka avatar May 05 '22 08:05 zrzka

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jun 27 '22 00:06 github-actions[bot]

A friendly reminder that ‘stale issues’ is a misnomer.

andrewshadura avatar Jun 27 '22 06:06 andrewshadura

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Jul 28 '22 00:07 github-actions[bot]

Because it’s still an issue. Can somebody please disable this annoying bot?

andrewshadura avatar Jul 28 '22 07:07 andrewshadura

This annoying bot is the only thing that keeps the issue in the foreground, without it, I doubt anyone will pay attention to the issue, it will get lost in the forest.

It is always best if you have an issue to step forward and open a PR to solve it.

rhatdan avatar Jul 28 '22 13:07 rhatdan

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Aug 28 '22 00:08 github-actions[bot]

@mtrmac, any updates on this please?

andrewshadura avatar Aug 28 '22 11:08 andrewshadura

A friendly reminder that this issue had no activity for 30 days.

github-actions[bot] avatar Sep 28 '22 00:09 github-actions[bot]

Adding a vote for this feature. Our use case: We run image builds on a restricted k8s cluster using kaniko, and push the resulting image archive to a registry using skopeo. We're now creating images for multiple architectures, so it would be great to be able to use skopeo to push a multi arch image to a registry. We cant use the buildah method as suggested by @terinjokes, as buildah manifest requires elevated permissions, which aren't an option for us.

mccaig avatar Dec 07 '22 20:12 mccaig

vote +1

panpan0000 avatar Apr 04 '23 01:04 panpan0000

vote +1

d1nfinite avatar Apr 30 '23 07:04 d1nfinite