3
respostas

[Dúvida] Como containerizar imagens nativas GraalVM

Como containerizar imagens nativas GraalVM? O que vai e o que não vai ao buildar uma imagem Java nativa GraalVM para ser disponibilizada num registry para ser usada de fato em ambientes por orquestradores de container em homologação...produção? (Openshift...kubernetes...)

A idéia é entender, de fato, seu uso e benefícios como imagem leve e performática pra uso em containers. No quesito de melhores pulls em registries (mais leves e mais rapidos) e menores tempos de inicialização de Pods...etc

3 respostas

Oi Helton! Como vai?

Containerizar uma imagem nativa GraalVM pode ser uma ótima maneira de criar aplicações leves e performáticas, especialmente quando você está visando tempos de inicialização rápidos e eficiência em ambientes de orquestração como Kubernetes e OpenShift.

Para containerizar uma imagem nativa GraalVM, você pode seguir os passos abaixo:

  1. Criação da Imagem Nativa: Primeiro, compile sua aplicação Java para uma imagem nativa usando o GraalVM. Você já está familiarizado com o uso do native-maven-plugin para esse propósito, gerando um executável nativo.

  2. Dockerfile para Imagem Nativa: Crie um Dockerfile que utilize uma imagem base mínima, como alpine, para manter a imagem o mais leve possível. Aqui está um exemplo de como seu Dockerfile pode parecer:

    FROM alpine:latest
    WORKDIR /app
    COPY target/api /app/api
    ENTRYPOINT ["/app/api"]
    

    Neste exemplo, estamos copiando o executável nativo gerado para dentro da imagem e definindo-o como o ponto de entrada.

  3. Construção da Imagem Docker: Com o Dockerfile configurado, você pode construir sua imagem Docker com o seguinte comando:

    docker build -t sua-imagem-nativa .
    
  4. Publicação no Registry: Após a construção, você pode enviar sua imagem para um registry Docker (como Docker Hub ou um registry privado) para que possa ser utilizada em seus ambientes de homologação e produção:

    docker push seu-registry/sua-imagem-nativa
    
  5. Deploy em Orquestradores de Containers: Uma vez que sua imagem está no registry, você pode usá-la em seus ambientes Kubernetes ou OpenShift. Crie um arquivo de configuração de deployment que referencie sua imagem.

Os benefícios de usar imagens nativas GraalVM incluem tempos de inicialização mais rápidos e menor uso de memória, o que é ideal para aplicações que precisam escalar rapidamente. No entanto, lembre-se de que a criação da imagem nativa pode demandar mais tempo e recursos durante o build.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Olá Armano, tudo bem, obrigado pela resposta.

Então me parece simples...vi que vc utilizou uma imagem Linux-Alpine como base...mas acredito que possam ser outros Linux tbm né....e vejo que realmente não é necessário incluir nenhum JDK Engine na imagem...

Pra vc entender melhor o cenário em que estou estudando, meu objetivo final é instrumentar uma aplicação Java como uma imagem nativa, com Dynatrace por exemplo ...E o Dynatrace, normalmente funciona juntamente com a JVM pra coletar as métricas...mas no caso de imagens nativas, é necessário que esta instrumentação ocorra em tempo de compilação.

Pra isto ele disponibiliza um plugin proprio, pra ser usado em tempo de build com ferramentas como Maven ou Graddle. Ele tbm gera após a build, uma pasta /dynatrace no Target. Imagino então, que este diretório deva ser copiado junto com o executável gerado pra dentro da imagem de container, no Dockerfile.

Oi, Helton! Como vai?

Sim, o diretório /dynatrace gerado no build precisa ir junto com o binário nativo, porque toda a instrumentação ocorre em tempo de compilação e não existe JVM em runtime para anexar agentes dinamicamente.

O que fazer, de forma direta:

  1. Build da imagem nativa já instrumentada

    • Execute o build com o plugin do Dynatrace habilitado no Maven/Gradle.
    • Esse passo gera:
      • o executável nativo
      • a pasta /dynatrace (normalmente dentro de target/)
  2. Dockerfile sem JDK

    • A imagem não leva JDK, nem GraalVM, nem JVM.
    • Leva apenas:
      • o binário nativo
      • o diretório /dynatrace
      • dependências mínimas do sistema operacional

Veja este exemplo:


FROM gcr.io/distroless/base-debian12

WORKDIR /app

COPY target/app-native /app/app
COPY target/dynatrace /app/dynatrace

ENV DT_HOME=/app/dynatrace

ENTRYPOINT ["/app/app"]
  1. Imagem base

    • Use distroless ou alpine.
    • Distroless é mais comum em produção com Kubernetes/OpenShift por reduzir superfície de ataque.
    • Alpine funciona, mas pode exigir ajustes de libc dependendo do binário.
  2. O que NÃO vai para a imagem

    • JDK
    • JVM
    • Agente Dynatrace tradicional (.jar)
    • Ferramentas de build (Maven, Gradle)
  3. Benefícios reais no Kubernetes/OpenShift

    • Pull mais rápido no registry (imagem menor)
    • Startup quase imediato do Pod
    • Menor consumo de memória
    • Ideal para auto scaling e ambientes com alta rotatividade de Pods

Neste ponto, o Dynatrace coleta métricas via código já instrumentado, não por attach em runtime, o que é exatamente o modelo correto para GraalVM Native Image.

Fico à disposição.