Ограничить потребление памяти JVM в контейнере Docker
У меня есть приложение Spring Boot, реализующее сервис, который я хочу запустить в контейнере Docker. Я следовал рекомендациям официальных документов Spring, которые предлагают создать DockerFile, похожий на этот:
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, я использую 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, но это заметно замедляет работу приложения.
1 ответ
После некоторого времени, кажется, JAVA_OPTS
переменная может быть передана в контейнер, когда она основана на образе Tomcat, но Spring Boot использует саму Java в качестве базового образа.
Я нашел этот учебник, который решил эту проблему для меня, просто изменив способ запуска процесса в DockerFile и добавив переменную JAVA_OPTS непосредственно в ENTRYPOINT:
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar
Таким образом, JVM выберет значение из самой команды.