Containerize seus aplicativos Java para Kubernetes

Este artigo descreve como contentorizar seus aplicativos Java para implementação no Kubernetes.

Para obter orientação sobre memória de contêiner, memória de heap JVM, coletores de lixo (GCs) e núcleos vCPU, consulte Containerize your Java applications.

Determine a SKU de VM apropriada para o pool de nós do Kubernetes

Determine se o pool de nós do Kubernetes ou os pools disponíveis para seu cluster podem caber na memória do contêiner e nos núcleos de vCPU que você pretende usar. Se o pool de nós puder hospedar o aplicativo, continue. Caso contrário, provisione um pool de nós apropriado para a quantidade de memória de contêiner e o número de núcleos de vCPU que você está direcionando.

Lembre-se de que o custo de uma SKU de VM é proporcional ao número de núcleos e à quantidade de memória. Depois de determinar seu ponto de partida em termos de vCPUs e memória para uma instância de contêiner, determine se você pode atender às necessidades do seu aplicativo apenas com dimensionamento horizontal. Para sistemas confiáveis e sempre ativos, um mínimo de duas réplicas devem estar disponíveis. Aumente e diminua a escala conforme necessário.

Definir solicitações e limites de CPU

Se você precisar limitar a CPU, certifique-se de aplicar o mesmo valor para ambos limits e requests no arquivo de implantação. A JVM não ajusta dinamicamente seu tempo de execução, como o GC e outros pools de threads. A JVM lê o número de processadores disponíveis apenas durante o tempo de inicialização.

Gorjeta

Defina o mesmo valor para solicitações de CPU e limites de CPU.

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

Compreender os processadores disponíveis da JVM

Quando a JVM HotSpot no OpenJDK identifica que está sendo executada dentro de um contêiner, ela usa valores como cpu_quota e cpu_period para determinar quantos processadores estão disponíveis para ela. Em geral, qualquer valor de até 1000m milinúcleos é identificado como uma única máquina processadora. Qualquer valor entre 1001m e é identificado como uma máquina de processador duplo, e 2000m assim por diante. Essas informações estão disponíveis por meio da API Runtime.getRuntime().availableProcessors(). Esse valor também pode ser usado por alguns dos GCs simultâneos para configurar seus threads. Outras APIs, bibliotecas e estruturas também podem usar essas informações para configurar pools de threads.

As cotas de CPU do Kubernetes estão relacionadas à quantidade de tempo que um processo passa na CPU, e não ao número de CPUs disponíveis para o processo. Tempos de execução multi-threaded, como a JVM, ainda podem usar vários processadores simultaneamente, com vários threads. Mesmo que um contêiner tenha um limite de uma vCPU, a JVM pode ser instruída a ver dois ou mais processadores disponíveis.

Para informar a JVM do número exato de processadores que ela deve ver em um ambiente Kubernetes, use o seguinte sinalizador da JVM:

-XX:ActiveProcessorCount=N

Definir solicitação de memória e limites

Defina os limites de memória para a quantidade que você determinou anteriormente. Certifique-se de que o número de limites de memória é a memória do contêiner e NÃO o valor da memória de heap da JVM.

Gorjeta

Defina as solicitações de memória iguais aos limites de memória.

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

Definir os argumentos da JVM no arquivo de implantação

Lembre-se de definir a memória de heap da JVM para a quantidade que você determinou anteriormente. Recomendamos que você passe esse valor como uma variável de ambiente para que possa alterá-lo facilmente sem precisar reconstruir a imagem do contêiner.

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

Próximos passos