Scott Rossillo

Scott Rossillo

Softwareingeniør, Inception Team

AWS annoncerede for nylig en forhåndsvisning af sin nye generation af Amazon EC2 M6g-instanser, der drives af 64 bit ARM-baserede AWS Graviton2-processorer. Den forventede ydeevne og prismæssige fordele i forhold til den seneste generation af AWS x86–64-instanser er for imponerende til at ignorere.

Selvom vi simpelthen kunne bruge standard Docker på ARM til at bygge billeder til disse nye AWS Graviton-processorer, er der mange fordele ved at understøtte begge arkitekturer i stedet for at opgive x86–64-skibet:

  1. Udviklere skal kunne køre deres CI/CD-genererede Docker-billeder lokalt. I en overskuelig fremtid vil udviklermaskiner fortsætte med at bruge x86–64 CPU'er.
  2. Del fælles containere på tværs af x86–64- og Graviton2-klynger.
  3. Kør iscenesættelsesmiljøer på ARM og produktion på x86–64, indtil Graviton2 er ude af forhåndsvisning.
  4. Når Graviton2s er generelt tilgængelige, skal du hurtigt skifte tilbage til x86–64, hvis en tjenestemigrering til ARM forårsager problemer.

Opbygning af Docker-billeder med flere arkitekturer er stadig en eksperimentel funktion. Dog er hosting af multi-arkitekturbilleder allerede godt understøttet af Docker's Registry, både selvhostet og på hub.docker.com. Dit kilometertal kan variere med 3. parts Docker-registreringsimplementeringer

I dette indlæg vil vi demonstrere, hvordan man bygger og udgiver Docker-billeder med flere arkitekturer på en ARM Linux-vært til både x86–64 (AMD64) og ARM64, så du kan køre en Docker-container fra billedet på begge arkitekturer.

Bemærk: Hvis du er okay med at bygge dine billeder på dit macOS- eller Windows-skrivebord, leveres Docker Desktop ud af kassen med understøttelse af opbygning af Docker-billeder med flere arkitekturer. Men hvis du kører Linux eller ønsker at bygge dine Docker-billeder korrekt, som en del af din CI/CD-pipeline, så læs videre.

Installer Docker 19.03 eller nyere

For at starte har vi brug for en ARM64 Linux-vært, der er i stand til at køre Docker 19.03 eller nyere. Du kan også bruge en x86–64-vært.

Men da vi søger at drage fordel af omkostningsbesparelserne ved ARM, vil vi bruge en som vores build-server med Ubuntu 19.10. Ubuntu er en populær Linux-distribution, der understøttes af flere cloud-tjenester, men andre nyere distributioner burde også fungere fint. Du skal dog sørge for, at du kører en Linux-kerne 5.x eller nyere. På AWS kan du bruge Ubuntu 19.10 AMI.

På Ubuntu skal du installere docker.io til Ubuntus repository. Vi installerer også binfmt-support og qemnu-user-static. QEMU gør det muligt for en enkelt vært at bygge billeder til flere arkitekturer, og binfmt-support tilføjer understøttelse af flere binære formater til Linux-kernen. Bemærk, at binfmt-support version 2.1.43 eller senere er påkrævet.

Tilføj din bruger til Docker-gruppen for at aktivere kommandoer, der kan køres fra din brugerkonto. Husk at genstarte eller logge ud og ind igen efter at have kørt:

1. #!/bin/bash #Installer Docker og multi-arch afhængigheder
 2.
 3. sudo apt-get install binfmt-support qemu-user-static
 4. sudo apt-get install docker.io
 5. sudo usermod -aG docker $USERp
 6. sudo genstart

Installer Docker Buildx

Dernæst skal vi installere Dockers buildx -kommando. Buildx er i teknologisk preview og tilbyder eksperimentelle byggefunktioner såsom multi-arkitektur builds. Hvis du aktiverede docker til at køre som din bruger, kan du installere dette som din almindelige bruger i stedet for root.

Installer buildx kommandolinje-plugin til Docker. Koden nedenfor installerer den seneste udgivelse til ARM 64-bit.

