- 1 Kubernetes
- 1.1 O que é orquestração de containers?
- 1.2 O que é Kubernetes?
- 1.3 Conceitos fundamentais
- 1.4 Dependências necessárias
- 1.5 Instalando Kubernetes e dependências no Linux
- 1.6 Inicializando Minikube
- 1.7 Parando o Minikube
- 1.8 Acessando a dashboard do Kubernetes
- 1.9 Deployment teoria
- 1.10 Criando o projeto
- 1.11 Criando o Deployment
- 1.12 Verificando Deployments
- 1.13 Verificando Pods
- 1.14 Configurações do Kubernetes
- 1.15 Services na teoria
- 1.16 Criando um Service
- 1.17 Gerando um IP para o Services
- 1.18 Verificando os nossos Services
- 1.19 Replicando nossa aplicação
- 1.20 Checar número de réplicas
- 1.21 Diminuindo número de réplicas
- 1.22 Atualizando a imagem do projeto
- 1.23 Desfazendo alteração do projeto
- 1.24 Deletando Service
- 1.25 Deletando Deployment
- 1.26 Modo declarativo
- 1.27 Chaves mais utilizadas do modo declarativo
- 1.28 Criando o Deployment do modo declarativo
- 1.29 Executando o arquivo de Deployment
- 1.30 Parando o Deployment
- 1.31 Criando o Service do modo declarativo
- 1.32 Iniciando o Service
- 1.33 Parando o Service
- 1.34 Atualizando o projeto no modo declarativo
- 1.35 Unindo arquivos do projeto
- Orquestração é o ato de conseguir gerenciar e escalar os containers da aplicação;
- Temos um serviço que rege sobre os outros serviços, verificando se os mesmos estão funcionando como deveriam;
- Desta forma conseguimos garantir uma aplicação saudável e também que esteja sempre disponível;
- Alguns serviços: Docker Swarm, Kubernetes e Apache Mesos;
- Uma ferramenta de orquestração de containers;
- Permite a criação de múltiplos containers em diferentes máquinas(nodes);
- Escalando projetos, formando um cluster;
- Gerencia serviços, garantindo que as aplicações sejam executadas sempre da mesma forma;
- Criada pelo Google;
- Control Plane: Máquina onde é gerenciado o controle dos processos dos Nodes;
- Nodes: Máquinas que são gerenciadas pelo Control Plane;
- Deployment: A execução de uma imagem/projeto em um Pod;
- Pod: Um ou mais containers que estão em um Node
- Services: Serviços que expões os Pods ao mundo externo;
- kubectl: Cliente de linha de comando do Kubernetes;
- O Kubernetes pode ser executado de uma maneira simples em nossa máquina;
- Vamos precisar do client, kubectl, que é a maneira de executar o Kubernetes;
- E também o Minikube, uma espécie de simulador de Kubernetes, para não precisarmos de vávio computadores/servidores;
- No Linux vamos instalar primeiramente o client do Kubernetes, seguindo a documentação
- E depois, também seguiremos a documentação do Minikube;
- Um dos requisitos do Minikube é ter um gerenciador de VM/containers como: Docker, Virtual Box e Hiper-V;
Update the apt package index and install packages needed to use the Kubernetes apt repository:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
Download the Google Cloud public signing key:
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
Add the Kubernetes apt repository:
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Update apt package index with the new repository and install kubectl:
sudo apt-get update
sudo apt-get install -y kubectl
To verify kubectl installation:
kubectl verion
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb
To verify Minikube installation:
minikube version
- Para inicializar o Minikube vamos utilizar o comando:
minikube start --driver=[DRIVER]
- Onde o driver vai depender de como foi sua instalação das dependências
- As alternativas de drivers são: virtualbox, hyperv e docker
- Podemos testar o Minikube com:
minikube status
- Antes de darmos o start no Minikube utilizando o driver Docker, devemos rodar os seguinte comando no terminal para adicionar o seu usuário ao grupo do Docker e dar autorização de leitura para os arquivos do Docker:
sudo usermod -aG docker $USER && newgrp docker sudo chmod 777 ~/.docker sudo chmod 66 ~/.docker/config.json minikube delete --profile=minikube minikube start --profile=minikube --driver=docker
- Sempre que o computador for reiniciado, devemos iniciar o Minikube;
- Podemos pará-lo com o comando:
minikube stop
- O Minikube nos disponibiliza uma dashboard;
- Nela podemos ver todo o detalhamento de nosso projeto: serviços, pods e etc;
- Acessamos o dashboard com o comando:
minikube dashboard
- Ou para apenas obter a URL:
minikube dashboard --url
- O Deployment é uma parte fundamental do Kubernetes;
- O Deployment é análogo ao
docker run
; - Com ele criamos nosso serviço que vai rodar nos Pods, fazendo a inicialização do manager;
- Definimos uma imagem e um nome, para posteriormente ser aplicado entre os servidores;
- A partir do deployment teremos containers rodando;
- Vamos precisar de uma imagem no Hub do Docker, para gerar um Deployment
- Primeiramente vamos criar um pequeno projeto, novamente em Flask;
- Buildar a imagem do mesmo;
- Enviar a imagem para o Docker Hub;
- E testar rodando ele em um container;
- Este projeto será utilizado no Kubernetes!
-
Criamos um diretório para o projeto chamado
projeto_flask
-
Nele adicionamos o arquivo
app.py
, contendo:import flask from flask import Flask, render_template app = flask.Flask(__name__) app.config["DEBUG"] = True @app.route('/') def index(): return render_template('index.html') if __name__ == "__main__" app.run(host="0.0.0.0", debug=True, port="5000")
-
Adicionaremos também, no diretório raiz, o diretório
templates
com o arquivoindex.html
, contendo:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE-edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Kubernetes</title> </head> <body> <h1>Hello Kubernetes!!!</h1> </body> </html>
-
Na raiz do projeto adicionaremos o arquivo
Dockerfile
, contendo:FROM python:3 RUN apt-get update -y && atp-get install -y python-pip python-dev WORKDIR /app RUN pip install Flask COPY . . EXPOSE 5000 CMD ["python", "./app.py"]
-
No terminal, buildaremos a imagem passando uma
tag
com o nome de usuário do Docker Hub mais o nome que daremos ao projeto, exemplos:# docker build -t nome-usuario/nome-projeto caminho-para-o-projeto docker build -t ifasanelli/flask-kub-projeto .
-
Ainda no terminal executaremos o comando para rodar a imagem:
docker run -d -p 5000:5000 --name flask-kub --rm ifasanelli/flask-kub-projeto
-
Podemos verificar a execução da imagem rodando o comando:
> sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aef327e8389a ifasanelli/flask-kub-projeto "python ./app.py" 2 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp flask-kub 121561a100ef gcr.io/k8s-minikube/kicbase:v0.0.30 "/usr/local/bin/entr…" 23 hours ago Up 23 hours 127.0.0.1:49167->22/tcp, 127.0.0.1:49166->2376/tcp, 127.0.0.1:49165->5000/tcp, 127.0.0.1:49164->8443/tcp, 127.0.0.1:49163->32443/tcp minikube
-
Também podemos verificar o funcionamento da aplicação pelo navegador acessando localhost:5000
-
Com tudo funcionando corretamente, enviaremos a imagem ao Docker Hub através do comando:
docker push ifasanelli/flask-kub-projeto
- Após o mini setup do projeto, é hora de rodá-lo no Kubernetes;
- Para isso vamos precisar de um Deployment, que é onde rodamos os containers das aplicações nos Pods;
- O comando é:
kubectl create deployment <NOME> --image=<IMAGEM>
; - Desta maneira o projeto de Flask estará sendo orquestrado pelo Kubernetes
-
Criando o Deployment:
> kubectl create deployment flask-deployment --image=ifasanelli/flask-kub-projeto deployment.apps/flask-deployment created
-
Para verificarmos o Deployment, basta acessarmos o dashboard do Kuberneter utilizando o comando:
minikube dashboard
- Podemos checar se tudo foi criado corretamente, tanto o Deployment quanto a recepção do projeto pelo Pod;
- Para verificar o Deployment vamos utilizar o comando:
kubectl get deployments
- E para receber detalhes dos Deployments, o comando:
kubectl describe deployments
- Desta forma conseguimos saber se o projeto está rodando e também o que está rodando nele
- kubectl get deployments:
❯ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE flask-deployment 1/1 1 1 9m24s
- kubectl describe deployments:
❯ kubectl describe deployments Name: flask-deployment Namespace: default CreationTimestamp: Thu, 26 May 2022 00:33:32 -0300 Labels: app=flask-deployment Annotations: deployment.kubernetes.io/revision: 1 Selector: app=flask-deployment Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=flask-deployment Containers: flask-kub-projeto: Image: ifasanelli/flask-kub-projeto Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: flask-deployment-84d8c7c6bd (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set flask-deployment-84d8c7c6bd to 1
- Os Pods são componentes muito importantes também, pois são onde os containers são executados;
- Eles são criados no momento que criamos o Deployment;
- Para verificar os Pods, utilizamos o comando:
kubectl get pods
- E para saber mais detalhes sobre eles, utilizamos o comando:
kubectl describe pods
- Recebemos o status dos Pods que estão ligados e também informações importantes sobre eles
- kubectl get pods:
❯ kubectl get pods NAME READY STATUS RESTARTS AGE flask-deployment-84d8c7c6bd-2x225 1/1 Running 0 15m
- kubectl describe pods:
❯ kubectl describe pods Name: flask-deployment-84d8c7c6bd-2x225 Namespace: default Priority: 0 Node: minikube/192.168.49.2 Start Time: Thu, 26 May 2022 00:33:32 -0300 Labels: app=flask-deployment pod-template-hash=84d8c7c6bd Annotations: <none> Status: Running IP: 172.17.0.5 IPs: IP: 172.17.0.5 Controlled By: ReplicaSet/flask-deployment-84d8c7c6bd Containers: flask-kub-projeto: Container ID: docker://f53f1167ada11613084949a4e50d16cc0ead8567d3d11f99b52d2bcfdecfbee7 Image: ifasanelli/flask-kub-projeto Image ID: docker-pullable://ifasanelli/flask-kub-projeto@sha256:9fe26a73d5147bebf22114e162e5bc672ca5b14d2d83f473e45bb6042e509ea9 Port: <none> Host Port: <none> State: Running Started: Thu, 26 May 2022 00:34:06 -0300 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5p8zx (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-5p8zx: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 15m default-scheduler Successfully assigned default/flask-deployment-84d8c7c6bd-2x225 to minikube Normal Pulling 15m kubelet Pulling image "ifasanelli/flask-kub-projeto" Normal Pulled 15m kubelet Successfully pulled image "ifasanelli/flask-kub-projeto" in 33.12796523s Normal Created 15m kubelet Created container flask-kub-projeto Normal Started 15m kubelet Started container flask-kub-projeto
- Podemos também verificar como o Kubernetes está configurado;
- Utilizando o comando:
kubectl config view
- No nosso caso, receberemos informações importantes baseadas no Minikube, que é onde o Kubernetes está sendo executado
❯ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority: /home/italomiranda/.minikube/ca.crt extensions: - extension: last-update: Wed, 25 May 2022 01:26:01 -03 provider: minikube.sigs.k8s.io version: v1.25.2 name: cluster_info server: https://192.168.49.2:8443 name: minikube contexts: - context: cluster: minikube extensions: - extension: last-update: Wed, 25 May 2022 01:26:01 -03 provider: minikube.sigs.k8s.io version: v1.25.2 name: context_info namespace: default user: minikube name: minikube current-context: minikube kind: Config preferences: {} users: - name: minikube user: client-certificate: /home/italomiranda/.minikube/profiles/minikube/client.crt client-key: /home/italomiranda/.minikube/profiles/minikube/client.key
- As aplicações do Kubernetes não tem conexão com o mundo externo;
- Por isso precisamos criar um Service, que é o que possibilita expor os Pods;
- Isso acontece pois os Pods são criados para serem destribuídos e perderem tudo, ou seja, os dados gerados neles também são apagados;
- Então o Service é uma entidade separada dos Pods, que expões eles a uma rede
-
Para criar um serviço e expor nossos Pods devemos utilizar o comando:
kubectl expose deployment <NOME> --type=<TIPO> --port=<PORTA>
-
Colocaremos o nome do Deployment já criado;
-
O tipo de Service, há vários para utilizarmos, porém o LoadBalancer é o mais comum, onde todos os Pods são expostos;
-
E uma porta para o serviço ser consumido
❯ kubectl expose deployment flask-deployment --type=LoadBalancer --port=5000 service/flask-deployment exposed
- Podemos acessar o nosso serviço com o comando:
minikube service <NOME> --url
- Desta forma o IP aparece no nosso terminal;
- Pronto! Temos um projeto rodando em Kubernetes!
- Podemos também obter detalhes dos Services já criados;
- O comando para verificar todos é:
kubectl get services
; - E podemos obter informações de um serviço em específico com:
kubectl describe services/<NOME>
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flask-deployment LoadBalancer 10.107.160.75 <pending> 5000:31623/TCP 22d
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
❯ kubectl describe services/flask-deployment
Name: flask-deployment
Namespace: default
Labels: app=flask-deployment
Annotations: <none>
Selector: app=flask-deployment
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.107.160.75
IPs: 10.107.160.75
Port: <unset> 5000/TCP
TargetPort: 5000/TCP
NodePort: <unset> 31623/TCP
Endpoints: 172.17.0.5:5000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
- Vamos aprender agora como utilizar outros Pods, replicando assim nossa aplicação;
- O comando é:
kubectl scale deployment/<NOME> --replicas=<NUMERO>
- Podemos verificar no dashboar o aumento de Pods;
- E, também, com o comando:
kubectl get pods
❯ kubectl scale deployment/flask-deployment --replicas=5
deployment.apps/flask-deployment scaled
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-deployment-84d8c7c6bd-2kz6g 0/1 ContainerCreating 0 29s
flask-deployment-84d8c7c6bd-5bvsh 1/1 Running 1 (22d ago) 23d
flask-deployment-84d8c7c6bd-8bcld 0/1 ContainerCreating 0 29s
flask-deployment-84d8c7c6bd-kqx7w 0/1 ContainerCreating 0 29s
flask-deployment-84d8c7c6bd-q87q7 0/1 ContainerCreating 0 29s
- Além do
get pods
e da dashboard, temos mais um comando para checar réplicas; - Que é o:
kubectl get rs
- Desta maneira temos os status das réplicas dos projetos
❯ kubectl get rs
NAME DESIRED CURRENT READY AGE
flask-deployment-84d8c7c6bd 5 5 5 23d
- Podemos facilmente reduzir o número de Pods;
- Esta técnica é chamada de scale down;
- O comando é o mesmo, porém colocamos menos réplicas e o Kubernetes fará o resto;
- Comando:
kubectl scale deployment/<NOME> --replicas=<NUMERO_MENOR>
❯ kubectl scale deployment/flask-deployment --replicas=1
deployment.apps/flask-deployment scaled
❯ kubectl get rs
NAME DESIRED CURRENT READY AGE
flask-deployment-84d8c7c6bd 1 1 1 23d
- Para atualizar a imagem vamos precisar do nome do container, isso é dado na Dashboard dentro do Pod;
- E, também, a nova imagem deve ter versão diferente da atual, precisamos subir uma nova tah no Hub
- Depois utilizamos o comando:
kubectl set image deployment/<NOME> <NOME_CONTAINER>=<NOVA_IMAGEM>
# Após alteração de um ou mais arquivos do projeto
# Builda
❯ docker build -t ifasanelli/flask-kub-projeto:2 .
Sending build context to Docker daemon 102.4kB
Step 1/7 : FROM python:3
---> fec187bc258d
Step 2/7 : RUN apt-get update -y && apt-get install -y python3-pip python-dev
---> Using cache
---> e8f4dcac8481
Step 3/7 : WORKDIR /app
---> Using cache
---> bd19c2eaa2f6
Step 4/7 : RUN pip install Flask
---> Using cache
---> 77d7cdb3c0ce
Step 5/7 : COPY . .
---> 08b7330fbc22
Step 6/7 : EXPOSE 5000
---> Running in 83b6d6f21a86
Removing intermediate container 83b6d6f21a86
---> ba5a9affcbad
Step 7/7 : CMD ["python", "./app.py"]
---> Running in 345b23b2c627
Removing intermediate container 345b23b2c627
---> 9692ea581682
Successfully built 9692ea581682
Successfully tagged ifasanelli/flask-kub-projeto:2
# Envia para o Hub
❯ docker push ifasanelli/flask-kub-projeto:2
The push refers to repository [docker.io/ifasanelli/flask-kub-projeto]
8ad7098370ee: Pushed
18a55c03bd22: Layer already exists
cc26c29ead93: Layer already exists
64c4c1e6326e: Layer already exists
6da0431269fd: Layer already exists
d35a703f2b0a: Layer already exists
db7f8cc44a42: Layer already exists
b889a93a79dd: Layer already exists
9d4550089a93: Layer already exists
a7934564e6b9: Layer already exists
1b7cceb6a07c: Layer already exists
b274e8788e0c: Layer already exists
78658088978a: Layer already exists
2: digest: sha256:93e6c03d47abe1b369fc2d679a52c780fc3f8a5e621dbb2df05422199cb83dbc size: 3057
# Descobrimos o nome do container pelo dashboard, em:
# Dashboard -> Pods -> Acessa o Pod -> Container
❯ kubectl set image deployment/flask-deployment flask-kub-projeto=ifasanelli/flask-kub-projeto:2
deployment.apps/flask-deployment image updated
- Para desfazer uma alteração utilizamos uma ação conhecida como rollback;
- O comando para verificar uma alteração é:
kubectl rollout status deployment/<NOME>
; - Com ele e com o
kubectl get pods
, podemos identificar problemas; - Para voltar a alteração utilizamos:
kubectl rollout undo deployment/<NOME>
# Simularemos um erro atualizando a imagem do projeto para uma imagem inexistente
❯ kubectl set image deployment/flask-deployment flask-kub-projeto=ifasanelli/flask-kub-projeto:3
deployment.apps/flask-deployment image updated
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-deployment-bdd884779-kbchg 0/1 ImagePullBackOff 0 78s
# Agora rodaremos o rollback
kubectl rollout undo deployment/flask-deployment
❯ kubectl rollout undo deployment/flask-deployment
deployment.apps/flask-deployment rolled back
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-deployment-6b7b6dfb6d-psfv8 1/1 Running 0 13m
- Para deletar um serviço do Kubernetes vamos utilizar o comando:
kubectl delete service <NOME>
- Desta maneira nossos Pods *não teraõ mais a conexão externa;
- Ou seja, não poderão mais ser acessados
❯ kubectl delete service flask-deployment
service "flask-deployment" deleted
- Para deletar um Deployment do Kubernetes vamos utilizar o comando:
kubectl delete deploymento <NOME>
- Desta maneira o container não estará mais rodando, pois paramos os Pods;
- Assim, precisaremos criar um deployment novamente com a mesma ou outra imagem, para acessar o projeto
❯ kubectl delete deployment flask-deployment
deployment.apps "flask-deployment" deleted
❯ kubectl get deployments
No resources found in default namespace.
❯ kubectl get pods
No resources found in default namespace.
- Até agora utilizamos o modo imperativo, que é quando iniciamos a aplicação com comandos;
- O modo declarativo é guiado por um arquivo, semelhante ao Docker Compose
- Desta maneira tornamos nossas configurações mais simples e centralizamos tudo em um comando
- Também escrevemos em YAML o arquivo de Kubernetes
- apiVersion: versão utilizada da ferramenta;
- kind: tipo do arquivo (Deployment, Service);
- metadata: descrever algum objeto, inserindo chaves como
name
; - replicas: número de réplicas de Nodes/Pods;
- containers: definir as especificações de containers como: nome e imagem.
- Agora vamos transformar nosso projeto em declarativo;
- Para isso vamos criar um arquivo para realizar o Deployment;
- Desta maneira vamos aprender a criar os arquivos declarativos e utilizar as chaves e valores;
Na raiz do projeto criaremos o arquivo flask.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app-deployment
spec:
replicas: 4
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask
image: ifasanelli/flask-kub-projeto:2
- O comando para execução do arquido de Deploymento é:
kubectl apply -f <ARQUIVO>
- Desta maneira o Deployment será criado conforme configurado no arquivo
.yaml
❯ kubectl apply -f flask.yaml
deployment.apps/flask-app-deployment created
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-app-deployment-7dbc67c8d5-2c4cr 1/1 Running 0 33s
flask-app-deployment-7dbc67c8d5-6jv8k 1/1 Running 0 33s
flask-app-deployment-7dbc67c8d5-ctccf 1/1 Running 0 33s
flask-app-deployment-7dbc67c8d5-kfvmk 1/1 Running 0 33s
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
- Para parar de executar um Deployment baseado em arquivo, o declarativo, utilizamos também o
delete
; - O comando é:
kubectl delete -f <ARQUIVO>
- Desta maneira teremos os Pods sendo excluídos e o serviço finalizado.
❯ kubectl delete -f flask.yaml
deployment.apps "flask-app-deployment" deleted
❯ kubectl get pods
No resources found in default namespace.
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
- Agora vamos criar o serviço em declarativo;
- Para isso vamos criar um arquivo para realizao o Service (kind);
- O arquivo será semelhante ao de Deployment, porém tem uma responsabilidade diferente
Na raiz do projeto criaremos o arquivo flask-service.yaml
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
selector:
app: flask-app
ports:
- protocol: 'TCP'
port: 5000
targetPort: 5000
type: LoadBalancer
- Vamos executar da mesma maneira que o Deployment:
kubectl apply -f <ARQUIVO>
- E o serviço estará disponível;
- Obs.: é necessário gerar o IP de acesso com o comando:
minikube service <NOME>
❯ kubectl apply -f flask-service.yaml
service/flask-service created
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flask-service LoadBalancer 10.107.101.4 <pending> 5000:30991/TCP 17s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
❯ minikube service flask-service --url
http://192.168.49.2:30991
- Para parar de executar um Service baseado em arquivo, o declarativo, utilizamos também o
delete
; - O comando é:
kubectl delete -f <ARQUIVO>
- Desta maneira o serviço não estará mais disponível, então perderemos o acesso ao projeto.
❯ kubectl delete -f flask-service.yaml
service "flask-service" deleted
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
- Primeiramente vamos criar uma nova versão da imagem;
- E fazer o push para o Hub;
- Depois é só alterar no arquivo de Deployment a tag;
- E reaplicar o comando apply.
# Alteramos um ou mais arquivos do projeto, então buildamos a imagem novamente
❯ docker build -t ifasanelli/flask-kub-projeto:3 .
Sending build context to Docker daemon 6.656kB
Step 1/7 : FROM python:3
---> fec187bc258d
Step 2/7 : RUN apt-get update -y && apt-get install -y python3-pip python-dev
---> Using cache
---> e8f4dcac8481
Step 3/7 : WORKDIR /app
---> Using cache
---> bd19c2eaa2f6
Step 4/7 : RUN pip install Flask
---> Using cache
---> 77d7cdb3c0ce
Step 5/7 : COPY . .
---> c0a73684f1e3
Step 6/7 : EXPOSE 5000
---> Running in 251318d77fe4
Removing intermediate container 251318d77fe4
---> 1e4be38eeb9a
Step 7/7 : CMD ["python", "./app.py"]
---> Running in 7492bedcebc9
Removing intermediate container 7492bedcebc9
---> 1e19690bfb94
Successfully built 1e19690bfb94
Successfully tagged ifasanelli/flask-kub-projeto:3
# Subimos a imagem para o Hub
❯ docker push ifasanelli/flask-kub-projeto:3
The push refers to repository [docker.io/ifasanelli/flask-kub-projeto]
2674640a73fb: Pushed
18a55c03bd22: Layer already exists
cc26c29ead93: Layer already exists
64c4c1e6326e: Layer already exists
6da0431269fd: Layer already exists
d35a703f2b0a: Layer already exists
db7f8cc44a42: Layer already exists
b889a93a79dd: Layer already exists
9d4550089a93: Layer already exists
a7934564e6b9: Layer already exists
1b7cceb6a07c: Layer already exists
b274e8788e0c: Layer already exists
78658088978a: Layer already exists
3: digest: sha256:f251c58d1c9a8d88f8d1eb969ba7a7caa0533d083f4941bfe651ee9a8ad22606 size: 3056
# Então alteramos o nome da imagem no arquivo de deployment "flask.yaml"
image: ifasanelli/flask-kub-projeto:3
# Agora é só dar o apply novamente
❯ kubectl apply -f flask.yaml
deployment.apps/flask-app-deployment configured
- Vamos precisar unir o deployment e o service em um arquivo;
- A separação de objetos para o YAML é com:
---
- desta forma cada um deles será executado;
- Uma boa prática é colocar o service antes do deployment!
Removeremos os arquivos flask.yaml
e flask-service.yaml
e criaremos o arquivo flask-project.yaml
:
---
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
selector:
app: flask-app
ports:
- protocol: 'TCP'
port: 5000
targetPort: 5000
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app-deployment
spec:
replicas: 4
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask
image: ifasanelli/flask-kub-projeto:3
Então executamos o comando apply
:
❯ kubectl apply -f flask-project.yaml
service/flask-service created
deployment.apps/flask-app-deployment created
❯ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flask-service LoadBalancer 10.97.25.54 <pending> 5000:32356/TCP 32s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24d
❯ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
flask-app-deployment-6d64f7764b-22n4c 1/1 Running 0 36s
flask-app-deployment-6d64f7764b-67ktf 1/1 Running 0 36s
flask-app-deployment-6d64f7764b-dvlv6 1/1 Running 0 36s
flask-app-deployment-6d64f7764b-qkmzt 1/1 Running 0 36s
❯ minikube service flask-service --url
http://192.168.49.2:32356