2016-05-27 4 views
5

У меня есть приложение Spring Boot, реализующее сервис, который я хочу запустить в контейнере Docker. Я следовал руководство официального Spring docs, которые свидетельствуют создать DockerFile похожее на это:Ограничение потребления памяти JVM в контейнере Docker

FROM frolvlad/alpine-oraclejdk8:slim 
VOLUME /tmp 
ADD gs-spring-boot-docker-0.1.0.jar app.jar 
RUN sh -c 'touch /app.jar' 
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 

Затем, когда изображение выталкивается Докер я использую Docker Compose запустить его таким образом:

spring-boot-docker: 
    ports: 
    - "80:80" 
    expose: 
    - "80" 
    image: my-repo/spring-boot-docker:0.1.0-SNAPSHOT 
    container_name: spring-boot-docker 
    environment: 
     JAVA_OPTS: '-Xmx64m' 

Здесь у меня есть переменная JAVA_OPTS, которая ограничивает выделение памяти, однако при выполнении docker stats spring-boot-docker память, занимаемая контейнером, чрезмерна (я понимаю, что общая память, полученная JVM, может быть намного больше, чем 64M, но в этом случай совершенно безграничен).

Я также пробовал с mem_limit param, но это заметно замедляет работу приложения.

ответ

6

После некоторого времени, кажется, переменная JAVA_OPTS может быть передана в контейнер when it's based in a Tomcat image, но Spring Boot использует Java как базовое изображение.

Я узнал this tutorial, которые решить эту проблему для меня, просто изменяя способ этот процесс запускается в DockerFile и добавление переменной JAVA_OPTS непосредственно в Entrypoint:

ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar 

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

+2

Обратите внимание, что переход из формы _exec_ в _shell_ 'ENTRYPOINT' также имеет побочный эффект отключение {' CMD', аргументы командной строки}, поэтому запуск вашего контейнера как 'docker run --spring.profiles.active = production' просто игнорирует профиль. – qerub

Смежные вопросы