Multi-Architecture Builds

Learn how to create and distribute Docker images that run on multiple hardware architectures

Docker-ის მრავალარქიტექტურული აგება

მრავალარქიტექტურული (multi-arch) აგება საშუალებას გაძლევთ შექმნათ Docker-ის იმიჯები, რომლებიც სხვადასხვა აპარატურულ არქიტექტურაზე მუშაობს. ეს უზრუნველყოფს ნამდვილი "ერთხელ ააგე, ყველგან გაუშვი" შესაძლებლობას მრავალფეროვან გარემოში. თითოეული არქიტექტურისთვის ცალკე იმიჯების შენახვის ნაცვლად, მრავალარქიტექტურული იმიჯები უზრუნველყოფს გამარტივებულ გამოცდილებას, სადაც კონტეინერის რანთაიმი ავტომატურად ირჩევს შესაბამის იმიჯს ჰოსტის არქიტექტურის მიხედვით.

რატომ არის მნიშვნელოვანი მრავალარქიტექტურული აგება

პლატფორმათაშორისი თავსებადობა

  • x86_64 (Intel/AMD) მხარდაჭერა: ტრადიციული სერვერისა და დესკტოპის არქიტექტურა, ფართოდ გამოიყენება მონაცემთა ცენტრებში და საწარმოებში
  • ARM64 მხარდაჭერა (Apple Silicon, AWS Graviton): პოპულარობა იზრდება წარმადობისა და ენერგოეფექტურობის გამო; კრიტიკულია MacOS-ის განვითარებისთვის და ARM-ზე დაფუძნებული cloud-ინსტანცებისთვის
  • 32-ბიტიანი ARM მხარდაჭერა (IoT მოწყობილობები): აუცილებელია edge computing-ისთვის, Raspberry Pi-სა და ჩაშენებული სისტემებისთვის
  • IBM Power და s390x არქიტექტურები: გამოიყენება საწარმოო mainframe გარემოებში სპეციფიკური წარმადობისთვის
  • ერთი იმიჯის რეფერენსი ყველა პლატფორმისთვის: მომხმარებლებს შეუძლიათ ერთი და იგივე ტეგის იმიჯის გადმოწერა, მიუხედავად მათი აპარატურისა

ღრუბლოვანი მოქნილობა

  • კონტეინერების გაშვება ხელმისაწვდომ ARM ინსტანცებზე: ARM-ზე დაფუძნებული ინსტანციები, როგორიცაა AWS Graviton, უზრუნველყოფს 40%-მდე უკეთეს ფას-წარმადობის შეფარდებას
  • ღრუბლოვან პროვაიდერებს შორის მარტივი გადართვა: შეგიძლიათ შეცვალოთ პროვაიდერი ან არქიტექტურა კონფიგურაციის ცვლილების გარეშე
  • არქიტექტურაზე დამოკიდებული ტეგების საჭიროება არ არის: ამარტივებს CI/CD პროცესებს და თავიდან იცილებს დაბნეულობას
  • განვითარების თანმიმდევრული გამოცდილება: დეველოპერებს შეუძლიათ იმუშაონ როგორც x86, ასევე ARM მოწყობილობებზე და დარწმუნდნენ, რომ პროდუქციაში ყველაფერი იმუშავებს
  • მომავლისთვის მზად კონტეინერის სტრატეგია: მზად ხართ ახალი არქიტექტურებისთვის ინფრასტრუქტურის თავიდან აგების გარეშე

BuildKit და მრავალარქიტექტურული მხარდაჭერა

BuildKit არის Docker-ის ახალი თაობის აგების სისტემა, რომელიც უზრუნველყოფს მრავალარქიტექტურულ აგებას, გაუმჯობესებულ ქეშირებას და პარალელურ აგებას. ის წარმოადგენს buildx-ის საფუძველს, რომელიც Docker-ის CLI პლაგინია მრავალარქიტექტურული იმიჯების ასაგებად.

# BuildKit-ის ჩართვა (თუ ჯერ არ არის ჩართული)
export DOCKER_BUILDX=1
# ან კონკრეტული ბრძანებისთვის
export DOCKER_BUILDKIT=1

# ხელმისაწვდომი buildx ბილდერების ნახვა
docker buildx ls
# გამოიტანს თქვენს ბილდერებს და მხარდაჭერილ პლატფორმებს

# ახალი ბილდერის შექმნა გაფართოებული შესაძლებლობებით
docker buildx create --name mybuilder --use
# ეს ქმნის ახალ ბილდერს, რომელიც მრავალ პლატფორმაზე აგებს

# მხარდაჭერილი პლატფორმების ინსპექტირება და ბილდერის ინიციალიზაცია
docker buildx inspect --bootstrap
# გამოიტანს ყველა არქიტექტურას, რომელსაც ეს ბილდერი უჭერს მხარს (ჩვეულებრივ linux/amd64, linux/arm64, linux/arm/v7)

--bootstrap პარამეტრი ინიციალიზაციას უკეთებს ბილდერს და ამზადებს მას ყველა მხარდაჭერილი პლატფორმისთვის. BuildKit იყენებს ან QEMU ემულაციას, ან ნატურალურ აგებას სხვადასხვა არქიტექტურის იმიჯების შესაქმნელად.

მრავალარქიტექტურული იმიჯების შექმნა

აგება Docker Compose-ით

Docker Compose ასევე შეიძლება გამოყენებულ იქნას მრავალარქიტექტურული იმიჯების ასაგებად Buildx-თან ერთად. ეს განსაკუთრებით სასარგებლოა მრავალი სერვისის მქონე აპლიკაციებისთვის:

# docker-compose.yml პლატფორმის მხარდაჭერით
version: '3.8'
services:
  app:
    build:
      context: .
      platforms:
        - linux/amd64  # Intel/AMD 64-ბიტი
        - linux/arm64  # ARM 64-ბიტი (Apple Silicon, Graviton)
    image: username/myapp:latest

# ასაგებად და გამოსაქვეყნებლად docker-compose-ით:
# DOCKER_BUILDKIT=1 docker-compose build
# docker-compose push

ამ მიდგომის გამოყენებისას, თქვენ უნდა:

  1. დარწმუნდეთ, რომ BuildKit ჩართულია
  2. ააგოთ იმიჯები docker-compose build-ით
  3. გამოაქვეყნოთ იმიჯები docker-compose push-ით
  4. რთული, მრავალსერვისიანი აპლიკაციებისთვის, შეგიძლიათ მიუთითოთ სხვადასხვა პლატფორმის მოთხოვნები თითოეული სერვისისთვის

Compose ფაილი ასევე შეიძლება შეიცავდეს პლატფორმა-სპეციფიკურ build არგუმენტებს ან კონფიგურაციებს საჭიროებისამებრ.

მანიფესტების სიები

მანიფესტების სიები (ასევე ცნობილი როგორც "fat manifests") არის მექანიზმი, რომელიც უზრუნველყოფს მრავალარქიტექტურულ მხარდაჭერას. ისინი მოქმედებენ როგორც მაჩვენებლები არქიტექტურა-სპეციფიკურ იმიჯის ვარიანტებზე.

მანიფესტების სიების ხელით შექმნა

# არქიტექტურა-სპეციფიკური იმიჯების აგება ცალკეული ტეგებით
docker build -t username/myapp:amd64 --platform linux/amd64 .
docker build -t username/myapp:arm64 --platform linux/arm64 .

# მანიფესტის სიის შექმნა, რომელიც ორივე არქიტექტურის ვარიანტს მიუთითებს
docker manifest create username/myapp:latest \
  username/myapp:amd64 \
  username/myapp:arm64

# მანიფესტის სიის გამოქვეყნება რეესტრში
docker manifest push username/myapp:latest

