Skip to content

Instantly share code, notes, and snippets.

@ifasanelli
Last active November 22, 2022 22:25
Show Gist options
  • Save ifasanelli/768ce3911463cafd83c08d50f12bc627 to your computer and use it in GitHub Desktop.
Save ifasanelli/768ce3911463cafd83c08d50f12bc627 to your computer and use it in GitHub Desktop.

0. Índice

1. Kubernetes

1.1 O que é orquestração de containers?

  • 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;

1.2 O que é Kubernetes?

  • 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;

1.3 Conceitos fundamentais

  • 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;

1.4 Dependências necessárias

  • 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;

1.5 Instalando Kubernetes e dependências no Linux

  • 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;

1.5.1 Instalando kubectl segundo a documentação:

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

1.5.2 Instalando Minikube segundo a documentação:

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

1.6 Inicializando Minikube:

  • 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

1.7 Parando o Minikube

  • Sempre que o computador for reiniciado, devemos iniciar o Minikube;
  • Podemos pará-lo com o comando: minikube stop

1.8 Acessando a dashboard do Kubernetes

  • 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

1.9 Deployment teoria

  • 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

1.10 Criando o projeto

  • 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!
  1. Criamos um diretório para o projeto chamado projeto_flask

  2. 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")
  3. Adicionaremos também, no diretório raiz, o diretório templates com o arquivo index.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>
  4. 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"]
  5. 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 .
  6. Ainda no terminal executaremos o comando para rodar a imagem:

    docker run -d -p 5000:5000 --name flask-kub --rm ifasanelli/flask-kub-projeto
  7. 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
  8. Também podemos verificar o funcionamento da aplicação pelo navegador acessando localhost:5000

  9. Com tudo funcionando corretamente, enviaremos a imagem ao Docker Hub através do comando: docker push ifasanelli/flask-kub-projeto

1.11 Criando o Deployment

  • 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
  1. Criando o Deployment:

    > kubectl create deployment flask-deployment --image=ifasanelli/flask-kub-projeto
    deployment.apps/flask-deployment created
  2. Para verificarmos o Deployment, basta acessarmos o dashboard do Kuberneter utilizando o comando: minikube dashboard

1.12 Verificando Deployments

  • 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
  1. kubectl get deployments:
    ❯ kubectl get deployments
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    flask-deployment   1/1     1            1           9m24s
  2. 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

1.13 Verificando Pods

  • 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
  1. kubectl get pods:
    ❯ kubectl get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    flask-deployment-84d8c7c6bd-2x225   1/1     Running   0          15m
  2. 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

1.14 Configurações do Kubernetes

  • 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

1.15 Services na teoria

  • 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

1.16 Criando um Service

  • 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

1.17 Gerando um IP para o Services

  • 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!

1.18 Verificando os nossos Services

  • 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>

1.19 Replicando nossa aplicação

  • 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

1.20 Checar número de réplicas

  • 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

1.21 Diminuindo número de réplicas

  • 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

1.22 Atualizando a imagem do projeto

  • 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

1.23 Desfazendo alteração do projeto

  • 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

1.24 Deletando Service

  • 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

1.25 Deletando Deployment

  • 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.

1.26 Modo declarativo

  • 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

1.27 Chaves mais utilizadas do modo declarativo

  • 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.

1.28 Criando o Deployment do modo declarativo

  • 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

1.29 Executando o arquivo de Deployment

  • 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

1.30 Parando o Deployment

  • 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

1.31 Criando o Service do modo declarativo

  • 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

1.32 Iniciando o Service

  • 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

1.33 Parando o Service

  • 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

1.34 Atualizando o projeto no modo declarativo

  • 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

1.35 Unindo arquivos do projeto

  • 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment