Создание многоархивных образов Docker с помощью Manifest, Buildx и GitHub Actions

Когда вы работаете в среде с единой архитектурой, довольно легко иметь дело со сборкой образов docker, работающих, например, под одной и той же архитектурой «amd64».
Но что будет, если вы работаете с Macbook Air с чипом M1, который является «arm64», а вам нужно создавать образы для «amd64», или наоборот, вы работаете с машиной «amd64», а вам нужно создавать контейнеры на кластере Raspberry PI или ARM-серверов, которые набирают все большую популярность среди облачных провайдеров.

Сегодняшняя цель — научить вас с моей точки зрения и на английском языке, как генерировать мультиархитектурные или мультиархитектурные докер-образы и публиковать их на Docker Hub.

Прежде всего, необходимо иметь приложение, в моем случае я буду использовать простой Python-файл для получения информации о текущей системе. Для этого мы будем использовать библиотеку платформы

#main.py
import platform
platform_var = platform.uname()
print ("*"*30)
print (f'Machine:t{platform_var.machine}')
print (f'System:tt{platform_var.system}')
print (f'Node:tt{platform_var.node}')
print (f'Release:t{platform_var.release}')
print (f'Version:t{platform_var.version}')
print (f'Processor:t{platform_var.processor}')
print ("*"*30)
Войдите в полноэкранный режим Выход из полноэкранного режима

Следующим шагом будет создание нашего Dockerfile, как обычно, это начальная версия, позже мы внесем в нее небольшие изменения, чтобы иметь возможность визуализировать архитектуру, на которой мы строим.

FROM python:alpine3.10
WORKDIR /app
COPY . .
CMD [ "python", "main.py" ]
Войдите в полноэкранный режим Выход из полноэкранного режима

До этого момента мы можем сгенерировать изображение и запустить его.

docker build . -t jevillanueva/multiarch:latest
docker run jevillanueva/multiarch:latest
Войдите в полноэкранный режим Выход из полноэкранного режима

Где мы имеем результат, подобный этому:


Машина: x86_64
Система: Linux
Узел: 8ca0b41e5372
Выпуск: 4.19.128-microsoft-standard
Версия: #1 SMP Tue Jun 23 12:58:10 UTC 2020
Процессор:


Пока что мы знаем, что это работает. Следующим шагом будет изменение Dockerfile, в котором мы добавим пару вещей, чтобы мы могли визуализировать происходящее.

FROM  --platform=$TARGETPLATFORM python:alpine3.10
ARG TARGETPLATFORM
WORKDIR /app
RUN  echo "construyendo para $TARGETPLATFORM" > /log
COPY . .
CMD [ "python", "main.py" ]

Войдите в полноэкранный режим Выход из полноэкранного режима

Мы добавляем опцию платформы и аргумент «TARGETPLATFORM», в данном случае

Существует два способа выполнения многоархивного процесса, первый — самый старый xD, мы опишем его ниже, чтобы понять, как он работает.

МАНИФЕСТ ДОКЕРА

Все образы docker имеют манифест, манифест содержит информацию об образе, его слоях, размере и дайджесте, который является неизменяемым идентификатором для каждого образа. Для нашего многоархитектурного случая это очень важно, так как манифест содержит подробную информацию для образов с одинаковой функциональностью, но для разных операционных систем и архитектур. Вы можете увидеть больше проявлений

Давайте проверим манифест для используемого нами базового образа, который называется «python:alpine3.10».

docker manifest inspect python:alpine3.10
Войдите в полноэкранный режим Выход из полноэкранного режима

Мы получим результат, подобный этому, который покажет нам размер, его дайджест, платформы, операционную систему и их архитектуру.

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:655edcda221823fcdb79b61095dd77e6c767bf1543505dcf078f6945497c7fcf",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:16779e4847cac747c0496fc56d0daa7c2090ea6cb2e4c9aa455672d6818d7179",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v6"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:3dee5de82f12477d1f0a8ed0836181064863ba84cd8098b9c62c65f8347c656b",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:001faf6c4b5e87a3a4b251e72bb9a9dd1a5ef93083fc3a42d54e8734dc76e1f5",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:42829bfc005ccdd282d82da1328c9a2511e20f09439c702311d30627c91c70ca",
         "platform": {
            "architecture": "386",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:52e6ffac79478822ea62492d73c7aac3eca9a1cf41e8531899744e8e4958c236",
         "platform": {
            "architecture": "ppc64le",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1368,
         "digest": "sha256:90f421378ca9b94b071a20e7c4b2df746d9b4bc26dcbd85ea79f0db9322d330f",
         "platform": {
            "architecture": "s390x",
            "os": "linux"
         }
      }
   ]
}
Войдите в полноэкранный режим Выход из полноэкранного режима