ეს ხელით მიდგომა გაძლევთ დეტალურ კონტროლს, როდესაც:

  • გჭირდებათ იმიჯების ცალ-ცალკე აგება თითოეული არქიტექტურისთვის
  • სხვადასხვა არქიტექტურა მოითხოვს სხვადასხვა აგების პროცესებს
  • გსურთ არქიტექტურა-სპეციფიკური იმიჯების ტესტირება მანიფესტის შექმნამდე

მანიფესტების შემოწმება

# მანიფესტის დეტალების ნახვა, ყველა არქიტექტურის ვარიანტის ჩათვლით
docker manifest inspect username/myapp:latest

# გამოტანილი შედეგი აჩვენებს დეტალებს, როგორიცაა:
# - მხარდაჭერილი არქიტექტურები და OS
# - დაიჯესტი (შიგთავსის ჰეში) თითოეული ვარიანტისთვის
# - თითოეული ვარიანტის ზომა
# - პლატფორმა-სპეციფიკური ანოტაციები

inspect ბრძანება ღირებულია იმის დასადასტურებლად, რომ თქვენი მანიფესტი მოიცავს ყველა მოსალოდნელ არქიტექტურას და არქიტექტურა-სპეციფიკურ ვარიანტებთან დაკავშირებული ნებისმიერი პრობლემის გამოსასწორებლად.

საბაზისო იმიჯის მოსაზრებები

კროს-კომპილაცია QEMU ემულაციის წინააღმდეგ

Docker-ი გთავაზობთ მრავალარქიტექტურული იმიჯების აგების ორ ძირითად მიდგომას, თითოეულს თავისი დადებითი და უარყოფითი მხარეებით:

# აგება QEMU ემულაციით (უფრო მარტივი, მაგრამ ნელი)
# მოითხოვს: docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx build --platform linux/arm64 \
  -t username/myapp:arm64 \
  --load .

QEMU ემულაცია:

  • ✅ მუშაობს ნებისმიერ Dockerfile-თან ცვლილებების გარეშე
  • ✅ უფრო მარტივია დასაყენებლად და გამოსაყენებლად
  • ✅ თავსებადია აგების უმეტეს პროცესებთან
  • ❌ მნიშვნელოვნად ნელია (5-10x) ნატიურ აგებასთან შედარებით
  • ❌ შეიძლება ჰქონდეს თავსებადობის პრობლემები ზოგიერთ სისტემურ გამოძახებებთან
# კროს-კომპილაცია (უფრო სწრაფი, მაგრამ უფრო რთული)
# მაგალითი Go აპლიკაციისთვის ნატიური კროს-კომპილაციით
FROM --platform=$BUILDPLATFORM golang:1.18 AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
WORKDIR /app
COPY . .
RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM" && \
    case "$TARGETPLATFORM" in \
      "linux/amd64") GOARCH=amd64 ;; \
      "linux/arm64") GOARCH=arm64 ;; \
      "linux/arm/v7") GOARCH=arm ;; \
    esac && \
    CGO_ENABLED=0 GOOS=linux GOARCH=$GOARCH go build -o app .

FROM alpine:3.16
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]

კროს-კომპილაცია:

  • ✅ ბევრად სწრაფი აგება (ნატიურთან მიახლოებული სიჩქარე)
  • ✅ არ არის ემულაციის ზედნადები
  • ✅ უკეთესია დიდი აპლიკაციებისთვის
  • ❌ მოითხოვს ენის/ინსტრუმენტების მხარდაჭერას კროს-კომპილაციისთვის
  • ❌ უფრო რთული Dockerfile მრავალსაფეხურიანი აგებით
  • ❌ შეიძლება მოითხოვოს პლატფორმა-სპეციფიკური კოდის ნაწილები

