Konteneryzowanie aplikacji Java dla platformy Kubernetes

W tym artykule opisano sposób konteneryzowania aplikacji Java na potrzeby wdrażania na platformie Kubernetes.

Aby uzyskać wskazówki dotyczące pamięci kontenera, pamięci sterty JVM, modułów odśmiecania pamięci (GCs) i rdzeni procesorów wirtualnych, zobacz Konteneryzowanie aplikacji Java.

Określanie odpowiedniej jednostki SKU maszyny wirtualnej dla puli węzłów Kubernetes

Ustal, czy pula węzłów kubernetes lub pule dostępne dla klastra mogą pasować do pamięci kontenera i rdzeni procesorów wirtualnych, które mają być używane. Jeśli pula węzłów może hostować aplikację, kontynuuj. W przeciwnym razie aprowizuj pulę węzłów odpowiednią dla ilości pamięci kontenera i liczby rdzeni procesorów wirtualnych, które są przeznaczone.

Należy pamiętać, że koszt jednostki SKU maszyny wirtualnej jest proporcjonalny do liczby rdzeni i ilości pamięci. Po określeniu punktu początkowego pod względem procesorów wirtualnych i pamięci dla jednego wystąpienia kontenera określ, czy można spełnić potrzeby aplikacji, skalując tylko w poziomie. W przypadku niezawodnych systemów zawsze włączonych muszą być dostępne co najmniej dwie repliki. Skalowanie w górę i w poziomie zgodnie z potrzebami.

Ustawianie żądań i limitów procesora CPU

Jeśli musisz ograniczyć procesor CPU, upewnij się, że zastosowano tę samą wartość zarówno dla pliku wdrożenia, jak limits i requests w pliku wdrożenia. Maszyny JVM nie dostosowują dynamicznie swojego środowiska uruchomieniowego, takiego jak GC i inne pule wątków. JVM odczytuje liczbę procesorów dostępnych tylko w czasie uruchamiania.

Napiwek

Ustaw tę samą wartość dla żądań procesora CPU i limitów procesora CPU.

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

Omówienie dostępnych procesorów JVM

Gdy funkcja JVM hotSpot w zestawie OpenJDK identyfikuje, że działa wewnątrz kontenera, używa wartości, takich jak cpu_quota i cpu_period do określenia, ile procesorów jest dostępnych. Ogólnie rzecz biorąc, każda wartość do 1000m milicores jest identyfikowana jako pojedyncza maszyna procesora. Każda wartość między 1001m i 2000m jest identyfikowana jako maszyna z podwójnym procesorem itd. Te informacje są dostępne za pośrednictwem interfejsu API Runtime.getRuntime().availableProcessors(). Ta wartość może być również używana przez niektóre współbieżne kontrolery domeny w celu skonfigurowania ich wątków. Inne interfejsy API, biblioteki i struktury mogą również używać tych informacji do konfigurowania pul wątków.

Limity przydziału procesora KUBernetes są związane z ilością czasu spędzanego przez proces w procesorze CPU, a nie liczbą procesorów dostępnych dla tego procesu. Środowiska uruchomieniowe wielowątkowy, takie jak JVM, mogą nadal używać wielu procesorów jednocześnie z wieloma wątkami. Nawet jeśli kontener ma limit jednego procesora wirtualnego, maszyna wirtualna JVM może być poinstruowana, aby wyświetlić co najmniej dwa dostępne procesory.

Aby poinformować maszynę wirtualną JVM o dokładnej liczbie procesorów, które powinny być widoczne w środowisku Kubernetes, użyj następującej flagi JVM:

-XX:ActiveProcessorCount=N

Ustawianie żądań i limitów pamięci

Ustaw limity pamięci na określoną wcześniej ilość. Upewnij się, że liczba limitów pamięci to pamięć kontenera, a nie wartość pamięci stertowej JVM.

Napiwek

Ustaw żądania pamięci równe limitom pamięci.

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

Ustawianie argumentów JVM w pliku wdrożenia

Pamiętaj, aby ustawić pamięć stert JVM na ilość wcześniej określoną. Zalecamy przekazanie tej wartości jako zmiennej środowiskowej, aby można było ją łatwo zmienić bez konieczności ponownego kompilowania obrazu kontenera.

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

Następne kroki