Conteinerizar seus aplicativos Java para Kubernetes

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

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

Determinar 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 o cluster podem se ajustar à memória do contêiner e aos núcleos 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 vCPU que você está segmentando.

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 dimensionando horizontalmente. Para sistemas confiáveis e sempre ativos, um mínimo de duas réplicas deve estar disponível. 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 somente durante o tempo de inicialização.

Dica

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"

Entender 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 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 seja a memória do contêiner e NÃO o valor da memória de heap da JVM.

Dica

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 recriar a imagem do contêiner.

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

Próximas etapas