ზემოთ მოყვანილი მაგალითი აჩვენებს:

  1. $BUILDPLATFORM-ის გამოყენებას - არქიტექტურა, სადაც აგება მიმდინარეობს
  2. $TARGETPLATFORM-ის გამოყენებას - არქიტექტურა, რომლისთვისაც ვაგებთ
  3. მრავალსაფეხურიან აგებას საბოლოო იმიჯის ზომის შესამცირებლად
  4. პლატფორმა-სპეციფიკურ კომპილაციის დროშებს

CI/CD ინტეგრაცია მრავალარქიტექტურული აგებისთვის

მრავალარქიტექტურული აგების CI/CD პროცესებში ინტეგრაცია უზრუნველყოფს იმიჯების თანმიმდევრულ შექმნას და გავრცელებას სხვადასხვა პლატფორმაზე.

GitHub Actions-ის მაგალითი

name: მრავალარქიტექტურული იმიჯის აგება

on:
  push:
    branches: [ main ]
  # სურვილისამებრ, რელიზებისთვის ტეგებზე გაშვება
  tags:
    - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: კოდის გადმოწერა
        uses: actions/checkout@v3
        
      - name: QEMU-ს დაყენება
        uses: docker/setup-qemu-action@v2
        # ეს აყენებს QEMU-ს სტატიკურ ბინარებს მრავალარქიტექტურული აგებისთვის
        
      - name: Docker Buildx-ის დაყენება
        uses: docker/setup-buildx-action@v2
        # ქმნის ახალ ბილდერის ინსტანციას მრავალარქიტექტურული მხარდაჭერით
        
      - name: DockerHub-ზე შესვლა
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
          # ავთენტიფიკაცია Docker Hub-ზე გამოქვეყნების გასააქტიურებლად
          
      - name: Docker-ისთვის მეტამონაცემების ამოღება
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: username/myapp
          # ავტომატურად გენერირებს ტეგებს ბრენჩებისა და ვერსიის ტეგების მიხედვით
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=ref,event=branch
          
      - name: აგება და გამოქვეყნება
        uses: docker/build-push-action@v4
        with:
          context: .
          platforms: linux/amd64,linux/arm64  # მიუთითეთ სამიზნე არქიტექტურები
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=registry,ref=username/myapp:buildcache
          cache-to: type=registry,ref=username/myapp:buildcache,mode=max
          # ქეშირება აუმჯობესებს აგების წარმადობას ხშირი აგებისას

GitHub Actions-ის მაგალითი მოიცავს:

  • ავტომატურ ტეგების გენერაციას Git-ის ტეგებისა და ბრენჩების მიხედვით
  • აგების ქეშირებას განმეორებითი აგების დასაჩქარებლად
  • QEMU-ს დაყენებას არქიტექტურის ემულაციისთვის
  • რეესტრში ავთენტიფიკაციას იმიჯების გამოსაქვეყნებლად

GitLab CI-ის მაგალითი

build-multi-arch:
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind  # Docker-in-Docker სერვისი
  variables:
    DOCKER_BUILDKIT: 1
    DOCKER_TLS_CERTDIR: "/certs"  # TLS-ის ჩართვა Docker-in-Docker-ისთვის
    BUILDX_VERSION: "0.9.1"       # buildx-ის ვერსიის მითითება
  before_script:
    # რეესტრში შესვლა
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    
    # buildx-ის დაყენება მრავალარქიტექტურული მხარდაჭერით
    - mkdir -p ~/.docker/cli-plugins
    - wget -O ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-amd64
    - chmod +x ~/.docker/cli-plugins/docker-buildx
    - docker context create builder-context
    - docker buildx create --name mybuilder --use builder-context
    - docker buildx inspect --bootstrap
    
    # ტეგის დაყენება CI_COMMIT_REF_NAME-ის მიხედვით
    - |
      if [[ $CI_COMMIT_TAG ]]; then
        export IMAGE_TAG=$CI_COMMIT_TAG
      else
        export IMAGE_TAG=$CI_COMMIT_REF_NAME
      fi
  script:
    - docker buildx build --platform linux/amd64,linux/arm64 
      -t $CI_REGISTRY_IMAGE:$IMAGE_TAG 
      -t $CI_REGISTRY_IMAGE:latest 
      --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') 
      --build-arg VCS_REF=$CI_COMMIT_SHA 
      --push .
  # გაშვება როგორც ბრენჩის push-ზე, ასევე ტეგებზე
  rules:
    - if: $CI_COMMIT_BRANCH || $CI_COMMIT_TAG