До сих пор мы примерно понимали, какую важную роль играет манифест, теперь мы будем использовать его для создания многоархивных образов, так что давайте приступим к работе, мы будем делать это для двух архитектур amd64 и arm64.

Изображения с использованием манифеста

Первое, что необходимо сделать, это создать образы для каждой архитектуры

# AMD64
docker build . -t jevillanueva/multiarch:manifest-amd64 --build-arg TARGETPLATFORM=amd64
docker push jevillanueva/multiarch:manifest-amd64

# ARM64
docker build . -t jevillanueva/multiarch:manifest-arm64 --build-arg TARGETPLATFORM=arm64
docker push jevillanueva/multiarch:manifest-arm64
Войдите в полноэкранный режим Выход из полноэкранного режима

Теперь мы создали два образа для разных архитектур и опубликовали их в Docker Hub, они выглядят примерно так

Теперь давайте создадим манифест, который будет перечислять эти два изображения с разными тегами в одном блоке.

docker manifest create jevillanueva/multiarch:manifest-latest --amend jevillanueva/multiarch:manifest-amd64 --amend jevillanueva/multiarch:manifest-arm64
Войдите в полноэкранный режим Выход из полноэкранного режима

И после этого мы публикуем новый манифест

docker manifest push jevillanueva/multiarch:manifest-latest
Войдите в полноэкранный режим Выход из полноэкранного режима

Как вы можете видеть, теперь в нашем реестре есть новый тег, который относится к двум образам и их соответствующим операционным системам и архитектурам.

Мы можем проверить изображения на основе манифеста из различных экземпляров, чтобы получить результаты архитектуры с помощью python

docker run jevillanueva/multiarch:manifest-latest
Войдите в полноэкранный режим Выход из полноэкранного режима

Вот результат с моей личной машины amd64 и с машины arm64

Пока это классический и подробный способ понять, почему все так происходит xD Теперь кое-что гораздо быстрее В настоящее время существует новый инструмент, разработанный Docker, который мы можем использовать для таких сценариев, под названием «Buildx».

ДОКЕР BUILDX

Docker buildx — это инструмент, который позволяет нам получить доступ к возможностям инструмента сборки moby buildkit, он позволяет нам поддерживать несколько экземпляров, чтобы мы могли создавать наши образы для разных платформ, мы создаем экземпляр для buildx под названием «mybuild» и используем этот экземпляр.

docker buildx create --name mybuild
docker buildx use mybuild
Войдите в полноэкранный режим Выход из полноэкранного режима
docker buildx build . --push -t jevillanueva/multiarch:buildx-latest --platform linux/amd64,linux/arm64
Войдите в полноэкранный режим Выход из полноэкранного режима

После загрузки и компиляции с помощью moby/buildkit мы публикуем образ в хабе docker и получаем результат, аналогичный использованию manifest.

Таким же образом мы переходим к тестированию на разных устройствах с разными архитектурами.

Как вы видите, существует несколько способов сделать это. И, наконец, в качестве дополнения я оставляю модель действий на github для генерации мультиархитектурных образов с использованием qemu для виртуализации архитектур.

Действия на Github

name: Docker Image CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

env:
  IMAGE_NAME: ${{ github.repository }}
  IMAGE_TAG: ${{ github.sha }}

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - 
      name: Checkout
      uses: actions/checkout@v2
    -
      name: Set up QEMU
      uses: docker/setup-qemu-action@v2
    -
      name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Docker Login
      env:
        DOCKER_USER: ${{secrets.DOCKER_USER}}
        DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
      run: |
        docker login -u $DOCKER_USER -p $DOCKER_PASSWORD 
    -
      name: Build and push
      uses: docker/build-push-action@v3
      with:
        context: .
        platforms: linux/amd64,linux/arm64
        push: true
        tags: ${{ env.IMAGE_NAME }}:${{env.IMAGE_TAG}},${{ env.IMAGE_NAME }}:latest

Войдите в полноэкранный режим Выход из полноэкранного режима

Здесь вы найдете репозиторий проекта

Использованные ссылки:

https://docs.docker.com/registry/spec/manifest-v2-2/
https://docs.docker.com/engine/reference/commandline/manifest/
https://docs.docker.com/build/buildx/multiplatform-images/
https://github.com/docker/setup-buildx-action#with-qemu

Вот моя личная домашняя страница jevillanueva.dev

Оцените статью
devanswers.ru
Добавить комментарий