1. Visão geral
Sobre o Micronaut
O Micronaut é um framework moderno de pilha completa baseado em JVM para criar microsserviços modulares e aplicativos sem servidor fáceis de testar. O Micronaut tem como objetivo oferecer um ótimo tempo de inicialização, capacidade de processamento rápida e um consumo mínimo de memória. Os desenvolvedores podem desenvolver com o Micronaut em Java, Groovy ou Kotlin.
O Micronaut oferece:
- Tempo de inicialização rápido e baixo consumo de memória: os frameworks IoC baseados em reflexão carregam e armazenam em cache dados de reflexão para cada campo, método e construtor no seu código. Já com o Micronaut, o tempo de inicialização do aplicativo e o consumo de memória não estão vinculados ao tamanho da base de código.
- Cliente HTTP declarativo, reativo e de tempo de compilação: crie clientes HTTP reativos de forma declarativa, que são implementados no tempo de compilação, reduzindo o consumo de memória.
- Servidor HTTP não bloqueador criado no Netty: com uma curva de aprendizado suave, o servidor HTTP do Micronaut facilita ao máximo a exposição de APIs que podem ser consumidas por clientes HTTP.
- Teste rápido e fácil: crie servidores e clientes com facilidade nos seus testes de unidade e execute-os instantaneamente.
- Injeção de dependência e AOP eficientes em tempo de compilação: o Micronaut oferece uma API de programação orientada a aspectos simples em tempo de compilação que não usa reflexão.
- Crie apps totalmente reativos e sem bloqueio: o Micronaut é compatível com qualquer framework que implemente Reactive Streams, incluindo RxJava e Reactor.
Para mais informações, acesse o site do Micronaut.
Sobre o Kubernetes
O Kubernetes é um projeto de código aberto que pode ser executado em diversos ambientes, de laptops a clusters com vários nós de alta disponibilidade, de nuvens públicas a implantações locais e de máquinas virtuais a bare metal.
Neste laboratório, você vai implantar um microsserviço simples do Micronaut baseado em Groovy no Kubernetes executado no Kubernetes Engine.
O objetivo deste codelab é executar seu microsserviço como um serviço replicado no Kubernetes. Você pega o código que desenvolveu na sua máquina, transforma-o em uma imagem de contêiner do Docker e executa essa imagem no Kubernetes Engine.
Confira um diagrama das várias partes deste codelab para entender como as peças se encaixam. Use isso como referência à medida que você avança no codelab. Tudo fará sentido quando você chegar ao fim. Você pode ignorar isso por enquanto.