1. #!/bin/bash
 2. #Installer buildx til arm64 og aktiver Docker CLI plugin
 3.
 4. sudo apt-get install jq
 5. mkdir -p ~/.docker/cli-plugins
 6. BUILDX_URL=$(krølle https://api.github.com/repos/docker/buildx
/udgivelser/seneste | jq -r .assets[].browser_download_url | grep arm64
 7. wget $BUILDX_URL -O ~/.docker/cli-plugins/docker-build
 8. chmod +x ~/.docker/cli-plugins/docker-buildx

Byg multiarkitekturbilleder

multi-architecture-images Opbygning af multiarkitekturbilleder (Dockers dokumentation refererer til disse som multiplatformsbilleder) kræver en builder understøttet af docker-container driveren og understøtter to strategier til opbygning af billeder på tværs af platforme:

  1. Brug af QEMU-emuleringsunderstøttelse i kernen
  2. Bygger på flere native noder koordineret af en enkelt builder

Her bruger vi QEMU-tilgangen, da den er den billigste af de to muligheder, da den kun kræver en enkelt byggevært for alle målrettede arkitekturer. Derudover bruger Docker ikke QEMU her til at skabe fuldt funktionel virtuel maskine. Vi bruger QEMU brugertilstand, så kun systemopkald skal emuleres.

Efterhånden som dine CI/CD-behov udvikler sig, ønsker du måske at investere i en byggefarm af indfødte noder for at fremskynde byggeprocessen.

Lad os oprette en bootstrap, bygherren, du kan give den et hvilket som helst navn, du ønsker:

1. $ docker buildx create --name mbuilder
 2. bygmester
 3.
 4. $ docker buildx brug mbilder
 5.
 6. $ docker buildx inspicer --bootstrap
 7. Navn: bygmester
 8. Driver: docker-container
 9.
 10. Noder:
 11. Navn: mbilder0
 12. Slutpunkt: unix:///var/run/docker.sock
 13. Status: kører
 14. Platforme: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le,
 linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

Perfekt, vi har nu en builder, der er i stand til at målrette mod linux/arm64 linux/amd64 og andre arkitekturer!

Lad os nu bygge et billede, der kan køres på både Linux amd64 og arm64 fra en simpel Dockerfile.

Bemærk, at det billede, du trækker fra, også skal understøtte de arkitekturer, du planlægger at målrette mod. Dette kan kontrolleres ved hjælp af:

$ docker buildx imagetools inspicere alpine

Dockerfile:

FRA alpint
 KØR apk tilføj util-linux
 CMD ["lscpu"]

 $ docker buildx build --platform linux/amd64, linux/arm64 -t foo4u/demo-mutliarch:2 --push .
[+] Bygning 4,7s (9/9) FÆRDIG
 => [intern] load build definition fra Dockerfile
 => => overførsel af dockerfil: 31B
 => [intern] load .dockerignore 
 => => overførsel af kontekst: 2B
 => [linux/amd64 intern] indlæs metadata til docker.io/library/alpine:latest 
 => [linux/arm64 intern] indlæs metadata til docker.io/library/alpine:latest
 => [linux/amd64 1/2] FRA docker.io/library/alpine@sha256:2171658620155679240babee0a7714f6509fae66898db422ad803b951257db78
 => => løs docker.io/library/alpine@sha256:2171658620155679240babee0a7714f6509fae66898db422ad803b951257db78
 => CACHED [linux/amd64 2/2] KØR apk tilføj util-linux
 => [linux/arm64 1/2] FRA docker.io/library/alpine@sha256:2171658620155679240babee0a7714f6509fae66898db422ad803b951257db78
 => => løs docker.io/library/alpine@sha256:2171658620155679240babee0a7714f6509fae66898db422ad803b951257db78 
 => CACHED [linux/arm64 2/2] KØR apk tilføj util-linux
 => eksporterer til billede
 => => eksporterer lag
 => => eksporterer manifest sha256:cb54200a7c04dded134ca9e3e6a0e434c2fdf851fb3a7226941d0983ad5bfb88
 => => eksporterer konfiguration sha256:307b885367f8ef4dc443dc35d6ed3298b9a3a48a846cf559a676c028a359731b
 => => eksporterer manifest sha256:6f4fe17def66ef5bc79279448e1cb77a1642d460ed58d5dc60d0e472c023e2eb
 => => eksporterer konfiguration sha256:26e6b092c7c1efffe51ce1d5f68e3359ab44152d33df39e5b85cd4ff6cfed3d4
 => => eksporterer manifestliste sha256:3b4e4135b92017e5214421543b813e83a77fcea759af8067c685b70a5d978497
 => => skubbe lag
 => => pusher manifest for docker.io/foo4u/demo-mutliarch:2

Der sker en masse her, så lad os pakke det ud:
 1. Docker overfører build-konteksten til vores builder-container
 2. Bygherren bygger et billede for hver arkitektur, vi anmodede om, med argumentet --platform
 3. Billederne skubbes til Docker Hub
 4. Buildx genererer en manifest JSON-fil og skubber den til Docker Hub som billedmærket.

Lad os bruge imagetools til at inspicere det genererede Docker-billede:

1. $ docker buildx imagetools inspicer foo4u/demo-mutliarch:2
 2. Navn: docker.io/foo4u/demo-mutliarch:2
3. MediaType: application/vnd.docker.distribution.manifest.list.v2+json
 4. Digest: sha256:3b4e4135b92017e5214421543b813e83a77fcea759af8067c685b70a5d978497
 5.
 6. Manifester:
 7. Navn: docker.io/foo4u/demo-mutliarch:2@sha256:cb54200a7c04dded134ca9e3e6a0e434c2fdf851fb3a7226941d0983ad5bfb88
8. MediaType: application/vnd.docker.distribution.manifest.v2+json
9. Platform: linux/amd64
 10.
 11. Navn: docker.io/foo4u/demo-12. mutliarch:2@sha256:6f4fe17def66ef5bc79279448e1cb77a1642d460ed58d5dc60d0e472c023e2eb
 12. MediaType: application/vnd.docker.distribution.manifest.v2+json
13. Platform: linux/arm64

Her kan vi se, at foo4u/demo-multiarch:2 er et JSON-manifest, der peger på manifesterne for hver af de platforme, vi målrettede under opbygningen. Selvom billedet vises i registreringsdatabasen som et enkelt billede, er det faktisk et manifest, der indeholder links til de platformsspecifikke billeder. Buildx byggede og publicerede et billede pr. arkitektur og genererede derefter et manifest, der knyttede dem sammen.

Docker bruger disse oplysninger, når billedet trækkes, for at downloade det passende billede til maskinens runtime-arkitektur.

Lad os køre billedet på x86–64 / amd64:

$ docker run --rm foo4u/demo-mutliarch:2
 Kan ikke finde billedet 'foo4u/demo-mutliarch:2' lokalt
 2: Trækker fra foo4u/demo-mutliarch
 e6b0cf9c0882: Eksisterer allerede
 Status: Downloadet nyere billede til foo4u/demo-mutliarch:2
 Arkitektur: x86_64

Lad os nu køre billedet på arm64:

$ docker run --rm foo4u/demo-mutliarch:2
 Kan ikke finde billedet 'foo4u/demo-mutliarch:2' lokalt
 2: Trækker fra foo4u/demo-mutliarch
 Status: Downloadet nyere billede til foo4u/demo-mutliarch:2
 Arkitektur: aarch64

Det er det! Nu har vi et fuldt fungerende Docker-image, som vi kan køre på enten vores eksisterende x86–64-servere eller vores skinnende nye ARM 64-servere!

Afslutningsvis er det ikke så svært at komme i gang med Docker-billeder med flere arkitekturer på Linux. Vi kan endda bruge en ARM-server til at bygge billederne, hvilket potentielt kan spare os penge på vores CI/CD-server(e) samt vores iscenesættelse og produktionsinfrastruktur.

Bonus: du kan optimere dine Docker-bygninger yderligere, hvis det sprog, du bruger til, har god multi-arkitektur-understøttelse (såsom Java eller Go). For eksempel kan du bygge en Spring Boot-applikation med en enkelt platformskompilering:

1. FRA --platform=$BUILDPLATFORM amazoncorretto:11 som bygherre
 2.
 3. KOPI . /srv/
 4. WORKDIR /srv
 5. KØR ./mvnw -DskipTests=true package spring-boot:repackage
 6.
 7. FRA amazoncorretto:11
 8.
 9. COPY --from=builder /srv/target/my-service-0.0.1-SNAPSHOT.jar /srv/
 10.
 11. EXPOSE 8080
 12.
 13. ENTRYPOINT ["java", "-jar", "/srv/my-service-0.0.1-SNAPSHOT.jar"]

Hvorfor ikke oversætte mere intelligent?

Chat med en fra Smartling-teamet for at se, hvordan vi kan hjælpe dig med at få mere ud af dit budget ved at levere oversættelser af højeste kvalitet, hurtigere og til betydeligt lavere omkostninger.
Cta-Card-Side-Image