It has been a while since multi-architecture support has been developed and brought upstream. Multi-architecture support allows to put several images behind a common identifier in a registry. With that, a consumer of the image won't have to think about pulling the right binary flavor of the image, it's done right automatically for him.
A couple of things play together for this magic:
- A manifest list defines the content of a (composite) image. In this manifest list, images are specified and can be flagged with OS type, architecture, and optional features.
- A manifest tool uses the manifest list and assembles the composite image in a registry. Today's tool is a stop gap until this will finally be picked up by some docker tool (docker "push" command?), but some details need to be fleshed out, like signing or conventions on the use of all the manifest list flags.
- A docker registry, version 2.3 or higher. Docker Hub also appears to work, while Docker Trusted Registry is not there today. The registry stores the metadata and manifest to serve the composite image.
- The docker engine will pull the right image layers from the registry according to its OS type and architecture
We assume we have pushed a z image ("s8345002:5000/demo-s390x:v0.2") and an x86 image ("s8345002:5000/demo-amd64:v0.2") into the registry.
Let's go for the manifest tool. I'm using an Ubuntu system with golang installed. You could run a container off the s390x/ubuntu image and and install git and golang to get to a similar build environment. Alternatively, a gccgo environment is also good. Check out previous posts (here and here) for options to get a go environment.
root@s8345002:~# export GOPATH=/goUpdate 5/24: instead of make, use make binary meanwhile
root@s8345002:~# mkdir -p /go/src/github.com/estesp
root@s8345002:~# cd /go/src/github.com/estesp
root@s8345002:/go/src/github.com/estesp# git clone https://github.com/estesp/manifest-tool
Cloning into 'manifest-tool'...
remote: Counting objects: 2290, done.
remote: Total 2290 (delta 0), reused 0 (delta 0), pack-reused 2290
Receiving objects: 100% (2290/2290), 1.33 MiB | 865.00 KiB/s, done.
Resolving deltas: 100% (845/845), done.
Checking connectivity... done.
root@s8345002:/go/src/github.com/estesp# cd manifest-tool/
root@s8345002:/go/src/github.com/estesp/manifest-tool# make binary
go build -o manifest github.com/estesp/manifest-tool
root@s8345002:/go/src/github.com/estesp/manifest-tool# file manifest
manifest: ELF 64-bit MSB shared object, IBM S/390, version 1 (SYSV), dynamically linked, interpreter /lib/ld64.so.1, for GNU/Linux 3.2.0, BuildID[sha1]=4558a22a1bd2855cf8cb9d909e6491dacef92b61, not stripped
You can use "make install" to put the binary into /usr/bin (warning to Ubuntu users: it will overwrite your existing manifest tool, which is a packaging tool, so maybe avoid this step), or just copy it someplace to use it as appropriate.
Usage of the manifest tool is simple; it accepts two commands, pushml and inspect. pushml will take a manifest list and create a composite image in a registry. In our case, the manifest list is in a file demo_v0.2.yml and looks like this:
image: s8345002:5000/demo:v0.2
manifests:
-
image: s8345002:5000/demo-s390x:v0.2
platform:
architecture: s390x
os: linux
-
image: s8345002:5000/demo-amd64:v0.2
platform:
architecture: amd64
os: linux
Pushing the manifest list is a simple task then:
root@s8345002:~# manifest pushml demo_v0.2.ymlSo now we have assembled s8345002:5000/demo:v0.2 as multi-arch image! We can use it on both s390x and x86 systems in the same way -- here it is on z (the last line is the ID of the started container):
INFO[0000] Retrieving digests of images...
INFO[0000] Image "s8345002:5000/demo-s390x:v0.2" is digest sha256:9ce1108764ac3573305f0385f48bb13a1dbbab190024b74e537dade5266c9433; size: 1160
INFO[0000] Image "s8345002:5000/demo-amd64:v0.2" is digest sha256:19917b5260edb681a54796ef55ca84de9a25d0847bbebe98fdaaecdd5d01d846; size: 948
Digest: sha256:a8989538239ad5fe35edc7585cdbc3d1ccd17ef073bf5b68b19de6008d2e2548
root@s8345006:~# uname -mon x86 (never mind the z in the name of the host):
s390x
root@s8345006:~# docker run -d s8345002:5000/demo:v0.2
Unable to find image 's8345002:5000/demo:v0.2' locally
v0.2: Pulling from demo
8b882489a3a3: Pull complete
f426950865ca: Pull complete
04b013558d21: Pull complete
30827c9a9c1a: Pull complete
Digest: sha256:a8989538239ad5fe35edc7585cdbc3d1ccd17ef073bf5b68b19de6008d2e2548
Status: Downloaded newer image for s8345002:5000/demo:v0.2
556189a965b6e31b90d867e5f8dcb96ebef4c833e02bb62258b4ee9265e77e5a
root@zhyp223:~# uname -m
x86_64
root@zhyp223:~# docker run -d s8345002:5000/demo:v0.2
Unable to find image 's8345002:5000/demo:v0.2' locally
v0.2: Pulling from demo
e110a4a17941: Pull complete
1d7959f73be3: Pull complete
e402f7bb28d1: Pull complete
Digest: sha256:a8989538239ad5fe35edc7585cdbc3d1ccd17ef073bf5b68b19de6008d2e2548
Status: Downloaded newer image for s8345002:5000/demo:v0.2
8d27377bbd89af5d92448a1986da4f0b690fcb6513b11d3e63b8a291a7249e4f
Different platforms, same commands, same success. q.e.d.! This works for simple "docker run" commands, but also any other tool or orchestration infrastructure that uses docker images: above the docker API level, multi-arch is transparent.
To wrap up, here's how the manifest tool can inspect existing composite images:
root@s8345002:~# manifest inspect s8345002:5000/demo:v0.2
s8345002:5000/demo:v0.2 is a manifest list containing the following 2 manifest references:
1 Mfst Type: application/vnd.docker.distribution.manifest.v2+json
1 Digest: sha256:9ce1108764ac3573305f0385f48bb13a1dbbab190024b74e537dade5266c9433
1 Mfst Length: 1160
1 Platform:
1 - OS: linux
1 - Arch: s390x
1 - Variant:
1 - Feature:
1 # Layers: 5
layer 1: digest = sha256:8b882489a3a36a51c029665ac9cfce0bf9094791321a2d65d78f40709e50bb5c
layer 2: digest = sha256:f426950865cae44ca253a30e1bd0bcf730b1d300affd793bbcf6aff38ea48cb9
layer 3: digest = sha256:04b013558d2122c1c979af4934b7d0c6a69fae45dd848fb56a9ee75e3b982f71
layer 4: digest = sha256:30827c9a9c1aca6526d17f79c4663455e879c87446a5422404487b76702e4bba
layer 5: digest = sha256:296b0a2fd33c9ec2e1808ad9edfb097d2eb5a94155d6f4503e5fa1fe27bc3e21
2 Mfst Type: application/vnd.docker.distribution.manifest.v2+json
2 Digest: sha256:19917b5260edb681a54796ef55ca84de9a25d0847bbebe98fdaaecdd5d01d846
2 Mfst Length: 948
2 Platform:
2 - OS: linux
2 - Arch: amd64
2 - Variant:
2 - Feature:
2 # Layers: 4
layer 1: digest = sha256:e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58
layer 2: digest = sha256:1d7959f73be365cad2a5f05cccaf5bdf5169c29cdea4d8b49e3d160f76ac6fab
layer 3: digest = sha256:e402f7bb28d1d772c50d2abf79d92abbb4f87aef0b3aed39db391c1e1b0dac22
layer 4: digest = sha256:30a29be64d6006d974ecdef7040346a381a80486e411206faf8aef4e5ef1bce0
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.