This is the fourth day of my participation in the First Challenge 2022

Author: xcbeyond

Blog: xcbeyond.cn/ official account: Program ape technology guru

In the cloud era, containerization has become a fact, and packaging software products and building them into Docker images is the most basic and critical step. In the context of Xinchuang, there are different architectures such as x86 and ARM in the cloud environment. Therefore, images of various architectures need to be constructed during image construction to adapt to servers with different architectures.

When the Docker image is pulled, it will automatically pull the image of the corresponding architecture based on the architecture of the current environment. For example, the image pulled in the x86 environment is the image of the x86 architecture, and the image pulled in the ARM environment is the image of the ARM architecture. (Provided that the mirror is a multi-schema mirror)

This article expands on how to build multiple schema images based on Docker Buildx (build multiple schema images at once).

1. Buildx installation

Docker Buildx is a CLI plug-in that extends the Docker command and fully supports the functionality provided by the Moby BuildKit Builder toolkit. It provides the same user experience as docker builds, with many new features, such as creating scoped builder instances and building against multiple nodes at once.

  1. Download the Buildx binary.

    Download the latest Buildx binaries on the Github Release page.

    Select the binary based on your operating system.

  2. Buildx copy to the corresponding directory of Docker.

    Rename the downloaded buildx binary and copy it to the appropriate directory for your operating system:

    The operating system

    Binary name

    Destination folder

    Linux

    docker-buildx

    $HOME/.docker/cli-plugins

    MacOS

    docker-buildx

    $HOME/.docker/cli-plugins

    Windows

    docker-buildx.exe

    %USERPROFILE%\.docker\cli-plugins

    For example, my MacOS:

    xcbeyond@xcbeyonddeMacBook-Pro ~ % mv ~/Downloads/buildx-v0.7.1. Darwin -arm64 ~/. Docker /cli-plugins/docker-buildx xcbeyond@xcbeyonddeMacBook-Pro ~ % chmod +x ~/.docker/cli-plugins/docker-buildxCopy the code

    Note: You need to grant permissions to the buildx binary file, executechmod +x.

  3. Check buildx.

    Docker buildx version

    xcbeyond@xcbeyonddeMacBook-Pro ~ % docker buildx version
    github.com/docker/buildx v0.7.1 05846896d149da05f3d6fd1e7770da187b52a247
    Copy the code

2. Enable binfmT_misc to run non-local Docker images

If you are using the Mac or Windows Docker desktop version, you can skip this step because binfmt_misc is enabled by default.

Tonistiigi/Binfmt image can be used for installation if you are using another platform:

 docker run --privileged --rm tonistiigi/binfmt --install all
Copy the code

3. Switch the default Docker builder to a multi-schema builder

By default, Docker uses the default builder and does not support multi-schema builds.

To build a multi-schema image, you need to create a new builder that supports multiple schemas by executing docker Buildx create –use:

xcbeyond@xcbeyonddeMacBook-Pro % docker buildx create --use --name mybuilder
mybuilder
Copy the code

To see if the new multi-schema builder works, run docker BuildX ls:

xcbeyond@xcbeyonddeMacBook-Pro % docker buildx ls
NAME/NODE       DRIVER/ENDPOINT             STATUS   PLATFORMS
mybuilder *     docker-container                     
  mybuilder0    unix:///var/run/docker.sock inactive 
desktop-linux   docker                               
  desktop-linux desktop-linux               running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default         docker                               
  default       default                     running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Copy the code

