Fazendo deploy de MONGO, REDIS API E FRONT no Kubernets

Este projeto tem repositório no github: https://github.com/ramondomiingos/PPGTI2001-cloud-computing/. Então, alguns códigos mais extensos estão apenas lá, e não aqui, principalmente os .yaml . Mas sempre irei botar o link para o exato arquivo que estou me referenciando.

Este projeto foi a avaliação da disciplina Computação em Nuvem, PPGTI2001, do mestrado da UFRN. É necessário criar um pod com vários contêineres, deve ser gerado e atender aos seguintes requisitos:

– O pod deve ter 4 containers e deve ser criado usando um Manifesto do Kubernetes (arquivo yaml);

Alunos:

-Ramon Domingos Duarte Oliveira

Gerfesson Santos da Nóbrega

Já que você ja aprendeu a configurar o k8s em sua máquina, conforme o post anterior, agra vamos subir as aplicações.

front,back, cache e mongodb.

Sobre aplicativos

API

API de registro de produto

{

"nome": "PEN_BLACK",

"description": "caneta preta, com corpo transparente",

"qtdDisponível": 12

}

  • /produto `(get, post)`
  • /produto/:id `(put, delete, get)`

FRONT

Aplicativo que consome a API, exibindo listagens e formulários.

Usando https://refine.dev/ como modelo base.

Docker-compose

version: '3.7'
services:
  redis-service:
    container_name: redis-database
    image: 'bitnami/redis:latest'
    ports:
      - "6379:6379"
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
  front:
    build:
      context: ./front
      dockerfile: Dockerfile
    container_name: front
    expose:
      - '3000'
    ports:
      - '3000:3000'
    environment:
      API_URL: api
      NEXT_PUBLIC_API_URL: api
      NEXT_PUBLIC_API_URL_PORT: 8002
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    container_name: api
    expose:
      - '8002'
    ports:
      - '8002:8001'
    environment:
      - PORT=8001
      - REDIS_URL=redis-service
      - REDIS_PORT=6379
      - REDIS_EXPIRE=10
      - MONGO_USERNAME=root
      - MONGO_PASSWORD=example
      - MONGO_URL=mongo:27017
      - MONGO_DB=product
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    ports:
      - '27017:27017'

Para executar usando apenas docker-compose use:

docker-compose up

Serviços:

  • mongo: MongoDB para registro de produtos
  • redis: cache para solicitações frequentes
  • api: API REST para conectar-se ao banco de dados.
  • front: Frente usando React.

Kubernets

Etapa 1: Envie estas imagens para DockerHub pessoal (opcional)

Para construir a imagem da API

cd api
docker build -t <your_username>/api-products .
docker push  <your_username>/api-products

Para construir a imagem do front

cd frontend
docker build -t <your_username>/front-products .
docker push  <your_username>/front-products

Se você criar imagens personalizadas, vá para os arquivos `k8s/*-deployment` e altere a imagem para a sua.

As imagens MONGO e REDIS são imagens oficiais, já estão disponíveis no dockerhub para uso.

Espera-se que o ambiente da máquina já esteja pré-configurado e domine um trabalhador unido, usando o comando `kubeadm join –token`

Etapa 2: Criar namespace

kubectl get ns

kubectl create namespace products-application

kubectl get ns

kubectl config get-contexts

kubectl config set-context --current --namespace=products-application

[output]

kubectl config set-context –current –namespace=products-application

kubectl config get-contexts

[output]

CURRENTNAMECLUSTERAUTHINFONAMESPACE
*kubernetes-admin@kubernetes kuberneteskubernetes-admin products-api

Etapa 3: crie uma implantação

Nos arquivos de implantação, há detalhes sobre o **image docker** e um **imagePullPolicy**. Neste exemplo é Sempre,

para Sempre implantar, obtenha uma nova imagem para o dockerhub.

O comando de linha é

kubectl create deployment redis --image=redis --port=5701

