Kubernetes (DOKS)

A DigitalOcean oferece uma plataforma em nuvem com o recurso gerenciado de Kubernetes (DOKS), altamente escalável conforme a demanda, permitindo instanciá-lo em questão de segundos utilizando um conjunto de nodes baseados na tecnologia Dropnet e possibilitando a rápida disponibilização de aplicações de microsserviços desenvolvidas utilizando a plataforma Devprime.

Devprime using DigitalOcean

Introdução

A plataforma Devprime acelera a produtividade do desenvolvedor de software, oferecendo um projeto completo de arquitetura de software, componentes com comportamentos inteligentes, aceleradores para implementação de código e atualizações com novos recursos.

Neste artigo, abordaremos o uso do serviço Kubernetes (DOKS) da DigitalOcean, uma plataforma de cloud que oferece diversos recursos para o desenvolvedor de software utilizar nas aplicações.

Nós utilizaremos dois microsserviços com uma regra de negócio relacionada a pedidos e outra a pagamentos utilizando o banco de dados MongoDB gerenciado pela DigitalOcean. Demonstraremos os passos para criar o microsserviço, os serviços de cloud na DigitalOcean como o Kubernetes (DOKS), Container Registry, MongoDB e implantaremos o RabbitMQ dirante no Kubernetes, em seguida, as configurações iniciais necessárias.

Checklist e preparação do ambiente inicial

Primeiros passos

Neste artigo, utilizaremos um projeto com dois Microsserviços utilizando comunicação assíncrona, sendo o primeiro Order e o segundo Payment que você pode optar por criar do zero ou utilizando o exemplo no GitHub.

a) Execute um clone do projeto no GitHub:
git clone https://github.com/devprime/devprime-microservices-order-payment.git

b) Acesse a pasta clonada e verifique a pasta inicial com os itens Order e Payment. Cada pasta desta tem um microsserviço desenvolvido com a plataforma Devprime e pronto para utilização.
cd devprime-microservices-order-payment
git remote remove origin

c) Execute o comando dp stack para aplicar atualização e a sua licença Devprime:
dp stack

d) Execute cada microsserviço em uma aba do terminal para testar localmente utilizando os arquivos .\run.ps1 no Windows ou run.sh no Linux e macOS. Aplique a permissão chmod no Linux, macOS.
chmod +x run.sh

Inicie o microsserviço executando um dos scripts abaixo:
.\run.ps1 (Windows) ou ./run.sh (Linux, macOS)

  • /ms-order
  • /ms-payment

Com os microsserviços rodando efetue um post na API do microsserviço order e acompanhe o processamento no microsserviço payment conforme descrito no artigo sobre comunicação assíncrona entre microsserviços.

Criando um cluster Kubernetes (DOKS), Container Registry e MongoDB na DigitalOcean

Acesse o seu portal na DigitalOcean e no menu Kubernetes, entre na opção Create Cluster para iniciar o procedimento de criação e em node plan escolha o tamanho apropriado ao seu cenário, defina a quantidade de instâncias e avance com o processo. Execute o mesmo procedimento com o Container Registry e em Database com MongoDB criando os serviços iniciais para utilização nesse artigo.

Na imagem abaixo é apresentado uma visão dos primeiros serviços criados MongoDB e Kubernetes.

Devprime using DigitalOcean

Após criar o cluster do MongoDB é fundamental acessar o item Connection String e copiar para utilizarmos na configuração nos microsserviços (order/payment). Copie toda a string de conexão e certifique que a mesma está com o usuário e a senha.

Devprime using DigitalOcean

O cluster Kubernetes foi noemado como ““do-k8s-nyc1-demo” para utilização nesse artigo. No item marketplace você tem alguns recursos interessantes para implantação no cluster usando 1-Click Apps como NGINX Ingress Controller, Cert-Manager, OpenEBS NFS Provisioner, Kubernetes Monitoring Stack.

Devprime using DigitalOcean

Para publicar containers no Kubernetes, nós utilizaremos o Container Registry que nesse attigo está nomeado como “dp-registry-nyc3”. Copie nesse momento a url apresentada, pois utilizaremos mais a frente no momento de criação da imagem do container.