GitLab CI-ის მაგალითი მოიცავს:

  • buildx-ის ხელით დაყენებას (დეტალური კონტროლისთვის)
  • ტეგების გენერაციას Git-ის ბრენჩებისა და ტეგების მიხედვით
  • აგების არგუმენტებს იმიჯის მეტამონაცემებისთვის
  • TLS უსაფრთხოებას Docker-in-Docker სერვისისთვის

მრავალარქიტექტურული იმიჯების ტესტირება

მრავალარქიტექტურული იმიჯების ტესტირება კრიტიკულად მნიშვნელოვანია იმის უზრუნველსაყოფად, რომ ისინი სწორად მუშაობენ ყველა სამიზნე პლატფორმაზე. Docker-ი გაძლევთ საშუალებას, მოახდინოთ სხვადასხვა არქიტექტურის ემულაცია ტესტირების მიზნით:

# arm64 იმიჯის ტესტირება amd64 მანქანაზე ემულაციის გამოყენებით
docker run --platform linux/arm64 username/myapp:latest
# ეს აიძულებს Docker-ს გამოიყენოს ARM64 ვარიანტი, თუნდაც x86_64 ჰოსტზე

# არქიტექტურის შემოწმება კონტეინერის შიგნით ემულაციის დასადასტურებლად
docker run --platform linux/arm64 username/myapp:latest uname -m
# უნდა გამოიტანოს: aarch64 (ARM64 არქიტექტურა)

# არქიტექტურა-სპეციფიკური ტესტების გაშვება
docker run --platform linux/arm64 username/myapp:latest ./run-tests.sh

# წარმადობის ტესტირება (გაითვალისწინეთ: ემულაცია უფრო ნელი იქნება, ვიდრე ნატიური შესრულება)
docker run --platform linux/arm64 username/myapp:latest benchmark

# ტესტირება სხვადასხვა არქიტექტურაზე ყველა ვარიანტის დასადასტურებლად
for arch in linux/amd64 linux/arm64 linux/arm/v7; do
  echo "ვტესტავ $arch..."
  docker run --platform $arch username/myapp:latest ./verify-platform.sh
done

გახსოვდეთ, რომ ემულაციის ქვეშ ტესტირებას აქვს შეზღუდვები:

  1. წარმადობა მნიშვნელოვნად ნელი იქნება ნატიურ შესრულებასთან შედარებით
  2. ზოგიერთი არქიტექტურა-სპეციფიკური პრობლემა შეიძლება მხოლოდ რეალურ აპარატურაზე გამოჩნდეს
  3. სისტემური გამოძახებები და აპარატურა-სპეციფიკური ფუნქციები შეიძლება განსხვავებულად მოიქცნენ
  4. მეხსიერების გამოყენების ნიმუშები შეიძლება განსხვავდებოდეს ემულირებულ და ნატიურ გარემოებს შორის

კრიტიკული აპლიკაციებისთვის, ემულაციის ტესტირების გარდა, განიხილეთ ტესტირება თითოეული სამიზნე არქიტექტურის რეალურ აპარატურაზე.

საუკეთესო პრაქტიკები

გაფართოებული ტექნიკები

არქიტექტურა-სპეციფიკური ოპტიმიზაციები

FROM --platform=$TARGETPLATFORM python:3.10-slim

