Использование Docker manifest для создания многоархитектурных образов на процессорах AWS Graviton

Docker manifest — это экспериментальная команда для создания образов docker, поддерживающих несколько архитектур. Давайте посмотрим, как она работает, и сравним ее с docker buildx.

В 2019 году docker buildx был создан как способ построения мультиархитектурных образов. В то время у разработчиков не было Arm в облаке или на рабочем столе. Проекты были заинтересованы в архитектуре Arm, но как вторичный вариант для AWS Graviton или даже Raspberry Pi. С помощью buildx одна команда сборки создает образ с несколькими архитектурами. В некоторых случаях для сборки даже не требуется машина Arm.

Сегодня разработчики используют архитектуру Arm на своем рабочем столе и в облаке. Новаторский успех процессоров AWS Graviton побудил разработчиков попробовать Graviton на практике. Популярность компьютеров Mac с кремнием Apple означает, что у многих разработчиков на столе стоит та же архитектура. Сегодня я расскажу, как создавать многоархивные образы с помощью команды docker manifest. Я обнаружил, что это самый простой способ создания многоархивных образов для многих проектов.

Справочная информация

Docker buildx предоставляет команду сборки для создания образов для нескольких архитектур. Я в основном использую arm64 и amd64. Если вы используете другие архитектуры, концепция может быть легко расширена.

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

Docker buildx также сбивает с толку разработчиков, которые ожидают, что локальный образ будет немедленно запущен после успешной сборки. Поскольку buildx предназначен для нескольких архитектур, его необходимо сохранять в репозиторий, а не в локальное хранилище. Для этого требуется push в хранилище, а затем pull для запуска. Есть и другие обходные пути, но модель использования отличается от того, что ожидают многие разработчики. Поиск на Stack Overflow и GitHub подтверждает, что отсутствие изображения после успешного запуска buildx — распространенный вопрос.

Я трачу большую часть своего времени на архитектуру Arm. Все меньшее число проектов требует поддержки amd64, но когда это происходит, я стараюсь избегать buildx. Docker buildx — один из способов решения проблем, связанных с несколькими архитектурами, но docker manifest кажется мне проще.

Давайте посмотрим, как это работает.

Docker manifest

Docker включает экспериментальную функцию под названием docker manifest. Пожалуйста, имейте в виду, что эта функция является экспериментальной и не рекомендуется для использования в производстве.

Docker manifest обеспечивает другой способ работы. Он позволяет создавать отдельные образы для каждой архитектуры, которые могут быть объединены в многоархитектурный образ, когда приходит время поделиться. Это позволяет мне собирать и тестировать на любой архитектуре и отложить использование multi-arch на потом. Когда приходит время поделиться многоархитектурным образом, он может быть создан за считанные секунды с помощью docker manifest. Docker manifest также позволяет легко обновлять одну из архитектур без эмуляции или удаленных сборщиков.

Давайте проведем небольшое сравнение между buildx и docker manifest.

Вот небольшой пример Dockerfile.

FROM alpine AS builder
RUN apk add build-base
WORKDIR /home
COPY hello.c .
RUN gcc "-DARCH="`uname -a`"" hello.c -o hello

FROM alpine
WORKDIR /home
COPY --from=builder /home/hello .
CMD ["./hello"]
Войти в полноэкранный режим Выход из полноэкранного режима

Dockerfile компилирует и запускает программу hello world на C.

#include <stdio.h>
#include <stdlib.h>

#ifndef ARCH
#define ARCH "Undefined"
#endif

int main()
{
    printf("Hello Arm Developers, architecture from uname is %sn", ARCH);

    switch (sizeof(void *))
    {
        case 4:
            printf("32-bit userspacen");
            break;
        case 8:
            printf("64-bit userspacen");
            break;
        default:
            printf("unknown userspacen");
    }
    exit(0);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Скопируйте Dockerfile и hello.c на свой компьютер для выполнения следующих шагов.

Давайте посмотрим, как использовать его с помощью buildx для сборки мультиархитектурного образа.

Docker buildx

Использование buildx подразумевает настройку билдера и выполнение команды buildx.

Ниже приведен сценарий, показывающий, как использовать buildx. Скопируйте файл, измените переменную HUBU на ваше имя пользователя Docker Hub и запустите скрипт, чтобы попробовать.

#!/bin/bash

HUBU=hubuser
IMG=hello-world

docker buildx create --name mybuilder
docker buildx use mybuilder
docker buildx build --platform linux/amd64,linux/arm64 -t $HUBU/$IMG --push .

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

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

Существует множество руководств по использованию buildx, если вы хотите узнать больше.

Манифест Docker

Команда docker manifest полезна для объединения нескольких существующих образов в один мультиархитектурный образ.

Чтобы отслеживать образы, я использую тег image для указания архитектуры.

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

docker build -t hello-world:$(arch) .
Вход в полноэкранный режим Выйти из полноэкранного режима

Образ доступен для запуска локально. На AWS Graviton тег будет aarch64, чтобы отличить его от той же команды, запущенной на машине x86_64.

После создания образа на каждой машине, которую вы хотите поддерживать, отметьте образы для учетной записи Docker Hub и проведите push. Снова измените имя пользователя Docker Hub, чтобы попробовать.

docker tag hello-world:$(arch) jasonrandrews/hello-world:$(arch)
docker push jasonrandrews/hello-world:$(arch)
Вход в полноэкранный режим Выход из полноэкранного режима

На изображении ниже показаны обе метки в Docker Hub.

Последним шагом будет объединение двух меток в один мультиархитектурный образ.

docker manifest create jasonrandrews/hello-world:latest 
--amend jasonrandrews/hello-world:aarch64 
--amend jasonrandrews/hello-world:x86_64

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

Опция purge не нужна в первый раз, но я обнаружил, что для обновления одного из образов и обновления многоархитектурного образа она необходима.

После обновления манифеста будет доступен новый многоархивный образ с последним тегом. Вытаскивание hello-world:latest из любой архитектуры теперь работает, и пользователю не нужно обращать внимание на то, какой компьютер он использует.

Резюме

Экспериментальная команда docker manifest предлагает способ создания мультиархитектурных образов путем объединения нескольких образов с помощью манифеста. Docker manifest предоставляет дополнительные возможности, не рассмотренные здесь, и полезен для создания, проверки и изменения списков манифестов. По мере развития команды docker manifest и расширения использования AWS Graviton разработчиками, она предоставляет еще один способ создания образов docker.

Попробуйте и посмотрите, как это работает.

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