JDK 11 Dockerコンテナリソースセンシングの設定
一、背景
Java 8のいくつかの以前のバージョン(8 u 131以前?)では、dockerコンテナに配備されている場合、JVMがdockerコンテナのリソース制限を感知できないため、docker編成ファイルで設定されたリソース制限がJVMに対して無効になります.軽ければ複数のdockerコンテナがリソースを占有し、パフォーマンスが低下し、重ければdockerコンテナが不安定で頻繁に再起動します.
Java 8 u 131+とJDK 9以降,JVMはコンテナリソースを感知するパラメータを増やし,この問題を解決した.
この文書では、JDK 11を例に、javaアプリケーションのコンテナ感知パラメータを設定する方法と、docker編成ファイルでコンテナリソース制限を設定する方法について説明します.
二、環境 java: AdoptOpenJDK 11.0.8+10 docker ce: 19.03.4 docker-compose: 1.24.0
三、Javaアプリケーション関連設定
Openjdk 11ベースのjavaアプリケーションミラーを作成します.
3.1 Javaベースミラー
本文はAdoptOpenJDKのopenjdk 11ミラー
Dockerfileは次のとおりです.
Dockerfileが存在するディレクトリでdockerミラーコンパイルコマンドを実行します.
3.2 Javaアプリケーション
Openjdk 11が開発したjavaアプリケーションを事前に用意し、jarにコンパイルし、前のJavaベースミラーに基づいてjavaアプリケーションミラーをコンパイルします.
Dockerfileは次のとおりです. 上記のコマンドはjava 10以降のみ有効であり、他の感知をサポートするバージョンのパラメータ構成はそれぞれ異なる. ミラーコンパイルコマンドは、これ以上説明しません.
四、docker編成と起動
Javaアプリケーションのdocker composeファイルを編成し、起動し、リソースの占有量を確認します.
4.1 docker作成ファイル
ここではdocker compose v 3の編成規則を使用し、編成ファイルは以下の通りです.
service.yaml: deployはもともとdocker swarmの limitsはリソースの上限であり、reservationsは保持リソースである. cpusが設定した数字は、シンクホストcpuを占有する割合であり、
4.2 dockerコンテナを起動し、リソース使用量を確認する
次のコマンドを使用して起動します.
次に、dockerコンテナのリソース使用量を表示するには、次のコマンドを使用します.
dockerリソースの占有率は次のとおりです.
注意してみると、この容器はCPUの占有量が最大100%程度で、メモリは1 Gの制限を超えないことがわかります.
Java 8のいくつかの以前のバージョン(8 u 131以前?)では、dockerコンテナに配備されている場合、JVMがdockerコンテナのリソース制限を感知できないため、docker編成ファイルで設定されたリソース制限がJVMに対して無効になります.軽ければ複数のdockerコンテナがリソースを占有し、パフォーマンスが低下し、重ければdockerコンテナが不安定で頻繁に再起動します.
Java 8 u 131+とJDK 9以降,JVMはコンテナリソースを感知するパラメータを増やし,この問題を解決した.
この文書では、JDK 11を例に、javaアプリケーションのコンテナ感知パラメータを設定する方法と、docker編成ファイルでコンテナリソース制限を設定する方法について説明します.
二、環境
三、Javaアプリケーション関連設定
Openjdk 11ベースのjavaアプリケーションミラーを作成します.
3.1 Javaベースミラー
本文はAdoptOpenJDKのopenjdk 11ミラー
adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine
に基づいて中国タイムゾーンを作成し、中国語のopenjdk 11ミラーをサポートした.Dockerfileは次のとおりです.
# dockerhub
FROM adoptopenjdk/openjdk11:jdk-11.0.8_10-alpine
#
ENV TIME_ZONE=Asia/Shanghai \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=en_US.UTF-8
#
RUN apk add --no-cache tzdata \
&& echo "${TIME_ZONE}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime
Dockerfileが存在するディレクトリでdockerミラーコンパイルコマンドを実行します.
docker build -t czhao/base-openjdk11:jdk-11.0.8_001 .
3.2 Javaアプリケーション
Openjdk 11が開発したjavaアプリケーションを事前に用意し、jarにコンパイルし、前のJavaベースミラーに基づいてjavaアプリケーションミラーをコンパイルします.
Dockerfileは次のとおりです.
FROM czhao/base-openjdk11:jdk-11.0.8_001
# JDK11 : -XX:+UseContainerSupport JVM , -XX:InitialRAMPercentage , -XX:MaxRAMPercentage
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:InitialRAMPercentage=50 -XX:MaxRAMPercentage=80"
# target/*.jar
ADD target/*.jar app.jar
# ""
ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
docker build -t : .
容器感知をオンにします.-XX:+UseContainerSupport
と-XX:InitialRAMPercentage
は、JVMの初期のコンテナメモリ比と最大コンテナメモリ比を設定するために使用されます.四、docker編成と起動
Javaアプリケーションのdocker composeファイルを編成し、起動し、リソースの占有量を確認します.
4.1 docker作成ファイル
ここではdocker compose v 3の編成規則を使用し、編成ファイルは以下の通りです.
service.yaml:
version: '3'
...
services:
:
container_name:
image: :
...
deploy:
resources:
limits:
cpus: '1.00'
memory: 1024M
reservations:
# cpus: '0.1'
memory: 512M
-XX:MaxRAMPercentage
コマンドでサポートされている属性ですが、docker stack deploy
コマンドにdocker-compose up
パラメータを追加することで有効にすることができます.しかし、--compatibility
はまだ有効ではありません.deploy.resources.reservations.cpus
、すなわち1.00
は、シンクホストCPUを完全に占有するprocessを表す.注意、ホストがマルチコアマシンであれば、100%
はプロセスを1つ占有しているだけです.例えば、100%
のシンクホストであり、cpusは理論的に8 core 16 process
に設定することができる.しかし、ここでは、1つの容器のcpu占有量が16.00
を超えないことをお勧めします.4.2 dockerコンテナを起動し、リソース使用量を確認する
次のコマンドを使用して起動します.
docker-compose --compatibility -f service.yaml up -d
次に、dockerコンテナのリソース使用量を表示するには、次のコマンドを使用します.
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
dockerリソースの占有率は次のとおりです.
NAME CPU % MEM USAGE / LIMIT
0.66% 418.5MiB / 1GiB
注意してみると、この容器はCPUの占有量が最大100%程度で、メモリは1 Gの制限を超えないことがわかります.