Java™ в Docker на Apple Silicon – быстро и просто
11 августа 2021 г.
В июне 2020 года Apple объявила о переводе Mac с процессоров Intel x86_64 на однокристальные процессоры Apple Silicon на базе архитектуры ARM64. Это вызвало определенные трудности у разработчиков, пользующихся средствами низкоуровневого программирования для создания приложений. К счастью, IT-индустрия была к этому готова, поэтому переход выполняется довольно плавно. Компания Apple и разработчики на Mac постепенно адаптируют свой софт под новую платформу. Кроме того, не стоит забывать о технологии Rosetta (инструмент для запуска x86 приложений на arm64): она позволяет на время перехода решить проблему совместимости. Также вышли обновления важных программных средств, включая Docker, благодаря чему использование JDK в Docker на новых компьютерах Mac стало таким же быстрым и простым, как раньше.
В данной статье мы подробно опишем процесс установки Docker и контейнеризации Java-приложений на macOS, установленной на компьютерах с новым процессором Apple Silicon. В качестве среды исполнения и базового образа для контейнеризации мы будем использовать сборки Axiom JDK .
Установка
Перед тем, как приступить к работе, установите необходимое ПО. Будем считать, что у вас уже есть тестовый проект. В данной статье в качестве примера мы будем использовать приложение Spring Boot PetClinic.
Скачайте нативную сборку JDK 11 для macOS ARM 64 bit. Мы рекомендуем использовать файл расширения .dmg, так как бинарные сборки прошли нотаризацию Apple, а пользоваться программой установки удобно и просто.
Затем скачайте Maven или используйте Maven Wrapper (mvnw), чтобы собрать тестовый проект (в нашем случае это Spring PetClinic). Убедитесь, что проект был успешно создан, запустив его:
% java -jar target/spring-petclinic-2.4.2.jar
Поскольку мы используем сборку Axiom JDK, предназначенную для macOS aarch64, приложение запустится на http://localhost:8080
.
Следует отметить, что для использования некоторых бинарных файлов из состава Docker может понадобиться Rosetta 2. Тем не менее ожидается, что эта проблема будет устранена в будущих релизах. Для установки Rosetta выполните в терминале следующую команду:
softwareupdate --install-rosetta
После этого установите последнюю версию Docker для ARM:
Запустите Docker Desktop. Для завершения настройки программа попросит предоставить ей привилегированный доступ.
Самое время воспользоваться терминалом и загрузить образ JDK!
% docker pull bellsoft/axiom-openjdk-alpine-musl:11
Таким образом, вы скачаете образ Axiom JDK 11 для linux-aarch64 и установите его практически мгновенно, так как он занимает всего 102 Мб на диске (здесь мы рассказываем, как нам удалось сделать его таким маленьким).
Запуск приложения в контейнере
Давайте посмотрим, как аппаратное обеспечение представлено в контейнере. Обратите внимание: четверо из восьми ядер CPU отображаются по умолчанию и (эффективно) виртуализируются в соответствии с документацией.
В основе лежит дистрибутив Alpine Linux, и стандартные инструменты Linux это покажут.
% docker run -it bellsoft/axiom-openjdk-alpine-musl:11 \
tail /proc/cpuinfo
processor : 3
BogoMIPS : 48.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp flagm2 frint
CPU implementer : 0x00
CPU architecture: 8
CPU variant : 0x0
CPU part : 0x000
CPU revision : 0
Внутри — сборка JDK для Linux на aarch64 с библиотекой C musl, благодаря чему наше тестовое приложение можно с легкостью запустить в контейнере:
% docker run -it -v $(pwd)/target:/target -p 8080:8080 \
bellsoft/axiom-openjdk-alpine-musl:11 java -jar \
/target/spring-petclinic-2.4.2.jar
В данном случае новый образ не создается, а jar-файл выбирается из хранилища (volume). Приложение открывается по адресу http://localhost:8080
:
Сборка образа контейнера
На основе приложения можно создать Docker-образ. Простой Dockerfile может выглядеть следующим образом:
FROM bellsoft/axiom-openjdk-alpine-musl:11
WORKDIR /
ARG JAR=spring-petclinic-2.4.2.jar
ADD /target/$JAR app.jar
EXPOSE 8080
CMD java -jar app.jar
Для создания образа выполните обычную команду:
% docker build -f ./Dockerfile -t my/petclinic-m1 .
Теперь запустите его:
% docker run -it my/petclinic-m1
Кросс-платформенная сборка для x86
Теперь ваш образ можно развернуть на ваших устройствах на базе ARM64: сюда относятся, например, инстансы AWS EC2 M6g на базе процессора Graviton 2 с архитектурой ARM64 или Arm-инстансы Ampere Altra в Oracle Cloud, а также системы на процессорах «Байкал». Однако если вы запустите приложение на x86_64 (:amd64), вы получите ошибку Exec format error. Чтобы избежать этого, используйте кросс-платформенную сборку с применением плагина Buildx:
% docker buildx build --platform linux/amd64 \
-f ./Dockerfile -t my/petclinic-x86 .
Новый образ основан на Alpine Linux и Axiom JDK для процессоров x86, поэтому теперь его можно развернуть на x86_64 для тестирования или эксплуатации.
Важно упомянуть еще несколько преимуществ описанного подхода, а именно — надежность и высокая скорость. В конце 2020 г. вышла IntelliJ IDEA с нативной поддержкой M1, поэтому теперь вы можете не просто клонировать и собирать свое приложение, но и разрабатывать его в привычном режиме. Хотя при работе с Docker все еще могут возникать некоторые ошибки, это происходит крайне редко. При этом производительность нативной JVM по факту выше, чем в режиме эмуляции x86.
Приложение Spring Boot PetClinic (которое мы использовали в качестве примера) запускается довольно быстро. При использовании Java™ и Docker запуск на компьютерах Mac M1 занимает всего 3-5 секунд. Более того, кросс-платформенная сборка позволяет, например, собирать образы контейнеров на устройствах x86 для ОС на базе ARM или создавать многоплатформенные образы.
Заключение
После выхода апрельского обновления Docker использовать это приложение на новых Mac Apple Silicon стало так же просто, как и в те времена, когда Apple выпускала компьютеры на базе Intel x86_64. Все необходимые инструменты готовы к использованию и стабильны, поэтому вы можете уверенно создавать образы для любой платформы. А благодаря тому, что Axiom JDK включает нативную сборку для macOS ARM 64 bit, процесс установки становится еще более быстрым и простым.