Executando aplicativos de inicialização com o Minikube

Executando aplicativos de inicialização com o Minikube

1. Visão geral

Nesteprevious article, cobrimos uma introdução teórica sobre o Kubernetes.

Neste tutorial,we’ll discuss how to deploy a Spring Boot application on a local Kubernetes environment, also known as Minikube.

Como parte deste artigo, nós:

  • Instale o Minikube em nossa máquina local

  • Desenvolver um aplicativo de exemplo que consiste em dois serviços Spring Boot

  • Configure o aplicativo em um cluster de um nó usando o Minikube

  • Implante o aplicativo usando arquivos de configuração

2. Instalando Minikube

A instalação do Minikube consiste basicamente em três etapas: instalação de um Hypervisor (como o VirtualBox), do CLIkubectl, além do próprio Minikube.

Oofficial documentation fornece instruções detalhadas para cada uma das etapas e para todos os sistemas operacionais populares.

Depois de concluir a instalação, podemos iniciar o Minikube, definir o VirtualBox como Hypervisor e configurarkubectl para se comunicar com o cluster chamadominikube:

$> minikube start
$> minikube config set vm-driver virtualbox
$> kubectl config use-context minikube

Depois disso, podemos verificar sekubectl se comunica corretamente com nosso cluster:

$> kubectl cluster-info

A saída deve ficar assim:

Kubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Nesta fase, vamos manter o IP na resposta próximo (192.168.99.100 em nosso caso). Mais tarde nos referiremos a isso comoNodeIP, que é necessário para chamar recursos de fora do cluster, e. g. do nosso navegador.

Por fim, podemos inspecionar o estado do nosso cluster:

$> minikube dashboard

Este comando abre um site em nosso navegador padrão, que fornece uma ampla visão geral sobre o estado do nosso cluster.

4. Aplicação de demonstração

Como nosso cluster está em execução e pronto para implantação, precisamos de um aplicativo de demonstração.

Para este propósito, criaremos um aplicativo simples “Hello world”, consistindo em dois serviços Spring Boot, que chamaremos defrontendebackend.

O backend fornece um ponto de extremidade REST na porta 8080, retornando umString contendo seu nome de host. O front-end está disponível na porta 8081, ele simplesmente chamará o terminal e retornará sua resposta.

Depois disso, precisamos criar uma imagem do Docker a partir de cada aplicativo. Todos os arquivos necessários para isso também estão disponíveison GitHub.

Para obter instruções detalhadas sobre como construir imagens Docker, dê uma olhada emDockerizing a Spring Boot Application.

We have to make sure here that we trigger the build process on the Docker host of the Minikube cluster, caso contrário, o Minikube não encontrará as imagens posteriormente durante a implantação. Além disso, o espaço de trabalho em nosso host deve ser montado na VM do Minikube:

$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
  --tag=demo-backend:latest --rm=true .

Depois disso, podemos sair do Minikube VM, todas as etapas seguintes serão executadas em nosso host usando as ferramentas de linha de comandokubectleminikube.

5. Implantação simples usando comandos imperativos

Em uma primeira etapa, criaremos uma implantação para nosso aplicativodemo-backend, consistindo em apenas um pod. Com base nisso, discutiremos alguns comandos para que possamos verificar a implantação, inspecionar os registros e limpá-los no final.

5.1. Criação da implantação

Usaremoskubectl, passando todos os comandos necessários como argumentos:

$> kubectl run demo-backend --image=demo-backend:latest \
  --port=8080 --image-pull-policy Never

Como podemos ver, criamos uma implantação chamadademo-backend, which que é instanciada a partir de uma imagem também chamadademo-backend, com a versãolatest.

Com–port, especificamos que a implantação abre a porta 8080 para seus pods (já que nosso aplicativodemo-backend escuta a porta 8080).

O sinalizador–image-pull-policy Never garante que o Minikube não tente puxar a imagem de um registro, mas sim do host Docker local.

5.2. Verificando a implantação

Agora, podemos verificar se a implantação foi bem-sucedida:

$> kubectl get deployments

A saída é assim:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend   1         1         1            1           19s

Se quisermos dar uma olhada nos logs do aplicativo, precisamos primeiro do ID do Pod:

$> kubectl get pods
$> kubectl logs 

5.3. Criação de um serviço para a implantação

Para disponibilizar o endpoint REST de nosso aplicativo de back-end, precisamos criar um serviço:

$> kubectl expose deployment demo-backend --type=NodePort

–type=NodePort disponibiliza o serviço de fora do cluster. Ele estará disponível em<NodeIP>:<NodePort>, i. e. o serviço mapeia qualquer solicitação recebida em<NodePort> para a porta 8080 de seus pods atribuídos.

Usamos o comando expose, entãoNodePort será definido pelo cluster automaticamente (esta é uma limitação técnica), o intervalo padrão é 30000-32767. Para obter uma porta de nossa escolha, podemos usar um arquivo de configuração, como veremos na próxima seção.

Podemos verificar se o serviço foi criado com sucesso:

$> kubectl get services

A saída é assim:

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend   NodePort    10.106.11.133           8080:30117/TCP   11m

Como podemos ver, temos um serviço chamadodemo-backend, do tipoNodePort, que está disponível no IP interno do cluster 10.106.11.133.

