Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Контейнеры предоставляют согласованную переносимую среду для приложений Java на этапах разработки, тестирования и рабочей среды. В этой статье приводятся основные понятия контейнеризации для приложений Java и показано, как создавать, отлаживать, оптимизировать и развертывать контейнерные приложения Java в приложениях контейнеров Azure.
В этой статье описаны основные понятия контейнеризации для разработчиков Java и следующие навыки.
- Настройка среды разработки для контейнерных приложений Java.
- Создание файлов Dockerfile, оптимизированных для рабочих нагрузок Java.
- Настройка локальных рабочих процессов разработки с помощью контейнеров.
- Отладка контейнерных приложений Java.
- Оптимизация контейнеров Java для рабочей среды.
- Развертывание контейнерных приложений Java в приложениях контейнеров Azure.
Благодаря контейнеризации приложений Java вы получаете согласованные среды, упрощенное развертывание, эффективное использование ресурсов и улучшенную масштабируемость.
Контейнеры для приложений Java
Контейнеры упаковывают приложения со своими зависимостями, обеспечивая согласованность между средами. Для разработчиков Java это означает объединение приложения, его зависимостей, среды выполнения Java и пакета средств разработки Java (JRE/JDK) и файлов конфигурации в одном переносимом модуле.
Контейнеризация имеет ключевые преимущества по сравнению с виртуализацией, что делает его идеальным для разработки в облаке. В отличие от виртуальной машины, контейнер выполняется на хостовом ядре операционной системы сервера. Это полезно для приложений Java, которые уже работают на виртуальной машине Java (JVM). Контейнеризация приложений Java добавляет минимальные затраты и обеспечивает значительные преимущества развертывания.
Экосистема контейнеров включает следующие ключевые компоненты:
- Изображения — схемы.
- Контейнеры — запускаемые экземпляры.
- Реестры — где хранятся образы.
- Оркестраторы — системы, управляющие контейнерами в крупных масштабах.
Docker — это самая популярная платформа контейнеризации, и она хорошо поддерживается в экосистеме Azure с помощью приложений контейнеров Azure.
Настройка среды разработки
В этом разделе описано, как установить необходимые средства и настроить среду разработки для создания, запуска и отладки контейнерных приложений Java.
Установка необходимых средств
Чтобы контейнеризировать приложения Java, на компьютере разработки необходимо установить следующие средства:
- Docker Desktop. Предоставляет подсистему Docker, CLI и Docker Compose для Windows или macOS.
- Visual Studio Code. Доступно в качестве бесплатного редактора кода.
- Следующие расширения Visual Studio Code:
- Расширение Docker для управления контейнерами.
- Пакет расширений Java для разработки Java.
- Контейнеры разработки для разработки в контейнерах.
Проверьте установку с помощью следующих команд:
docker --version
docker compose version
Настройка Visual Studio Code для разработки контейнеров
Для разработки Java в контейнерах настройте Visual Studio Code, установив пакет расширений Java и настроив JDK. Расширение "Контейнеры разработки" позволяет открывать любую папку внутри контейнера и использовать полный набор функций Visual Studio Code внутри этого контейнера.
Чтобы включить автоматическую сборку и подключение Visual Studio Code к контейнеру разработки, создайте файл devcontainer/devcontainer.json в проекте.
Например, в следующем примере конфигурации определяется сборка Java:
{
"name": "Java Development",
"image": "mcr.microsoft.com/devcontainers/java:21",
"customizations": {
"vscode": {
"extensions": [
"vscjava.vscode-java-pack",
"ms-azuretools.vscode-docker"
]
}
},
"forwardPorts": [8080, 5005],
"remoteUser": "vscode"
}
Эта конфигурация использует образ контейнера разработки Java в Microsoft, добавляет необходимые расширения и перенаправляет порт приложения, 8080
а также порт отладки. 5005
Создайте Dockerfile
Файл Dockerfile содержит инструкции по созданию образа Docker. Для приложений Java файл Dockerfile обычно включает следующие компоненты:
- Базовый образ с JDK или JRE.
- Инструкции по копированию файлов приложения.
- Команды для задания переменных среды.
- Конфигурации точек входа.
Выбор базового образа
Выбор правильного базового образа имеет решающее значение. Рассмотрим следующие варианты:
Описание | Имя | Замечания |
---|---|---|
Образ разработки Microsoft Java | mcr.microsoft.com/java/jdk:21-zulu-ubuntu |
Полный JDK и оптимизированный для Azure |
Рабочий образ Microsoft Java | mcr.microsoft.com/java/jre:21-zulu-ubuntu |
Только среда выполнения и оптимизированная для Azure |
Официальный образ разработки OpenJDK | openjdk:21-jdk |
Полный JDK |
Официальный рабочий образ OpenJDK | openjdk:21-jre |
Только среда выполнения |
Для сред разработки используйте полный образ JDK. Для продакшн-среды используйте образ JRE или distroless image, чтобы минимизировать размер и поверхность атаки вашего приложения.
Образы Microsoft Java поставляются со специфическими для Azure оптимизациями и регулярно обновляются с помощью исправлений безопасности, что делает их идеальными для приложений, предназначенных для Azure Container Apps.
Базовые примеры Dockerfile
В следующем примере показан простой файл Dockerfile для приложения Java:
FROM mcr.microsoft.com/java/jdk:21-zulu-ubuntu
WORKDIR /app
COPY target/myapp.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Для приложений Spring Boot можно настроить Dockerfile со следующей базой:
FROM mcr.microsoft.com/java/jdk:21-zulu-ubuntu
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Dspring.profiles.active=docker", "-jar", "app.jar"]
Для рабочих развертываний используйте образ JRE, показанный в следующем примере, чтобы уменьшить размер и свести к минимуму область атаки приложения:
FROM mcr.microsoft.com/java/jre:21-zulu-ubuntu
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENV JAVA_OPTS="-Dserver.port=8080"
ENTRYPOINT ["java", ${JAVA_OPTS}, "-jar", "app.jar"]
Локальная разработка с программными контейнерами
Контейнеры предназначены для запуска в различных контекстах. В этом разделе описан локальный поток разработки для использования с контейнерами.
Использование Docker Compose для многоконтейнерных приложений
Большинство приложений Java взаимодействуют с базами данных, кэшами или другими службами. Docker Compose помогает определять и оркестрировать многоконтейнерные приложения с помощью простого файла конфигурации YAML.
Что такое Docker Compose?
Docker Compose — это средство, которое позволяет выполнять следующие задачи:
- Определите многоконтейнерные приложения в одном файле.
- Управление жизненным циклом приложения, включая запуск, остановку и перестроение.
- Поддерживайте изолированные среды.
- Создание сетей для связи между службами.
- Сохранение данных с помощью томов.
Пример: приложение Java с базой данных
Следующий файл compose.yml настраивает приложение Java с базой данных PostgreSQL:
version: '3.8'
services:
app:
build: . # Build from Dockerfile in current directory
ports:
- "8080:8080" # Map HTTP port
- "5005:5005" # Map debug port
environment:
- SPRING_PROFILES_ACTIVE=dev
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/myapp
volumes:
- ./target:/app/target # Mount target directory for hot reloads
depends_on:
- db # Ensure database starts first
db:
image: postgres:13
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=myapp
ports:
- "5432:5432" # Expose PostgreSQL port
volumes:
- postgres-data:/var/lib/postgresql/data # Persist database data
volumes:
postgres-data: # Named volume for database persistence
Этот файл имеет следующие характеристики:
- Службы могут ссылаться друг на друга по имени, например
db
в URL-адресе JDBC. - Docker Compose автоматически создает сеть для служб.
- Приложение Java ожидает запуска базы данных из-за
depends_on
. - Данные базы данных сохраняются во время перезапуска с помощью именованного тома.
Общие команды Docker Compose
После создания файла compose.yml управляйте приложением с помощью следующих команд:
# Build images without starting containers
docker compose build
# Start all services defined in compose.yml
docker compose up
# Start in detached mode (run in background)
docker compose up -d
# View running containers managed by compose
docker compose ps
# View logs from all containers
docker compose logs
# View logs from a specific service
docker compose logs app
# Stop all services
docker compose down
# Stop and remove volumes (useful for database resets)
docker compose down -v
Рабочий процесс разработки
Типичный рабочий процесс разработки Java с помощью Docker Compose содержит следующие действия:
- Создайте файл compose.yml и Dockerfile.
- Запустите
docker compose up
, чтобы запустить все службы. - Внесите изменения в код Java.
- Перестройте приложение. В зависимости от конфигурации может потребоваться перезапустить контейнеры.
- Проверьте изменения в контейнерной среде.
- По завершении выполните команду
docker compose down
.
Запуск отдельных контейнеров с помощью Docker
Для более простых сценариев, если вам не требуется несколько взаимосвязанных служб, можно использовать docker run
команду для запуска отдельных контейнеров.
Следующие команды Docker типичны для приложений Java:
# Run a Java application JAR directly
docker run -p 8080:8080 myapp:latest
# Run with environment variables
docker run -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=prod" myapp:latest
# Run in detached mode (background)
docker run -d -p 8080:8080 myapp:latest
# Run with a name for easy reference
docker run -d -p 8080:8080 --name my-java-app myapp:latest
# Run with volume mount for persistent data
docker run -p 8080:8080 -v ./data:/app/data myapp:latest
Отладка контейнерных приложений
Отладка контейнерных приложений Java иногда является сложной задачей, так как код выполняется в изолированной среде внутри контейнера.
Стандартные подходы к отладке не всегда применяются напрямую, но с правильной конфигурацией можно установить удаленное подключение к приложению. В этом разделе показано, как настроить контейнеры для отладки, подключить средства разработки к запуску контейнеров и устранить распространенные проблемы, связанные с контейнерами.
Настройка удаленной отладки
Отладка контейнерных приложений Java требует предоставления порта отладки и настройки интегрированной среды разработки для подключения к нему. Эти задачи можно выполнить, выполнив следующие действия.
Чтобы включить отладку, измените файл Dockerfile , чтобы он содержал следующее содержимое:
Замечание
Вместо этого можно изменить команду запуска контейнера.
FROM mcr.microsoft.com/java/jdk:21-zulu-ubuntu WORKDIR /app COPY target/*.jar app.jar EXPOSE 8080 5005 ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "app.jar"]
Настройте launch.json файл Visual Studio Code для подключения к порту отладки, как показано в следующем примере:
{ "version": "0.2.0", "configurations": [ { "type": "java", "name": "Debug in Container", "request": "attach", "hostName": "localhost", "port": 5005 } ] }
Запустите контейнер с портом
5005
, сопоставленным с хостом, и затем запустите отладчик в Visual Studio Code.
Устранение неполадок с контейнером
Если контейнеры не работают должным образом, вы можете проверить журналы приложения, чтобы изучить эту проблему.
Чтобы устранить неполадки с приложением, используйте следующие команды. Перед выполнением этих команд обязательно замените заполнители (<...>
) собственными значениями.
# View logs
docker logs <CONTAINER_ID>
# Follow logs in real-time
docker logs -f <CONTAINER_ID>
# Inspect container details
docker inspect <CONTAINER_ID>
# Get a shell in the container
docker exec -it <CONTAINER_ID> bash
Для проблем, связанных с Java, включите флаги JVM для улучшения диагностики, как показано в следующем примере:
ENTRYPOINT ["java", "-XX:+PrintFlagsFinal", "-XX:+PrintGCDetails", "-jar", "app.jar"]
В следующей таблице перечислены распространенные проблемы и соответствующие решения.
Ошибка | Возможное решение |
---|---|
Недостаточно памяти | Увеличение ограничений памяти контейнера |
Время ожидания подключения | Проверьте конфигурацию сети на наличие ошибок. Проверьте порты и правила маршрутизации. |
Проблемы с разрешениями | Проверьте разрешения файловой системы. |
Проблемы с путём к классам | Проверьте структуру JAR и зависимости. |
Оптимизация контейнеров Java
Приложения Java в контейнерах требуют особого внимания для оптимальной производительности. JVM был разработан до того, как контейнеры стали распространенными. Использование контейнеров может привести к проблемам выделения ресурсов, если они не настроены должным образом.
Вы можете значительно повысить производительность и эффективность контейнерных приложений Java, настроив параметры памяти, оптимизируя размер изображения и настраивая сборку мусора. В этом разделе рассматриваются основные оптимизации для контейнеров Java с акцентом на управление памятью, время запуска и использование ресурсов.
Конфигурация памяти JVM в контейнерах
JVM не автоматически обнаруживает ограничения памяти контейнера в Java 8. Для Java 9+, осведомленность о контейнерах включена по умолчанию.
Настройте JVM для соблюдения ограничений контейнеров, как показано в следующем примере:
FROM mcr.microsoft.com/java/jre:21-zulu-ubuntu
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
Для контейнерных приложений важны следующие флаги JVM:
-
-XX:MaxRAMPercentage=75.0
. Задает максимальную кучу в процентах от доступной памяти. -
-XX:InitialRAMPercentage=50.0
. Задает начальный размер кучи. -
-Xmx
и-Xms
. Эти флаги также доступны, но для них требуются фиксированные значения.
Подготовка к развертыванию в рабочей среде
Перемещение контейнерных приложений Java в рабочую среду требует рекомендаций, помимо основных функциональных возможностей.
Рабочие среды требуют надежной безопасности, надежного мониторинга, правильного распределения ресурсов и гибкости конфигурации.
В этом разделе рассматриваются основные методики и конфигурации, необходимые для подготовки контейнеров Java для использования в рабочей среде. В этом разделе рассматриваются вопросы безопасности, проверки работоспособности и управления конфигурацией, чтобы обеспечить надежную работу приложений в рабочей среде.
Рекомендации по обеспечению безопасности
Защита контейнерных приложений Java с помощью следующих методик:
Контекст безопасности по умолчанию. Запустите приложения как не корневого пользователя, как показано в следующем примере:
FROM mcr.microsoft.com/java/jre:21-zulu-ubuntu WORKDIR /app COPY target/*.jar app.jar RUN addgroup --system javauser && adduser --system --ingroup javauser javauser USER javauser ENTRYPOINT ["java", "-jar", "app.jar"]
Упреждающее поиск проблем. Регулярно сканируйте образы контейнеров для уязвимостей с помощью следующей команды:
docker scan myapp:latest
Свежесть базового образа. Обновляйте базовые образы.
Управление секретами. Реализуйте надлежащее управление секретами. Например, не создавайте конфиденциальные данные жесткого кода в приложении и по возможности используйте хранилище ключей.
Ограниченные контексты безопасности. Примените принцип наименьшей привилегии ко всем контекстам безопасности.
Доступ к файловой системе. Используйте файловые системы, доступные только для чтения, где это возможно.
Проверки работоспособности и мониторинг
Проверьте работоспособность приложения с помощью проб, чтобы убедиться, что приложение работает правильно.
Для приложений Spring Boot включите зависимость Actuator для комплексных показателей работоспособности, как показано в следующем примере.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Настройте приложение для вывода журналов в формате, подходящем для сред контейнеров, таких как JSON.
Развертывание в приложениях контейнеров Azure
В этом разделе описано, как подготовить контейнеры Java для развертывания приложений контейнеров Azure и выделить основные рекомендации по настройке.
Подготовка контейнера для Azure
Конфигурация порта. Убедитесь, что контейнер прослушивает порт, предоставленный Azure, как показано в следующем примере:
FROM mcr.microsoft.com/java/jre:21-zulu-ubuntu WORKDIR /app COPY target/*.jar app.jar ENV PORT=8080 EXPOSE ${PORT} CMD java -jar app.jar --server.port=${PORT}
Тест на здоровье. Реализуйте пробы работоспособности для проверок активности и готовности Azure.
Конфигурация журнала. Настройте ведение журнала для вывода в
stdout
/stderr
.Планируйте на случай неожиданного. Настройте надлежащее завершение работы с настройкой тайм-аута. Дополнительные сведения см. в разделе "Управление жизненным циклом приложений" в приложениях контейнеров Azure.