# არქიტექტურა-სპეციფიკური ოპტიმიზაციების ინსტალაცია
RUN case "$(uname -m)" in \
      "x86_64") \
        apt-get update && apt-get install -y --no-install-recommends \
        libjemalloc2 && \
        # გამოიყენეთ jemalloc მეხსიერების ალოკატორი უკეთესი წარმადობისთვის x86_64-ზე
        echo "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2" > /etc/ld.so.preload \
        ;; \
      "aarch64") \
        apt-get update && apt-get install -y --no-install-recommends \
        # libatomic1 საჭიროა ზოგიერთი ოპერაციისთვის ARM64-ზე
        libatomic1 \
        # ARM-სპეციფიკური ოპტიმიზაციები
        && apt-get install -y --no-install-recommends libneon27 \
        ;; \
      "armv7l") \
        # 32-ბიტიანი ARM-სპეციფიკური პაკეტები
        apt-get update && apt-get install -y --no-install-recommends \
        libatomic1 libarmmem-${TARGETARCH} \
        ;; \
      *) \
        echo "არქიტექტურა $(uname -m) არ არის ოპტიმიზირებული, გამოიყენება ნაგულისხმევი პარამეტრები" \
        ;; \
    esac

# გააგრძელეთ საერთო დაყენებით
COPY requirements.txt .
RUN pip install -r requirements.txt

ეს Dockerfile აჩვენებს:

  • არქიტექტურის ამოცნობას uname -m-ის გამოყენებით
  • არქიტექტურა-სპეციფიკური წარმადობის ბიბლიოთეკების ინსტალაციას
  • სარეზერვო ვარიანტს არამხარდაჭერილი არქიტექტურებისთვის
  • მეხსიერების ალოკატორის ოპტიმიზაციებს x86_64-სთვის
  • ARM-სპეციფიკურ ბიბლიოთეკებს უკეთესი წარმადობისთვის

პლატფორმა-სპეციფიკური აგება

# docker-compose.override.yml
services:
  app:
    build:
      args:
        - TARGETARCH=${TARGETARCH:-amd64}
        # ნაგულისხმევად amd64, თუ არ არის მითითებული
        
        # დამატებითი პლატფორმა-სპეციფიკური აგების არგუმენტები
        - EXTRA_FEATURES=${EXTRA_FEATURES:-}
        # შეიძლება დაყენდეს განსხვავებულად თითოეული არქიტექტურისთვის CI/CD-ში
    
    # პირობითად გამოიყენეთ პლატფორმა-სპეციფიკური ვოლუმები ან კონფიგურაციები
    volumes:
      - ${PLATFORM_SPECIFIC_VOLUME:-/tmp}:/opt/platform-specific

პლატფორმა-სპეციფიკურ აგებას ასევე შეუძლია გამოიყენოს:

# აგების სკრიპტი პლატფორმა-სპეციფიკური კონფიგურაციების გენერირებისთვის
#!/bin/bash
TARGETARCH=${TARGETARCH:-$(uname -m)}

case "$TARGETARCH" in
  "x86_64"|"amd64")
    # x86-სპეციფიკური კონფიგურაციის გენერირება
    echo "ვქმნი x86_64 ოპტიმიზირებულ კონფიგურაციას"
    cat base-config.json | jq '.optimizations.simd = true' > config.json
    ;;
  "aarch64"|"arm64")
    # ARM64-სპეციფიკური კონფიგურაციის გენერირება
    echo "ვქმნი ARM64 ოპტიმიზირებულ კონფიგურაციას"
    cat base-config.json | jq '.optimizations.neon = true' > config.json
    ;;
esac

# პლატფორმა-სპეციფიკური აგების ნაბიჯების გაშვება
docker-compose build

ეს მიდგომა გაძლევთ საშუალებას:

  1. შექმნათ პლატფორმა-სპეციფიკური კონფიგურაციის ფაილები აგებამდე
  2. გადასცეთ სხვადასხვა აგების არგუმენტები სამიზნე არქიტექტურის მიხედვით
  3. გამოიყენოთ პირობითი ლოგიკა Dockerfile-ის გარეთ
  4. შექმნათ მორგებული დეპლოიმენტები თითოეული პლატფორმისთვის

Troubleshooting