Я запускаю несколько приложений Java с образом Docker jboss/wildfly:20.0.1.Final в Кубернете 1.19.3. Сервер Wildfly работает в OpenJDK 11, поэтому jvm поддерживает ограничения памяти контейнера (cgroups).
Если я устанавливаю лимит памяти, этот лимит полностью игнорируется контейнером при работе в Kubernetes. Но это соблюдается на той же машине, когда я запускаю ее в обычном Docker:
<сильный>1. Запустите Wildfly в Docker с ограничением памяти 300 МБ:
$ docker run -it --rm --name java-wildfly-test -p 8080:8080 -e JAVA_OPTS='-XX:MaxRAMPercentage=75.0' -m=300M jboss/wildfly:20.0.1.Final
проверить использование памяти:
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
515e549bc01f java-wildfly-test 0.14% 219MiB / 300MiB 73.00% 906B / 0B 0B / 0B 43
Как и ожидалось, контейнер НЕ превысит лимит памяти в 300 МБ.
<сильный>2. Запустите Wildfly в Kubernetes с ограничением памяти 300 МБ:
Теперь я запускаю тот же контейнер в kubernetes.
$ kubectl run java-wildfly-test --image=jboss/wildfly:20.0.1.Final --limits='memory=300M' --env="JAVA_OPTS='-XX:MaxRAMPercentage=75.0'"
проверить использование памяти:
$ kubectl top pod java-wildfly-test
NAME CPU(cores) MEMORY(bytes)
java-wildfly-test 1089m 441Mi
Предел памяти в 300M полностью игнорируется и немедленно превышается.
Почему это происходит? Оба теста могут быть выполнены на одной и той же машине.
Ответить
Причиной высоких значений стал некорректный вывод данных Метрики, полученных от проекта kube-prometheus а>. После удаления kube-projemet и установки вместо него metric-server все данные отображались корректно. используя kubctl сверху. Теперь он показывает те же значения, что и статистика докера. Я не знаю, почему kube-prometheus вычислил неправильные данные. На самом деле он предоставлял двойные значения для всех данных памяти.