Поделиться через


Контейнеризация приложений Java для Kubernetes

В этой статье описывается, как контейнеризировать приложения Java для развертывания в Kubernetes. Рекомендации по памяти контейнера, памяти кучи JVM, сборщикам мусора (GCs) и ядрам виртуальных ЦП см. в контейнеризации приложений Java.

Определение соответствующего номера SKU виртуальной машины для пула узлов Kubernetes

Определите, может ли пул узлов Kubernetes или пулы, доступные для кластера, соответствовать памяти контейнера и ядрам виртуальных ЦП, которые вы планируете использовать. Если пул узлов может разместить приложение, продолжайте работу. В противном случае подготовьте пул узлов, соответствующий объему памяти контейнера и количеству ядер виртуального ЦП, которые вы используете.

Помните, что стоимость SKU виртуальной машины пропорциональна количеству ядер и объему памяти. Определив начальную точку с точки зрения виртуальных ЦП и памяти для одного экземпляра контейнера, определите, можно ли соответствовать потребностям приложения только по горизонтальному масштабированию. Для надежных и постоянно работающих систем должно быть доступно не менее двух реплик. Масштабируйте вверх и наружу по мере необходимости.

Настройка запросов и ограничений ЦП

Если необходимо ограничить ЦП, убедитесь, что вы применяете одинаковое значение для обоих limits и requests в файле развертывания. JVM не динамически настраивает среду выполнения, например GC и другие пулы потоков. JVM считывает количество процессоров, доступных только во время запуска.

Совет

Задайте то же значение для запросов ЦП и ограничений ЦП.

containers:
- image: myimage
  name: myapp
  resources:
    limits:
      cpu: "2"
    requests:
      cpu: "2"

Общие сведения о доступных процессорах JVM

Когда JVM HotSpot в OpenJDK определяет, что он работает внутри контейнера, он использует такие значения, как cpu_quota и cpu_period, чтобы определить, сколько процессоров доступно для него. Как правило, любое значение до 1000m милликор определяется как однопроцессорная машина. Любое значение между 1001m и 2000m определяется как компьютер с двумя процессорами и т. д. Эти сведения доступны через API Runtime.getRuntime().availableProcessors(). Некоторые параллельные GCs также могут использовать это значение для настройки потоков. Другие API, библиотеки и платформы также могут использовать эти сведения для настройки пулов потоков.

Квоты на центральный процессор в Kubernetes связаны с количеством времени, которое процесс использует центральный процессор, а не с количеством доступных центральных процессоров для процесса. Многопоточные среды выполнения, такие как JVM, могут все еще использовать несколько процессоров одновременно с несколькими потоками. Даже если контейнер имеет ограничение на один виртуальный ЦП, JVM может быть инструктирован увидеть два или более доступных процессоров.

Чтобы сообщить JVM о точном количестве процессоров, которые он должен видеть в среде Kubernetes, используйте следующий флаг JVM:

-XX:ActiveProcessorCount=N

Настройка запроса памяти и ограничений

Задайте ограничения памяти на определенный ранее объем. Убедитесь, что число ограничений памяти — это память контейнера, а не значение памяти кучи JVM.

Совет

Задайте запросы памяти, равные ограничениям памяти.

containers:
  - name: myimage
    image: myapp
    resources:
      limits:
        memory: "4Gi"
      requests:
        memory: "4Gi"

Установка аргументов JVM в файле развертывания

Не забудьте задать объем памяти кучи JVM, который вы ранее определили. Мы рекомендуем передать это значение в качестве переменной среды, чтобы можно было легко изменить ее, не перестроив образ контейнера.

containers:
  - name: myimage
    image: myapp
    env:
    - name: JAVA_OPTS
      value: "-XX:+UseParallelGC -XX:MaxRAMPercentage=75"

Дальнейшие действия