Devprime using DigitalOcean

Agora é necessário seguir um passo importante realizando o vinculo do seu Cluster Kubernetes com o Container Registry para facilitar o acesso aos containeres dentro do cluster. No portal do seu Ckuster Kubernetes, entre em Settings e depois entre na opção “DigitalOcean Container Registry Integration” e selecione o Container Registry.

Devprime using DigitalOcean

Instalando ferramentas para utilização no Kubernetes

Nós utilizaremos algumas ferramentas para integração com o Kubernetes como o kubectl, que é o CLI do Kubernetes, Helm, ferramenta para instalar pacotes no Kubernetes, K9S ferramenta para visualizar o cluster, Stern, ferramenta para visualizar logs no Kubernetes, doctl, DigitalOcean’s command-line tool e Docker.

Após instalar o CLI doctl, é fundamental seguir os procedimentos de configuração do mesmo para ativar o acesso na DigitalOcean e habilitar as operações como obteção de credenciais do Container Registry e do Kubernetes.

Obtendo acesso ao Kubernetes

As credenciais de acesso ao Cluster do Kubernetes podem ser obtidas pelo portal ou utilizando o CLI doctl, conforme faremos durante esse artigo.

  • Obtendo as credenciais de acesso ao Cluster ao confirmar será salvo no ambiente local “.kube/config”. Copie esse comando diretamente do portal com o Guid do seu cluster.
    doctl kubernetes cluster kubeconfig save a61716c9-c207-4c23-b789-399a811ef050

  • Listando todos os pods do Cluster
    kubectl get pods --all-namespaces

  • Utilizando o k9s para visualizar o Cluster
    k9s

Na imagem estamos listando todos os containers ativos implantados na criação do cluster. Nos próximos passos iniciaremos a criação do container do order e do payment.

Devprime using DigitalOcean

Criando imagens Docker e publicando no Container Registry

Um passo importante no cenário do Kubernetes é construir a imagem Docker dos nossos microsserviços para que possamos realizar a publicação dentro do ambiente do Cluster Kubernetes.

Autenticando o Docker no Container Registry
doctl registry login

Construindo a imagem do microsserviço order no Docker

  • Entre na primeira do microsserviço order e execute
    /ms-order
    docker build -t ms-order .

  • Crie uma tag para essa imagem
    docker tag ms-order registry.digitalocean.com/dp-registry-nyc3/ms-order:latest

  • Efetuando o push enviando para o Docker
    docker push registry.digitalocean.com/dp-registry-nyc3/ms-order:latest

Construindo a imagem do microsserviço payment no Docker

  • Entre na segunda pasta do microsserviço payment e execute
    /ms-payment
    docker build -t ms-payment .

  • Crie uma tag para essa imagem
    docker tag ms-payment registry.digitalocean.com/dp-registry-nyc3/ms-payment:latest

  • Efetuando o push enviando para o Docker
    docker push registry.digitalocean.com/dp-registry-nyc3/ms-payment:latest

Ao final desse procedimento de push nas imagens do order e payment será possível conferir no portal do Container Registry e já estão prontas
para utilização no Kubernetes.

Devprime using DigitalOcean

Implantando o RabbitMQ no Kubernetes

A plataforma Devprime habilita a conectividade com diversos serviços de Stream com RabbitMQ, Kafka e outros e nesse projeto nós vamos utilizar o helm para implantar o RabbitMQ no cluster. Você pode optar a depender do cenário no seu projeto em utilizar o serviço de Kafka gerenciado oferecido pela Digital Ocean ou outra alternativa para comunicação entre os microsserviços.

Implantando o RabbitMQ utilizando o Helm. Altere o usuário e senha a seu critério.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install rabbitmq bitnami/rabbitmq --set auth.username=admin --set auth.password=MQ@passX6DP

O processo de implantação do RabbitMQ demora um certo tempo até concluir e você pode acompanhar pelo K9S. Após a instalação você pode mapear as portas do RabbitMQ no ambiente local para acessar. Antes de realizar o mapemaento é fundamental parar o container local do RabbiMQ para evitar conflitos de portas TCP.

