5
votes

Comment créer une image Docker sur une architecture spécifique avec Docker Hub?

J'ai ces versions automatisées sur Docker Hub:

 builds automatisés docker hub

Et pour référence, voici les deux fichiers Docker:

Et voici le journal de construction pour la construction arm32v7 :

Building in Docker Cloud's infrastructure...
Cloning into '.'...
Warning: Permanently added the RSA host key for IP address '192.30.253.113' to the list of known hosts.
Reset branch 'master'
Your branch is up-to-date with 'origin/master'.
Executing build hook...
Sending build context to Docker daemon 88.06kB
Step 1/17 : ARG ALPINE_VERSION="3.8"
Step 2/17 : ARG S6_OVERLAY_VERSION="1.21.7.0"
Step 3/17 : FROM golang:1.11-alpine${ALPINE_VERSION} AS builder
1.11-alpine3.8: Pulling from library/golang
169185f82c45: Pulling fs layer
34c29055ee42: Pulling fs layer
29802c64cdfc: Pulling fs layer
dd82873a5b09: Pulling fs layer
b711937b138a: Pulling fs layer
dd82873a5b09: Waiting
b711937b138a: Waiting
29802c64cdfc: Verifying Checksum
29802c64cdfc: Download complete
34c29055ee42: Verifying Checksum
34c29055ee42: Download complete
b711937b138a: Verifying Checksum
b711937b138a: Download complete
169185f82c45: Verifying Checksum
169185f82c45: Download complete
169185f82c45: Pull complete
34c29055ee42: Pull complete
29802c64cdfc: Pull complete
dd82873a5b09: Verifying Checksum
dd82873a5b09: Download complete
dd82873a5b09: Pull complete
b711937b138a: Pull complete
Digest: sha256:9657ef82d7ead12e0c88c7f4708e78b50c5fd3c1893ac0f2f0924ab98873aad8
Status: Downloaded newer image for golang:1.11-alpine3.8
---> be1230a1b343
Step 4/17 : RUN apk update && apk add --no-cache --virtual build-dependencies git && go get -u github.com/nmrshll/gphotos-uploader-cli/cmd/gphotos-uploader-cli && cd /go/src/github.com/nmrshll && rm -rf gphotos-uploader-cli && git clone https://github.com/rfgamaral/gphotos-uploader-cli.git --branch docker && rm -rf oauth2-noserver && git clone https://github.com/rfgamaral/oauth2-noserver.git --branch docker && cd gphotos-uploader-cli/cmd/gphotos-uploader-cli && GOOS=linux GOARCH=amd64 go build -ldflags='-w -s' -o /go/bin/gphotos-uploader-cli && apk del build-dependencies
---> Running in 79c1d68ad8b0
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.2-53-g53558ad6fc [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.2-53-g53558ad6fc [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9544 distinct packages available
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/7) Installing nghttp2-libs (1.32.0-r0)
(2/7) Installing libssh2 (1.8.0-r3)
(3/7) Installing libcurl (7.61.1-r1)
(4/7) Installing expat (2.2.5-r0)
(5/7) Installing pcre2 (10.31-r0)
(6/7) Installing git (2.18.1-r0)
(7/7) Installing build-dependencies (0)
Executing busybox-1.28.4-r3.trigger
OK: 19 MiB in 21 packages
Cloning into 'gphotos-uploader-cli'...
Cloning into 'oauth2-noserver'...
(1/7) Purging build-dependencies (0)
(2/7) Purging git (2.18.1-r0)
(3/7) Purging libcurl (7.61.1-r1)
(4/7) Purging nghttp2-libs (1.32.0-r0)
(5/7) Purging libssh2 (1.8.0-r3)
(6/7) Purging expat (2.2.5-r0)
(7/7) Purging pcre2 (10.31-r0)
Executing busybox-1.28.4-r3.trigger
OK: 5 MiB in 14 packages
Removing intermediate container 79c1d68ad8b0
---> 17b221a9ee49
Step 5/17 : FROM amd64/alpine:${ALPINE_VERSION}
3.8: Pulling from amd64/alpine
169185f82c45: Already exists
Digest: sha256:616d0d0ff1583933ed10a7b3b4492899942016c0577d43a1c506c0aad8ab4da8
Status: Downloaded newer image for amd64/alpine:3.8
---> 491e0ff7a8d5
Step 6/17 : LABEL maintainer="master@ricardoamaral.net"
---> Running in e58b7fcdb220
Removing intermediate container e58b7fcdb220
---> c525e340a42d
Step 7/17 : ARG BUILD_DATE
---> Running in 0a9417e1adcd
Removing intermediate container 0a9417e1adcd
---> 9f6c69125803
Step 8/17 : ARG S6_OVERLAY_VERSION
---> Running in 93a8cd6996b9
Removing intermediate container 93a8cd6996b9
---> 6034d93430da
Step 9/17 : ARG VCS_REF
---> Running in 8f6fc7d81c71
Removing intermediate container 8f6fc7d81c71
---> 74180d38dbc0
Step 10/17 : LABEL org.label-schema.build-date="${BUILD_DATE}" org.label-schema.description="Mass upload media folders to your Google Photos account with this Docker image." org.label-schema.name="rfgamaral/gphotos-uploader" org.label-schema.schema-version="1.0" org.label-schema.vcs-ref="${VCS_REF}" org.label-schema.vcs-url="https://github.com/rfgamaral/docker-gphotos-uploader.git"
---> Running in 08cf19c6f46a
Removing intermediate container 08cf19c6f46a
---> 106104e2ef17
Step 11/17 : ENV GPU_SCHEDULE="0 */8 * * *"
---> Running in edea63c892b9
Removing intermediate container edea63c892b9
---> d69ae92742d2
Step 12/17 : ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-amd64.tar.gz /tmp/
---> a7448cda217f
Step 13/17 : RUN apk update && apk add --no-cache curl && tar xzf /tmp/s6-overlay-amd64.tar.gz -C / && rm -rf /tmp/*
---> Running in 5d9ee7e3941d
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.2-53-g53558ad6fc [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.2-53-g53558ad6fc [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9544 distinct packages available
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/5) Installing ca-certificates (20171114-r3)
(2/5) Installing nghttp2-libs (1.32.0-r0)
(3/5) Installing libssh2 (1.8.0-r3)
(4/5) Installing libcurl (7.61.1-r1)
(5/5) Installing curl (7.61.1-r1)
Executing busybox-1.28.4-r3.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 6 MiB in 18 packages
Removing intermediate container 5d9ee7e3941d
---> 14fc569893de
Step 14/17 : COPY --from=builder /go/bin/gphotos-uploader-cli /usr/local/bin/gphotos-uploader-cli
---> 32fa657de51c
Step 15/17 : COPY rootfs/ /
---> 1639f6e639b4
Step 16/17 : VOLUME ["/config", "/photos"]
---> Running in 440d1d13cd60
Removing intermediate container 440d1d13cd60
---> fd730f9c1ebb
Step 17/17 : ENTRYPOINT ["/init"]
---> Running in 197c889006b2
Removing intermediate container 197c889006b2
---> 4e66fc7b481d
Successfully built 4e66fc7b481d
Successfully tagged rfgamaral/gphotos-uploader:latest-arm32v7
Pushing index.docker.io/rfgamaral/gphotos-uploader:latest-arm32v7...
Done!
Build finished

Comme vous pouvez le voir, le journal ne fait référence qu'à amd64 et non arm32v7 ou armhf qui sont clairement là dans le fichier Dockerfile.arm32v7 . Pourquoi Docker Hub change-t-il:

  • arm32v7 / alpine: $ {ALPINE_VERSION} à amd64/alpine:${ALPINE_VERSION}
  • s6-overlay-armhf.tar.gz à s6-overlay-amd64.tar.gz
  • GOARCH = armer GOARM = 7 à GOARCH=amd64

C'est comme si on utilisait Dockerfile au lieu de Dockerfile.arm32v7 mais a) ce n'est pas ce que j'ai choisi pour "Dockerfile location" dans les builds automatisés configuration et b) Docker Hub Builds section comme un onglet "Dockerfile" pour afficher le Dockerfile utilisé pour la construction et il affiche le bon.

Est-ce un bogue sur Docker Hub ou est-ce que je fais quelque chose de mal?


0 commentaires

3 Réponses :


1
votes

L'image Docker golang: 1.11-alpine3.8 est une image multiarch. Liste des architectures disponibles:

$ docker run --rm mplatform/mquery golang:1.11-alpine3.8
Image: golang:1.11-alpine3.8
 * Manifest List: Yes
 * Supported platforms:
   - linux/amd64
   - linux/arm/v6
   - linux/arm64
   - linux/386
   - linux/ppc64le
   - linux/s390x

Donc premier problème: la plateforme arm32 / v7 n'est pas disponible pour cette image Docker. Deuxième problème: le démon Docker extraira l'image de la plate-forme, qui est la même que la plate-forme du démon Docker. Je suppose que Docker Hub fonctionne sur amd64 , donc il choisira amd64.

Ma recommandation: construire un binaire lié statique + multiplateforme Aller compiler ( GOARCH = arm GOARM = 7 ) + utilisez l'image de base SCRATCH et vous pourrez créer arm7 également avec amd64 Docker .


4 commentaires

Si je ne me trompe pas, je fais exactement ce que vous proposez, la seule différence est que j'utilise alpin au lieu de scratch et j'ai choisi le bon alpin plate-forme pour cela. De plus, cela n'explique pas vraiment pourquoi la construction change GOARCH = arm en GOARCH = amd64 . Une chose est de choisir la plate-forme appropriée en fonction du système qu'elle exécute, mais une autre consiste à modifier le contenu de mon Dockerfile. Cela n'a pas de sens.


Vous avez raison. Peut-être que arm32v7 / alpine: 3.8 est une image spéciale. Je ne parviens pas à le récupérer sur ma machine locale, il n'est pas disponible. Peut-être que Docker Hub a choisi une image équivalente (qui est amd64).


Essayez arm32v6 / alpine: 3.8 (il est disponible), au lieu de arm32v7 / alpine: 3.8 pour prouver cette théorie. Je suppose que cela échouera, car Docker Hub ne pourra pas exécuter les binaires arm32 sur la plate-forme amd63.


Vous avez raison, mais ce n'était pas mon seul problème. Consultez ma réponse pour savoir comment j'ai résolu mes problèmes. Merci de votre aide :)



13
votes

J'ai résolu mon propre problème après quelques recherches ... Premièrement, je faisais une erreur stupide et deuxièmement, j'oubliais une chose très importante. Voici comment j'ai résolu mes problèmes:

The Stupid Mistake

Bien que j'aie spécifié différents Dockerfile s pour chaque build automatisé, j'avais aussi une build hook qui remplaçait la commande docker build et était par défaut Dockerfile pour toutes les versions au lieu de choisir le bon fichier.

Corrigé build hook file:

FROM arm32v6/alpine:3.8
COPY qemu-arm-static /usr/bin/
(...)

La chose importante

Comme @JanGaraj mentionné dans sa réponse, Docker Hub fonctionne sur amd64 et il ne peut pas exécuter de binaires pour d'autres architectures. Alors, comment créer des images multi-arch avec Docker Hub Automated Builds? Avec l'aide de qemu-user-static et d'autres hooks . J'ai trouvé la réponse sur ce problème GitHub mais je posterai ici la réponse complète à mon cas d'utilisation spécifique:

Mon exemple d'arborescence de projet:

FROM arm64v8/alpine:3.8
COPY qemu-aarch64-static /usr/bin/
(...)

Le post_checkout code> fichier hook:

FROM amd64/alpine:3.8
(...)

Le fichier hook pre_build :

#!/bin/bash

BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2)

[ "${BUILD_ARCH}" == "Dockerfile" ] && \
    { echo 'qemu-user-static: Registration not required for current arch'; exit 0; }

docker run --rm --privileged multiarch/qemu-user-static:register --reset

Le fichier Dockerfile :

#!/bin/bash

BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2)

[ "${BUILD_ARCH}" == "Dockerfile" ] && \
    { echo 'qemu-user-static: Download not required for current arch'; exit 0; }

QEMU_USER_STATIC_ARCH=$([ "${BUILD_ARCH}" == "armhf" ] && echo "${BUILD_ARCH::-2}" || echo "${BUILD_ARCH}")
QEMU_USER_STATIC_DOWNLOAD_URL="https://github.com/multiarch/qemu-user-static/releases/download"
QEMU_USER_STATIC_LATEST_TAG=$(curl -s https://api.github.com/repos/multiarch/qemu-user-static/tags \
    | grep 'name.*v[0-9]' \
    | head -n 1 \
    | cut -d '"' -f 4)

curl -SL "${QEMU_USER_STATIC_DOWNLOAD_URL}/${QEMU_USER_STATIC_LATEST_TAG}/x86_64_qemu-${QEMU_USER_STATIC_ARCH}-static.tar.gz" \
    | tar xzv

Le Dockerfile. Fichier aarch64 :

.
├── Dockerfile
├── Dockerfile.aarch64
├── Dockerfile.armhf
└── hooks
    ├── build
    ├── post_checkout
    └── pre_build

Le fichier Dockerfile.armhf :

#!/bin/bash

docker build \
    --file "${DOCKERFILE_PATH}" \
    --build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
    --build-arg VCS_REF="$(git rev-parse --short HEAD)" \
    --tag "$IMAGE_NAME" \
    .

C'est tout!


1 commentaires

J'ai essentiellement suivi vos étapes pour créer mon application .NET CORE pour arch ARM32, mais j'ai toujours échoué. mon Dockerfile.armhf est démarré comme: FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.7-buster-slim-arm32‌ v7 AS base COPY qemu-arm-static / usr / bin / . À partir des journaux de construction du concentrateur de quai, je peux voir que COPY qemu-arm-static / usr / bin / a réussi. Mais la dernière partie est toujours la suivante: [91mstandard_init_linux.go: 211: processus utilisateur exec n'a causé "aucun fichier ou répertoire de ce type" et [0mLa commande '/ bin / sh -c dotnet restore " MyAppMain / Main.csproj "'a renvoyé un code différent de zéro: 1 hook de construction a échoué! (1)