Neste codelab, o uso de um ambiente gerenciado como o Kubernetes Engine, uma versão do Kubernetes hospedada pelo Google em execução no Compute Engine, permite que você se concentre mais na experiência do Kubernetes, em vez de configurar a infraestrutura subjacente.
Se você estiver interessado em executar o Kubernetes no computador, como um laptop de desenvolvimento, conheça o Minikube. Ele oferece uma configuração simples de um cluster do Kubernetes de nó único para desenvolvimento e teste. Você pode usar o Minikube durante este codelab, se quiser.
Sobre o Jib
O Jib é uma ferramenta de código aberto que permite criar imagens do Docker e do OCI para seus aplicativos Java. Ele está disponível como plug-ins para Maven e Gradle e como uma biblioteca Java.
O Jib tem como objetivo ser:
- Rápido: implante suas mudanças rapidamente. O Jib separa seu aplicativo em várias camadas, dividindo dependências de classes. Agora você não precisa esperar que o Docker recrie todo o aplicativo Java. Basta implantar as camadas que foram alteradas.
- Reproduzível: recriar a imagem do contêiner com o mesmo conteúdo sempre gera a mesma imagem. Nunca mais acione uma atualização desnecessária.
- Sem daemon: reduza as dependências da CLI. Crie sua imagem Docker no Maven ou Gradle e envie para qualquer registro de sua escolha. Não é mais necessário escrever Dockerfiles e chamar docker build/push.
Saiba mais sobre o Jib na página do projeto no GitHub.
Sobre este tutorial
Neste tutorial, usamos o exemplo de código da ferramenta Jib para criar contêineres para aplicativos Java.
A amostra é um serviço simples de hello world, usando o framework Micronaut e a linguagem de programação Apache Groovy.
O que você vai aprender
- Como empacotar um aplicativo Java simples como um contêiner do Docker usando o Jib
- Como criar um cluster do Kubernetes no Kubernetes Engine
- Como implantar seu serviço do Micronaut no Kubernetes no Kubernetes Engine
- Como escalonar verticalmente o serviço e fazer um upgrade
- Como acessar o painel gráfico do Kubernetes
O que é necessário
- Um projeto do Google Cloud Platform
- Um navegador, como o Chrome ou o Firefox
- Conhecer os editores de texto padrão do Linux, como vim, emacs ou nano
Como você usará este tutorial?
Como você classificaria sua experiência com a criação de apps da Web em HTML/CSS?
Como você classificaria sua experiência com o uso dos serviços do Google Cloud Platform?
2. Configuração e requisitos
Configuração de ambiente autoguiada
- Faça login no Console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma se você ainda não tiver uma conta do Gmail ou do G Suite.
Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.
- Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.
A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.
3. Acessar o código-fonte de exemplo do Micronaut
Depois que o Cloud Shell for iniciado, use a linha de comando para clonar o código-fonte de exemplo no diretório principal e cd no diretório que contém nosso serviço de exemplo:
$ git clone https://github.com/GoogleContainerTools/jib.git
$ cd jib/examples/micronaut/
4. Uma olhada rápida no código
Nosso serviço simples do Micronaut é composto por um controlador que gera a famosa mensagem "Hello World":
@Controller("/hello")
class HelloController {
@Get("/")
String index() {
"Hello World"
}
}
O controlador HelloController está respondendo a solicitações no caminho /hello, e o método index() aceita as solicitações HTTP GET.
Uma classe de teste Spock também está disponível para verificar se a mensagem correta é exibida na saída.
class HelloControllerSpec extends Specification {
@Shared
@AutoCleanup
EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer)
@Shared
@AutoCleanup
RxHttpClient client = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL())
void "test hello world response"() {
when:
HttpRequest request = HttpRequest.GET('/hello')
String rsp = client.toBlocking().retrieve(request)
then:
rsp == "Hello World"
}
}
Mais do que um simples teste de unidade, esse teste executa a mesma pilha de servidor Micronaut (baseada no framework Netty) que é executada em produção. Assim, o comportamento do código será o mesmo no produto e nos testes.
Para executar os testes, execute o seguinte comando para verificar se está tudo bem:
./gradlew test
5. execute o aplicativo no local
É possível iniciar o serviço do Micronaut normalmente com o seguinte comando do Gradle:
$ ./gradlew run
Depois que o aplicativo for iniciado, abra outra instância do Cloud Shell usando o pequeno ícone de mais (+) e verifique com curl se você recebe a saída esperada:
$ curl localhost:8080/hello
Uma mensagem simples "Hello World" vai aparecer.
6. Empacotar o aplicativo como um contêiner do Docker com o Jib
Em seguida, prepare o aplicativo para ser executado no Kubernetes. Para isso, vamos aproveitar o Jib para fazer o trabalho pesado, já que não vamos precisar tocar em um Dockerfile.
Vamos executar o comando para criar nosso contêiner:
$ ./gradlew jibDockerBuild
Esta é a saída que você vai ver:
Tagging image with generated image reference micronaut-jib:0.1. If you'd like to specify a different tag, you can set the jib.to.image parameter in your build.gradle, or use the --im age=<MY IMAGE> commandline flag. Containerizing application to Docker daemon as micronaut-jib:0.1... warning: Base image 'gcr.io/distroless/java' does not use a specific image digest - build may not be reproducible Getting base image gcr.io/distroless/java... Building dependencies layer... Building resources layer... Building classes layer... Finalizing... Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, example.micronaut.Application] Loading to Docker daemon... Built image to Docker daemon as micronaut-jib:0.1
Agora que a imagem foi criada, vamos verificar se podemos ver a mensagem de olá executando a imagem Docker na primeira guia do Cloud Shell:
$ docker run -it -p 8080:8080 micronaut-jib:0.1 16:57:20.255 [main] INFO i.m.context.env.DefaultEnvironment - Established active environments: [cloud, gcp] 16:57:23.203 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 2926ms. Server Running: http://97b7d76ccf3f:8080
Nosso serviço está em execução. Agora podemos iniciar o comando curl na segunda guia do Cloud Shell para verificar se ele está funcionando como esperado:
$ curl localhost:8080/hello Hello World
Para interromper o contêiner, pressione Ctrl+C no Cloud Shell.
7. Como enviar nosso serviço em contêiner para o registro
Agora que a imagem funciona como esperado, envie-a para o Google Container Registry, um repositório particular para suas imagens Docker, acessível a partir de qualquer projeto na nuvem do Google (mas também de fora do Google Cloud Platform).
Antes de enviar para o registro, verifique se o Container Registry está ativado para o projeto. Para isso, acesse Ferramentas > Container Registry. Se ela não estiver ativada, a caixa de diálogo a seguir vai aparecer. Clique em Ativar a API Container Registry para ativar:

Quando o registro estiver pronto, execute os seguintes comandos para enviar a imagem a ele:
$ gcloud auth configure-docker
$ docker tag micronaut-jib:0.1 \
gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
$ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Os comandos acima permitem que o SDK gcloud configure e autorize o Docker a enviar imagens para sua instância do Container Registry, marque a imagem para apontar para a localização dela no registro e, em seguida, envie-a para o registro.
Se tudo der certo, depois de um tempo, a imagem do contêiner vai aparecer no console: Ferramentas > Container Registry. Agora você tem uma imagem do Docker disponível para todo o projeto que pode ser acessada e orquestrada pelo Kubernetes, como você verá em alguns minutos.

8. Crie o cluster
Agora você está pronto para criar seu cluster do Kubernetes Engine. Antes disso, navegue até a seção do Google Kubernetes Engine no console da Web e aguarde a inicialização do sistema (isso leva apenas alguns segundos).

Um cluster consiste em um servidor de API mestre do Kubernetes administrado pelo Google e um conjunto de nós de trabalho. Os nós de trabalho são máquinas virtuais do Compute Engine. Vamos usar a CLI gcloud da sua sessão do Cloud Shell para criar um cluster com dois nós n1-standard-1. Esse processo vai levar alguns minutos:
$ gcloud container clusters create hello-cluster \ --num-nodes 2 \ --machine-type n1-standard-1 \ --zone us-central1-c
No final, você verá o cluster criado.
Creating cluster hello-cluster in us-central1-c...done. Created [https://container.googleapis.com/v1/projects/mn-gke-test/zones/us-central1-c/clusters/hello-cluster]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-c/hello-cluster?project=mn-gke-test kubeconfig entry generated for hello-cluster. NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS hello-cluster us-central1-c 1.9.7-gke.7 35.239.224.115 n1-standard-1 1.9.7-gke.7 2 RUNNING
Agora você tem um cluster do Kubernetes totalmente funcional com o Google Kubernetes Engine:

Agora é hora de implantar o aplicativo em um contêiner no cluster do Kubernetes. A partir de agora, use a linha de comando kubectl (já configurada no ambiente shell do Cloud Shell). O restante deste codelab exige que a versão do cliente e do servidor do Kubernetes seja 1.2 ou superior. O kubectl version vai mostrar a versão atual do comando.
9. Implante o aplicativo no Kubernetes
Uma implantação do Kubernetes pode criar, gerenciar e escalonar várias instâncias do aplicativo usando a imagem do contêiner que você acabou de criar. Vamos criar uma implantação do aplicativo no Kubernetes usando o comando kubectl create deployment:
$ kubectl create deployment hello-micronaut \ --image=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Para ver a implantação que você acabou de criar, execute:
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 1 1 1 1 5m
Para ver as instâncias de aplicativo criadas pela implantação, execute este comando:
$ kubectl get pods NAME READY STATUS RESTARTS AGE hello-micronaut-5647fb98c5-lh5h7 1/1 Running 0 5m
Agora, você tem o contêiner em exibição sob o controle do Kubernetes, mas ainda precisa torná-lo acessível ao mundo exterior.
10. permitir o tráfego externo
Por padrão, o pod é acessível somente do seu IP interno dentro do cluster. Para tornar o contêiner hello-micronaut acessível de fora da rede virtual do Kubernetes, é necessário expor o pod como um serviço do Kubernetes.
Com o Cloud Shell, podemos expor o pod à Internet pública com o comando kubectl expose, combinado com a flag --type=LoadBalancer. A sinalização é obrigatória para a criação de um IP acessível externamente:
$ kubectl expose deployment hello-micronaut --type=LoadBalancer --port=8080
A flag usada nesse comando especifica que você vai usar o balanceador de carga fornecido pela infraestrutura subjacente (nesse caso, o balanceador de carga do Compute Engine). Você expôs a implantação, não o pod diretamente. Isso fará com que o serviço resultante faça o balanceamento de carga do tráfego em todos os pods gerenciados pela implantação (nesse caso, apenas um pod, mas você adicionará mais réplicas posteriormente).
O mestre do Kubernetes cria o balanceador de carga e as regras de encaminhamento do Compute Engine relacionadas, pools de destino e regras de firewall para tornar o serviço totalmente acessível de fora do Google Cloud Platform.
Para encontrar o endereço IP público do serviço, basta solicitar que o kubectl liste todos os serviços de cluster:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-micronaut LoadBalancer 10.39.243.251 aaa.bbb.ccc.ddd 8080:30354/TCP 1m kubernetes ClusterIP 10.39.240.1 <none> 443/TCP 31m
Há dois endereços IP listados para o serviço, ambos usando a porta 8080. Um é o IP interno que é visível apenas dentro da sua rede virtual na nuvem. Outro é o IP com balanceamento de carga externo. Neste exemplo, o endereço IP externo é aaa.bbb.ccc.ddd.
Agora, você deve conseguir acessar o serviço com este endereço no navegador: http://<EXTERNAL_IP>:8080/hello
11. escalonar o serviço verticalmente
Um dos poderosos recursos oferecidos pelo Kubernetes é a facilidade de escalonar seu aplicativo. Suponha que, de repente, você precise de mais capacidade para seu aplicativo. Basta dizer ao controlador de replicação para gerenciar um novo número de réplicas para as instâncias do aplicativo:
$ kubectl scale deployment hello-micronaut --replicas=3 deployment.extensions "hello-micronaut" scaled $ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 3 3 3 3 16m
Observe a abordagem declarativa aqui: em vez de iniciar ou interromper novas instâncias, você declara quantas instâncias precisam estar em execução o tempo todo. Os loops de reconciliação do Kubernetes garantem que a realidade corresponda ao solicitado e entre em ação, se necessário.
12. implementar uma atualização no serviço
Em algum momento, o aplicativo implantado na produção exigirá correções de bugs ou recursos adicionais. O Kubernetes ajuda você a implantar uma nova versão na produção sem afetar seus usuários.
Primeiro, vamos modificar o aplicativo. Abra o editor de código no Cloud Shell.

Navegue até /jib/examples/micronaut/src/main/groovy/example/micronaut/HelloController.groovy e atualize o valor da resposta:
@Controller("/hello")
class HelloController {
@Get("/")
String index() {
"Hello Kubernetes World"
}
}
No /jib/examples/micronaut/build.gradle, vamos fazer upgrade da versão da nossa imagem de 0.1 para 0.2 atualizando esta linha:
version '0.2'
Em seguida, recrie e empacote o aplicativo com as mudanças mais recentes:
$ ./gradlew jibDockerBuild
E marque e envie a imagem para o registro de imagens de contêiner:
$ docker tag micronaut-jib:0.2 \
gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2
$ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2
Agora já está tudo pronto para o Kubernetes atualizar o controlador de replicação para a nova versão do aplicativo. Para mudar o rótulo da imagem do contêiner em execução, edite o hello-micronaut deployment e mude a imagem de gcr.io/PROJECT_ID/micronaut-jib:0.1 para gcr.io/PROJECT_ID/micronaut-jib:0.2.
Use o comando kubectl set image para pedir ao Kubernetes que implante a nova versão do aplicativo em todo o cluster, uma instância por vez, com a atualização gradual:
$ kubectl set image deployment/hello-micronaut \
micronaut-jib=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2
deployment.apps "hello-micronaut" image updated
Verifique http://EXTERNAL_IP:8080 novamente para conferir se ele está retornando a nova resposta.
13. Reverter
Ops, você cometeu um erro com uma nova versão do aplicativo? Talvez a nova versão tenha um erro e você precise fazer um rollback rapidamente. Com o Kubernetes, é fácil reverter para o estado anterior. Vamos reverter o aplicativo executando:
$ kubectl rollout undo deployment/hello-micronaut
Se você observar a saída do serviço, vai ver que voltamos à mensagem inicial "Hello World".
14. Resumo
Nesta etapa, você configurou um serviço simples de hello world do Micronaut baseado em Apache Groovy e o executou diretamente no Cloud Shell, empacotou como um contêiner com Jib e implantou no Google Kubernetes Engine.
15. Parabéns!
Você aprendeu a criar e implantar um novo microsserviço baseado na Web do Apache Groovy / Micronaut no Kubernetes no Google Kubernetes Engine.
Saiba mais
- Documentação e exemplos do Jib: https://github.com/GoogleContainerTools/jib/
- Site do Micronaut: http://micronaut.io/
- Java no Google Cloud Platform: https://cloud.google.com/java/
- Exemplos em Java: https://cloud.google.com/java/samples
- Para um tutorial mais longo e completo do Kubernetes, acesse bit.ly/k8s-lab, que mostra como implantar um aplicativo de pilha completa.
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.