4. Build multiple architecture mirrors

  1. Write test programs.

    To facilitate testing, a simple program is written with Golang, and the architecture information of the current program running environment is output:

    package main
    
    import (
       "fmt"
       "runtime"
    )
    
    func main() {
       fmt.Printf("the current platform architecture is %s.\n", runtime.GOARCH)
    }
    Copy the code
  2. Write Dockerfile.

    Write the program’s Dockerfile:

    FROM XCBeyond/GO-Builder :1.16 LABEL Maintainer XCbeyond WORKDIR /app COPY Multi-arch-test. go /app RUN go build-o multi-arch-test /app/multi-arch-test.go CMD ["./multi-arch-test"]Copy the code
  3. Build multiple architectural images.

    Docker buildx build -t

    –platform= Linux /arm64, Linux /amd64. –push And push to Docker Hub:

    The –push argument automatically pushes the image to the Docker Hub, and the image is not kept locally. If you do not want to push, you can remove this parameter.

    xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker buildx build -t xcbeyond/multi-arch-test --platform=linux/arm64,linux/amd64 . --push
    [+] Building 3105.4s (19/19) FINISHED                                                                                                                                                                       
    => [internal] load build definition from Dockerfile                                                                                                                                                   0.0s
    => => transferring dockerfile: 222B                                                                                                                                                                   0.0s
    => [internal] load .dockerignore                                                                                                                                                                      0.0s
    => => transferring context: 2B                                                                                                                                                                        0.0s
    => [linux/amd64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16                                                                                                                        5.2s
    => [linux/arm64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16                                                                                                                        4.9s
    => [auth] xcbeyond/go-builder:pull token for registry-1.docker.io                                                                                                                                     0.0s
    => [internal] load build context                                                                                                                                                                      0.0s
    => => transferring context: 40B                                                                                                                                                                       0.0s
    => [linux/amd64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                               2323.9s
    => => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                                              0.0s
    => => sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 85.80MB / 85.80MB                                                                                                    2318.7s
    => => sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 54.57MB / 54.57MB                                                                                                      27.3s
    => => sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 129.08MB / 129.08MB                                                                                                    77.1s
    => => sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 10.87MB / 10.87MB                                                                                                      96.5s
    => => sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 5.15MB / 5.15MB                                                                                                         5.2s
    => => sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 54.92MB / 54.92MB                                                                                                      61.0s
    => => extracting sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3                                                                                                              1.5s
    => => extracting sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd                                                                                                              0.1s
    => => extracting sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56                                                                                                              0.3s
    => => extracting sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793                                                                                                              1.6s
    => => extracting sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92                                                                                                              1.9s
    => => extracting sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915                                                                                                              3.3s
    => => extracting sha256:2db41f0db9d9d9a1f49978ec31e8d187f491767e9b377f5ee121827c407e015e                                                                                                              0.0s
    => [linux/arm64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                               2187.3s
    => => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc                                                                              0.0s
    => => sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 99.63MB / 99.63MB                                                                                                      54.3s
    => => sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 81.01MB / 81.01MB                                                                                                     472.1s
    => => sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 54.67MB / 54.67MB                                                                                                    2084.9s
    => => sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 10.66MB / 10.66MB                                                                                                       6.2s
    => => sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 5.14MB / 5.14MB                                                                                                         6.8s
    => => sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 53.60MB / 53.60MB                                                                                                      22.7s
    => => extracting sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749                                                                                                              1.5s
    => => extracting sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b                                                                                                              0.1s
    => => extracting sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098                                                                                                              0.2s
    => => extracting sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd                                                                                                              1.5s
    => => extracting sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b                                                                                                              1.7s
    => => extracting sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d                                                                                                              2.7s
    => => extracting sha256:10c716f05a00666c190fb40f99503dc83b2886de744ab9b3dc6c5d37d01f6e49                                                                                                              0.0s
    => [auth] xcbeyond/go-builder:pull token for registry-1.docker.io                                                                                                                                     0.0s
    => [linux/arm64 2/4] WORKDIR /app                                                                                                                                                                     0.1s
    => [linux/arm64 3/4] COPY multi-arch-test.go /app                                                                                                                                                     0.0s
    => [linux/arm64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go                                                                                                                          0.3s
    => [linux/amd64 2/4] WORKDIR /app                                                                                                                                                                     0.2s
    => [linux/amd64 3/4] COPY multi-arch-test.go /app                                                                                                                                                     0.0s
    => [linux/amd64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go                                                                                                                          1.5s
    => exporting to image                                                                                                                                                                               774.4s
    => => exporting layers                                                                                                                                                                               10.5s
    => => exporting manifest sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2                                                                                                      0.0s
    => => exporting config sha256:628f504898973d1d935ffd37993d1db5fdc4715c5d58467db2c6531d3d7d3181                                                                                                        0.0s
    => => exporting manifest sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd                                                                                                      0.0s
    => => exporting config sha256:47e7af533f821be5ba256919303e0de3b39990109a419a98dbfddc6c82086822                                                                                                        0.0s
    => => exporting manifest list sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b                                                                                                 0.0s
    => => pushing layers                                                                                                                                                                                761.8s
    => => pushing manifest for docker.io/xcbeyond/multi-arch-test:latest@sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b                                                          2.0s
    => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s
    => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s
    => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io                                                                                                                           0.0s
       
    Copy the code

5. Test multiple architecture mirrors

Test xcBeyond/multi-ARCH-test :latest to make sure it works properly and output matching architecture information using the corresponding architecture image.

  1. View information for each schema image.

    Run the docker manifest inspect command to view the list of the image and obtain the SHA value of the image corresponding to the architecture:

    xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker manifest inspect xcbeyond/multi-arch-test:latest
    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
       "manifests": [
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 2419,
             "digest": "sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2",
             "platform": {
                "architecture": "arm64",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 2420,
             "digest": "sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd",
             "platform": {
                "architecture": "amd64",
                "os": "linux"
             }
          }
       ]
    }
    Copy the code

    You can also directly see the multi-architecture information supported by the image on Docker Hub:

  2. Run the different schema images one by one based on their SHA values and view their output.

    Docker run –rm

    Arm architecture mirroring:

    xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
    Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2' locally
    docker.io/xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2: Pulling from xcbeyond/multi-arch-test
    94a23d3cb5be: Pull complete 
    ac9d381bd1e9: Pull complete 
    aa9c5b49b9db: Pull complete 
    841dd868500b: Pull complete 
    627b3401fb61: Pull complete 
    221ff675cd35: Pull complete 
    10c716f05a00: Pull complete 
    15bae122089f: Pull complete 
    d764b5be0a55: Pull complete 
    34bfa57028a2: Pull complete 
    Digest: sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
    Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2
    the current platform architecture is arm64.
    Copy the code

    X86 architecture mirroring:

    xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
    Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd' locally
    docker.io/xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd: Pulling from xcbeyond/multi-arch-test
    0e29546d541c: Pull complete 
    9b829c73b52b: Pull complete 
    cb5b7ae36172: Pull complete 
    6494e4811622: Pull complete 
    6e1d20a8313e: Pull complete 
    5b59121a0c35: Pull complete 
    2db41f0db9d9: Pull complete 
    f708bf6a9dc8: Pull complete 
    cb0d69b97354: Pull complete 
    a8f5aa83ecfb: Pull complete 
    Digest: sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
    Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd
    the current platform architecture is amd64.
    Copy the code

    The output above is consistent with our expectations: multiple schema mirrors are built successfully and run in their respective schema environments.

6, summary

Multi-schema images are built based on Docker Buildx. Currently, Buildx requires additional installation. In the future, Buildx will probably become part of the Docker build command.

Reference article:

  1. Docker Buildx
  2. How to Build Multi-Architecture Docker Images with BuildX | Deploy containers to x86 and ARM!