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
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]
CURRENT | NAME | CLUSTER | AUTHINFO | NAMESPACE |
* | kubernetes-admin@kubernetes | kubernetes | kubernetes-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
NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE |
web-products | NodePort | 10.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
NAME | READY | STATUS | RESTARTS | AGE |
web-products | 0/4 | ContainerCreating | 0 | 40s |
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:
NAME | READY | STATUS | RESTARTS | AGE |
web-products | 3/4 | CrashLoopBackOff | 0 | 10m |
depois de alguns segundos, você pode executar este mesmo comando e verá:
NAME | READY | STATUS | RESTARTS | AGE |
web-products | 4/4 | Running | 0 | 22s |
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>`;