Temos que examinar mais de perto a coluna PORT (S): como a porta 8080 foi definida na implantação, o serviço encaminha o tráfego para essa porta. No entanto, se quisermos chamardemo-backend  de nosso navegador, temos que usar a porta 30117, que pode ser acessada de fora do cluster.

5.4. Ligar para o serviço

Agora, podemos ligar para o nosso serviço de back-end pela primeira vez:

$> minikube service demo-backend

Este comando iniciará nosso navegador padrão, abrindo<NodeIP>:<NodePort>. Em nosso exemplo, seriahttp://192.168.99.100:30117.

5.5. Limpeza do serviço e implantação

Posteriormente, podemos remover o Serviço e implantação:

$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

6. Implantação complexa usando arquivos de configuração

Para configurações mais complexas, os arquivos de configuração são uma escolha melhor, em vez de passar todos os parâmetros por meio de argumentos da linha de comando.

Os arquivos de configuração são uma ótima maneira de documentar nossa implantação e podem ser controlados por versão.

6.1. Definição de serviço para nosso aplicativo de back-end

Vamos redefinir nosso serviço para o back-end usando um arquivo de configuração:

kind: Service
apiVersion: v1
metadata:
  name: demo-backend
spec:
  selector:
    app: demo-backend
  ports:
  - protocol: TCP
    port: 8080
  type: ClusterIP

Criamos umService denominadodemo-backend, indicado pelo campometadata: name.

Ele tem como alvo a porta TCP 8080 em qualquer pod com o rótuloapp=demo-backend.

Por fim,type: ClusterIP indica que está disponível apenas de dentro do cluster (como queremos chamar o endpoint de nosso aplicativodemo-frontend desta vez, mas não diretamente de um navegador mais, como no exemplo anterior )

6.2. Definição de implantação para aplicativo de back-end

Em seguida, podemos definir a implantação real:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-backend
spec:
  selector:
      matchLabels:
        app: demo-backend
  replicas: 3
  template:
    metadata:
      labels:
        app: demo-backend
    spec:
      containers:
        - name: demo-backend
          image: demo-backend:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 8080

Criamos umDeployment denominadodemo-backend, indicado pelo campometadata: name.

O campospec: selector define como a implantação encontra quais pods gerenciar. Nesse caso, simplesmente selecionamos um rótulo definido no modelo do Pod (app: demo-backend).

Queremos ter três pods replicados, que indicamos pelo camporeplicas.

O campo do modelo define o Pod real:

  • Os pods são rotulados comoapp: demo-backend

  • O campotemplate: spec indica que cada replicação de pod executa um contêiner,demo-backend, com versãolatest

  • Os Pods abrem a porta 8080

6.3. Implantação do aplicativo de back-end

Agora podemos acionar a implantação:

$> kubectl create -f backend-deployment.yaml

Vamos verificar se a implantação foi bem-sucedida:

$> kubectl get deployments

A saída é assim:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend   3         3         3            3           25s

Também podemos verificar se o Serviço está disponível:

$> kubectl get services

A saída é assim:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend    ClusterIP   10.102.17.114           8080/TCP         30s

Como podemos ver, o serviço é do tipoClusterIP, e não fornece uma porta externa no intervalo 30000-32767, diferente de nosso exemplo anterior na seção 5.

6.4. Implementação e definição de serviço para nosso aplicativo de front-end

Depois disso, podemos definir Serviço e Implantação para o frontend:

kind: Service
apiVersion: v1
metadata:
  name: demo-frontend
spec:
  selector:
    app: demo-frontend
  ports:
  - protocol: TCP
    port: 8081
    nodePort: 30001
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-frontend
spec:
  selector:
      matchLabels:
        app: demo-frontend
  replicas: 3
  template:
    metadata:
      labels:
        app: demo-frontend
    spec:
      containers:
        - name: demo-frontend
          image: demo-frontend:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 8081

O front-end e o back-end são quase idênticos,the only difference between backend and frontend is the spec of the Service:

Para o frontend, definimos o tipo comoNodePort  (pois queremos tornar o frontend disponível para fora do cluster). O back-end só precisa ser acessado de dentro do cluster, portanto,type eraClusterIP.

Como dito antes, também especificamosNodePort manualmente, usando o camponodePort.

6.5. Implantação do aplicativo de front-end

Agora podemos acionar essa implantação da mesma maneira:

$> kubectl create -f frontend-deployment.yaml

Vamos verificar rapidamente se a implantação foi bem-sucedida e se o serviço está disponível:

$> kubectl get deployments
$> kubectl get services

Depois disso, podemos finalmente chamar o ponto de extremidade REST do aplicativo frontend:

$> minikube service demo-frontend

Este comando irá iniciar novamente nosso navegador padrão, abrindo<NodeIP>:<NodePort>, que éhttp://192.168.99.100:30001 para este exemplo.

6.6. Limpeza de serviços e implantações

No final, podemos limpar removendo Serviços e Implantações:

$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

7. Conclusão

Neste artigo, vimos rapidamente como implantar um aplicativo “Hello world” do Spring Boot em um cluster local do Kubernetes usando o Minikube.

Discutimos em detalhes como:

  • Instale o Minikube em nossa máquina local

  • Desenvolva e construa um exemplo que consiste em dois aplicativos Spring Boot

  • Implante os serviços em um cluster de um nó, usando comandos imperativos comkubectl, bem como arquivos de configuração

Como sempre, o código-fonte completo dos exemplos está disponívelover on GitHub.