Portas do RabbitMQ

  • RabbitMQ AMQP port:
    kubectl port-forward --namespace default svc/rabbitmq 5672:5672
  • RabbitMQ Web Management interface:
    kubectl port-forward --namespace default svc/rabbitmq 15672:15672

Definindo a configuração inicial do RabbitMQ
Efetue o mapeamento da porta 15672 e acesse o portal administrativo do RabbitMQ pela url http://localhost:15672 para configurar as filas ‘orderevents’ e ‘paymentevents’ no RabbitMQ e relacione com a “exchange” conforme a documentação do RabbitMQ na Devprime com o objetivo de habilitar esse artigo.

Analisando as credenciais do MongoDB e RabbitMQ nos microsserviços ambientes locais

No ambiente local, você pode editar as configurações e credenciais da aplicação no arquivo src/App/appsettings.json, como os dados de acesso ao MongoDB e ao RabbitMQ utilizados no projeto e outros itens disponiveis na documentação de configuração da Devprime.

Para abrir a configuração de cada microsserviço entre na pasta relacionada
/ms-order
/ms-payment

Abra pelo Visual Studio Code ou outro editor
code src/App/appsettings.json

Visualiuze na chave RabbitMQ e do MongoDB as credenciais do utilizadas no ambiemte local e podem ser modificadas a qualquer momento.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
  "DevPrime_Stream": [
    {
      "Alias": "Stream1",
      "Enable": "true",
      "Default": "true",
      "StreamType": "RabbitMQ",
      "HostName": "Localhost",
      "User": "guest",
      "Password": "guest",
      "Port": "5672",
      "Exchange": "devprime",
      "ExchangeType": "direct",
      "Retry": "3",
      "Fallback": "State1",
      "Threads": "30",
      "Buffer": "1",
      "Subscribe": []
    }
  ],
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  "DevPrime_State": [
    {
      "enable": "true",
      "alias": "State1",
      "type": "db",
      "dbtype": "mongodb",
      "connection": "mongodb://mongoadmin:LltF8Nx*yo@localhost:27017",
      "timeout": "5",
      "retry": "2",
      "dbname": "ms-order",
      "isssl": "true",
      "durationofbreak": "45"
    }
  ],

Configurando as credenciais do MongoDB e RabbitMQ no Kubernetes

Em nosso contexto criremos um arquivo de dpeloyment para cada microsserviço e utilizeremos Devprime CLI para construir o arquivo inicial deployment.yml e service.yml executando o comando na pasta de cada microsserviço e depois realizaremos a configuração com as credenciais que utilizaremos nos microsserviços ordeer e payment dentro do cluster Kubernetes.

Entre em cada pasta do microsserviço e execute o “dp export kubernetes”
/ms-order
/ms-payment
dp export kubernetes