mas, no diretório k8s tem 4 arquivos yaml para [api,front,mongo,redis]-deployment.yaml

exempo do api-deployment

apiVersion: apps/v1
kind: Deployment
metadata:
metadata:
  annotations:
   
   
metadata:   
  annotations:
   
   
  labels:
    app: api
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      annotations:
      annotations:
       
       
      annotations: 
       
       
      labels:
        app: api
    spec:
      containers:
        - env:
            - name: MONGO_DB
              value: product
            - name: MONGO_PASSWORD
              value: example
            - name: MONGO_URL
              value: $(MONGO_SERVICE_HOST):27017
            - name: MONGO_USERNAME
              value: root
            - name: PORT
              value: "8001"
            - name: REDIS_EXPIRE
              value: "10"
            - name: REDIS_PORT
              value: "6379"
            - name: REDIS_URL
              value: $(REDIS_SERVICE_SERVICE_HOST)
          image:  ramondomiingos/api-products
          imagePullPolicy: Always
          name: api
          ports:
            - containerPort: 8001
              hostPort: 8001
              protocol: TCP
      restartPolicy: Always

Os outros estão na mesma pasta [mongo, redis e front]

### Etapa 4: crie um serviço

para expor a aplicação para fora do k8s, é necessário criar um serviço

Você pode criar com um comando:

kubectl create service nodeport web-products --tcp=3000:3000 --node-port=30300

confira a criação

kubectl get service

NAMETYPECLUSTER-IPEXTERNAL-IP PORT(S) AGE
web-products NodePort10.97.135.212 <none> 3000:30300 | TCP 3s

No diretório k8s tem 4 arquivos yaml para [api,front,mongo,redis]-service.yaml

Etapa 5: Envie arquivos para o nó MASTER.

na pasta `k8s`tem 9 arquivos implantação e serviço para [api, front, mongo e Redis]

e 1 arquivo para **ingress**;

envie este arquivo para o seu mestre (pode usar scp)

scp k8s/* remote_username@10.10.0.2:/remote/directory

### Etapa 6: Aplicar arquivo de especificação

Em sequência é necessário aplicar este arquivo e verificar os pods.

kubectl apply -f .

“`

**[output]**

For apply all files use `kubectl apply -f .`

**[output]**

~kubectl apply -f .

deployment.apps/api created

service/api created

deployment.apps/front created

service/front created

deployment.apps/mongo created

service/mongo created

deployment.apps/redis-service created

service/redis-service created

kubectl get pods

output

NAMEREADYSTATUSRESTARTSAGE
web-products0/4ContainerCreating040s

enquanto os contêineres são criados, verifique os logs com:

kubectl logs web-products

Se demorar muito para criar os containers com sucesso, verifique os logs individualmente para ver se ocorreu algum erro, se necessário corrija e aplique este arquivo novamente.

kubectl logs web-products -c [redis-service, mongo, frontend, api]

> erro example:

NAMEREADYSTATUSRESTARTSAGE
web-products3/4CrashLoopBackOff010m

depois de alguns segundos, você pode executar este mesmo comando e verá:

NAMEREADYSTATUSRESTARTSAGE
web-products4/4Running022s

Etapa 7: Verifique sua aplicação.

Vá para o navegador, visite `http://<ip-worker>:3000` e veja o aplicativo.

3000 é a porta exposta em arquivos yaml.

Não contemplei volumes persistentes.

Aprendizagem pessoal

– No nosso cenário precisamos expor a api, já que as requisições feitas pelo front eram do lado do cliente, usar um IP interno não funcionaria.

– Todos os pods possuem muitas variáveis de ambiente no formato `<NAME>_SERVICE_HOST` para identificar outros serviços e podem ser usados em yaml como ambientes de configuração. [Exemplo](k8s/api-deployment.yaml) linha 39.

– Para ver todos os ambientes você pode usar `kubectl exec <pod-name> printenv`.

– Outro formato para URL é `<service-name>.<namespace|default>.svc.cluster.local:<service-port>`;