O resultado será similar ao trecho abaixo com dois arquivos criados com as configurações iniciais necessárias para publicarmos
no Kubernetes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 ____             ____       _
|  _ \  _____   _|  _ \ _ __(_)_ __ ___   ___
| | | |/ _ \ \ / / |_) | '__| | '_ ` _ \ / _ \
| |_| |  __/\ V /|  __/| |  | | | | | | |  __/
|____/ \___| \_/ |_|   |_|  |_|_| |_| |_|\___|
  Empower developers. Accelerate productivity
==============================================
Welcome to the DevPrime CLI v8.0.8

Export configurations kubernetes

.devprime/kubernetes/deployment.yml' created
.devprime/kubernetes/service.yml' created

Agora chegou o momento de editar o arquivo “deployment.yml” e localize
o item “image” na pasta do order e na pasta do payment.

Abra a pasta no Visual Studio Code ou outro editor
code .devprime

Arquivo: deployment.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion : apps/v1
kind: Deployment
metadata:
  name: ms-order
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ms-order
  template:
    metadata:
      labels:
        app: ms-order
    spec:
      containers:
        - name: ms-order 
          image: ms-order:latest

Realize o procedimento para cada microsserviço (order / payment) e altere o item image para o path da sua imagem no Container Registry. A url
do Container Registry é a mesma utilizada pelo comando push do docker.

Arquivo: order/deployment.yaml

1
2
3
      containers:
        - name: ms-order 
          image: registry.digitalocean.com/dp-registry-nyc3/ms-order:latest

Arquivo: payment/deployment.yaml

1
2
3
      containers:
        - name: ms-order 
          image: registry.digitalocean.com/dp-registry-nyc3/ms-payment:latest

Agora chegou um momento de configurar em cada microsserviço as credenciais de produçao do RabbitMQ e do
MongoDB fornecidas pela DigitalOcean e tratadas no inicio do arquivo onde falamos sobre Connection String.

Arquivo:deployment.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
         env:
           - name: devprime_stream1
             value: "alias=Stream1|||enable=true|||default=true|||streamtype=RabbitMQ
        |||hostname=rabbitmq.default.svc|||user=admin|||password=guest|||port=5672|||
             exchange=devprime|||exchangetype=direct|||retry=3|||fallback=State1|||
             threads=30|||buffer=1"
           - name: devprime_state1
             value: "enable=true|||alias=State1|||type=db|||dbtype=mongodb|||
             connection=mongodb.default.svc|||timeout=5|||retry=2|||
             dbname=ms-order|||isssl=true|||durationofbreak=45"

No item devprime_stream1 altere o usuário para “admin” e a senha para “MQ@passX6DP”.
no item devprime_state1 altere a connection pela Connection String do MongoDB na DigitalOean.

Abaixo é possível conferir um exemplo após as alterações que devem ser feitas nos arquivos de deployment dos microsserviços (order/payment). Faça a alteração diretamente em cada arquivo para evitar modificar outros parâmetros nessa demonstração, pois as chaves têm pequenas diferenças entre os microsserviços.

Arquivo:deployment.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
         env:
           - name: devprime_stream1
             value: "alias=Stream1|||enable=true|||default=true|||streamtype=RabbitMQ|||
             hostname=rabbitmq.default.svc|||user=admin|||password=MQ@passX6DP|||
             port=5672|||exchange=devprime|||exchangetype=direct|||retry=3
             |||fallback=State1|||threads=30|||buffer=1"
           - name: devprime_state1
             value: "enable=true|||alias=State1|||type=db|||dbtype=mongodb|||
             connection=mongodb+srv://user:password@
             do-mongodb-nyc1-demo-29a3fecf.mongo.ondigitalocean.com/admin?
             tls=true&authSource=admin&replicaSet=do-mongodb-nyc1-demo|||timeout=5|||
             retry=2|||dbname=ms-order|||isssl=true|||durationofbreak=45"
           - name: Devprime_Custom

Executando o deployment dos microsserviços no Kubernetes

Agora chegou o momento mais esperado, onde iremos publicar efetivamente os microsserviços (order e payment) dentro do cluster Kubernetes e para isso utilizaremos os arquivos deployment.yml e service.yml de cada microsserviço.

Entre em cada pasta e execute os comandos abaixo:

  • Para o microsserviço order

    • Navegue até a pasta do Kubernetes do serviço order:
      ms-order/.devprime/kubernetes
    • Aplique o deployment e o serviço:
      kubectl apply -f deployment.yml
      kubectl apply -f service.yml
  • Para o microsserviço ayment

    • Navegue até a pasta do Kubernetes do serviço payment:
      ms-payment/.devprime/kubernetes
    • Aplique o deployment e o serviço:
      kubectl apply -f deployment.yml
      kubectl apply -f service.yml

Agora que terminamos de efetuar o nosso deployment dos dois microsserviços, podemos visualizar diretamente no cluster pela ferramenta k9s ou utilizando o kubectl.

Devprime using DigitalOcean

Efetuando um teste no microsserviço

Abra uma aba do terminal e execute o comando port-forward para mapear o microsserviço order na porta local 8080 e permitir realizar o primeiro teste acessando a plataforma diretamente no cluster.

  • Execute o comando para o Order
    kubectl port-forward --namespace default svc/ms-order 8080:80

  • Acesse a URL e efetue um POST no microsserviço order para que processe e emita um evento na fila do RabbitMQ e propague para o microsserviço payment
    http://localhost:8080

Devprime using DigitalOcean

Atribuindo um IP público ao microsserviço order

Abra o arquivo ms-order/.devprime/kubernetes/service.yml com o Visual Studio Code e altere o “ClusterIP” para “LoadBalancer”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: Service
metadata:  
  name: ms-order
spec:
  selector:    
    app: ms-order
  type: LoadBalancer
  ports:  
  - name: http
    port: 80
    targetPort: 80

Excluindo o service ms-order:
kubectl delete svc ms-order

Recriando o service ms-order:
kubectl apply -f service.yml

Agora consulte a atualização até receber um IP público no microsserviço order:
kubectl get svc ms-order -w

NAME       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
ms-order   LoadBalancer   10.245.38.41   157.x.x.x   80:31256/TCP   2m32s

Visualizando logs no Kuberbernetes

Os microsserviços baseados na plataforma Devprime disponibilizam uma abordagem de observabilidade automática de logs distribuídos que podem ser visualizados pelo kubectl, k9s, stern e indexados em ferramentas como SEQ, Elastic Search e muitas outras para acompanhar o comportamento das aplicações no ambiente produtivo.

Nesse exemplo, utilizaremos a ferramenta stern para visualizar o log de cada deployment:

  • Abra uma aba para o microsserviço ‘order’ no terminal e execute:
    stern ms-order
  • Abra uma aba para o microsserviço ‘payment’ no terminal e execute:
    stern ms-payment
  • Agora, utilize o mapeamento de porta ou IP público e realize um post no microsserviço ‘order’ para conferir um resultado. No log abaixo, você verá um resumo do ‘order’ como exemplo.
[INF][ms-order][Web]["http://*:80"][Host]["Production"][Parameters]["Environment"][RID 30c1c7a9-7799-43e6-a1b2-5d4007b3edb8][TID 30c1c7a9-7799-43e6-a1b2-5d4007b3edb8]
[INF][ms-order][Stream][Type "RabbitMQ"][Alias "Stream1"]["Enable"][RID 30c1c7a9-7799-43e6-a1b2-5d4007b3edb8][TID 30c1c7a9-7799-43e6-a1b2-5d4007b3edb8]
[INF][ms-order][Web]["HTTP"][Order][POST /v1/order][Origin "http://localhost/swagger/index.html"][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Application][OrderService][Add][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Domain][Order][Add][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Domain][Order][ProcessEvent]["CreateOrder"][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Application][EventHandler]["CreateOrderEventHandler"][Event]["CreateOrder"][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][State][Type "MongoDB"][Alias "State1"][Initialize][OrderRepository][Add][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][State][Type "MongoDB"][Alias "State1"][Complete][OrderRepository][Add][Duration 1192.1472ms][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Domain][Order][ProcessEvent]["OrderCreated"][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Application][EventHandler]["OrderCreatedEventHandler"][Event]["OrderCreated"][RID c1461cc3-7000-473d-a62c-915867954ced][TID c1461cc3-7000-473d-a62c-915867954ced]
[INF][ms-order][Stream][Type "RabbitMQ"][Alias "Stream1"][Out][Event]["OrderCreated"]["Delivered"]["orderevents"]
["{\""Payload\":{\"ID\":\"ca9983\",\"CustomerName\":\"Ramon Duraes\",\"CustomerTaxID\":\"AC875512\",\"Total\":1200}}"]

Considerações finais

Durante este artigo, demonstramos a publicação de dois microsserviços (order e payment) desenvolvidos utilizando a tecnologia da plataforma Devprime no cluster Kubernetes (DOKS) da DigitalOcean, em conjunto com os serviços de Container Registry e MongoDB gerenciados e com o RabbitMQ que implantamos no cluster utilizando o Helm. Você acompanhou também como acessar o serviço utilizando um IP interno e um IP Externo e visualizar os logs.

Em um ambiente produtivo, é fundamental adicionar um nginx ingress, um dominio de internet e Let’s Encrypt para gerar um certificado SSL, utilizar um serviço de DevOps para automatizar a publicação, cofre digital para credenciais, proteção de acesso com um API Gateway, provedor de identidade e Web Application Firewall.

Para saber mais

Última modificação April 16, 2024 (2b35fcc8)