Usando o Kubernets pela primeira vez

yanpiing

Yan.ts

Posted on June 17, 2022

Usando o Kubernets pela primeira vez

Já subi uma aplicação para a AWS umas 3 vezes mas todas foram um processo muito manual usando o EC2, hoje pela primeira vez usei o kubernets para automatizar esse processo.

Kubernets (K8s)

O kubernets é um orquestadror de containers que fica responsável por transformar esses containers em pods e subir esses containers de forma mais automatizada para uma cloud como AWS ou GCP ou outras opções, porem ele não faz só isso, ele também tem o load balancer onde ele tenta distribuir as cargas para não deixar um pod sobrecarregado e também toda a parte de service discovery além de levantar pods novos sempre que os antigos caírem

Como usar o K8s

Primeiro vamos criar um arquivo do tipo yml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 80

Enter fullscreen mode Exit fullscreen mode

Nesse arquivo inicial temos:
apiVersion: Versão da api do k8s, nesse caso é a v1
kind: qual o tipo do recurso a ser criado, nesse caso um pod
metadata: dados complementares

  • name: nome do pod
  • labels: label do pod então podemos depois filtrar por pods com a label ngnix por exemplo spec: especificação do serviço
  • containers: qual o container dentro daquele pod com seu nome a sua imagem e a sua porta > Existem casos de termos mais de um pod em um container porem como regra geral geralmente temos um pod por container

Com isso temos já um pod, para testar esse pod podemos usar o kind que serve para rodar o kubernets localmente, no próprio site do kind eles ensinam como instalar em diversos sistemas operacionais. Depois de instalado podemos rodar o comando
kind create cluster --name={algo}

Image description

e entao o kind vai sugerir rodarmos o comando kubectl cluster-info --context kind-{algo} mas para isso vamos precisar do kubectl depois de rodarmos o comando do kubectl conseguimos ver que o kubernets já está como ready

Image description

por padrão o kubernets tem o control-plane que gerencia tudo, e quem é gerenciado são as maquinas que ficam conectadas no control-plane. Para rodar um cluster kubernets é recomendado no minimo 3 maquinas

agora para conectar o pod precisamos rodar kubectl apply -f {nome_do_yml} e com o kubectl get pods ele vai retornar o pod rodando, e para conectar com o ngnix? temos que dar um port-forward com o comando kubectl port-forward pod/nginx 9090:80 onde 80 é a porta que declaramos no yml e o 9090 é a porta que disponibilizei no meu computador, então se eu for no meu localhost 9090 vou encontrar o nginx

Image description

ReplicaSet

Porem o kubernets ainda não está mantendo o pod online todo o tempo, se rodarmos o comando kubectl delete pod nginx o pod vai ficar fora do ar. Para garantir que os pods estejam sempre online precisamos adicionar o Replica set, que fica gerenciando os pods e vendo se algum pod saiu do ar para ele criar um novo.

O yml do replicaSet ficou assim:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

onde ele é do tipo ReplicaSet e ele monitora todos os pods que a label é 'nginx', ele tem também um template igual ao pod que definimos no yaml anterior, para que ele saiba como vai ser o pod que ele vai criar.

Image description

Podemos ver que agora sempre que eu excluo um pod o replicaSet logo em seguida sobe um novo no lugar, além disso é possivel ver que já está salva a configuração que eu desejo manter apenas uma replica daquele pod.

Deployments

Se eu quiser mudar a versão da imagem que estou utilizando o replicaSet não vai fazer essa mudança de forma automática, para isso vou precisar matar o pod para quando subir novamente ele subir com a versão nova, o replicaSet só verifica se o pod caiu e quantos pods eu quero.

Agora imagine essa situação onde eu tenho por exemplo 100 replicas, eu teria que matar os pods para atualizar a versão da imagem. E para isso temos os deployments, que são responsaveis por cuidar dos replicasets.

O Deployment sempre que quisermos mudar a versão da imagem ele vai criar um novo replicaSet, então por exemplo, temos 10 pods na versão 1.0, queremos atualizar para a versão 1.1, o deployment cria um novo replicaset com a versão 1.1 e pedindo 10 pods, enquanto no da versão 1.0 ele pede por 0 pods, e se a versão 1.1 estiver quebrada e precisarmos voltar ele pede por 10 pods na versão 1.0 e 0 pods na versão 1.1

O yml do deployment é igual ao do replicaSet, só muda que no kind ao inves de ReplicaSet vai ser Deployment, porem todo o processo é mesmo, basta dar um apply que vai funcionar

Image description

Da para ver como ele fica alternando entre os replicaSets conforme a configuração muda

Rodando o kubernets com o meu servidor

Para isso criei um servidor bem basico em GO, tudo que ele faz é escrever hello world quando acessamos a porta 9090

package main

import "net/http"

func main() {
    http.HandleFunc("/", hello)
    http.ListenAndServe(":9090", nil)
}

func hello(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World!"))
}

Enter fullscreen mode Exit fullscreen mode

alem disso vou criar um arquivo docker

FROM golang:1.18 as builder

WORKDIR /app
COPY main.go .
COPY go.mod .
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o server main.go

FROM scratch
COPY --from=builder /app/server .
CMD [ "./server" ]
Enter fullscreen mode Exit fullscreen mode

vou buildar esse arquivo docker build -t yansb/goserver:latest . e se e eu rodar o comando docker run --rm -p 9090:9090 yansb/goserver:latest já consigo acessar minha porta 9090 e ver o hello world, depois disso posso dar um push dessa imagem para o meu dockerhub, agora ja posso criar um novo yaml com o essa imagem e fazer esse novo deployment
Image description

Se eu der um port-forward e for na porta 9090 já consigo ver o meu hello world

Load balancer

Agora com diversas replicas dos pods (10 com o GO e 10 nginx) temos um problema, como K8s vai saber para qual pod mandar a pessoa que está acessando a aplicação

Vamos criar um yaml para o service:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
Enter fullscreen mode Exit fullscreen mode

Esse service vai pegar todos os pods com a label nginx e vai fazer o loadBalance baseado nessa seleção agora qualquer pessoa que internamente procurar pelo nginx-service ou pelo ip dele, vai chegar até um dos nginx.

Image description

O external ip está como pending pois meu computador não consegue gerar um IP externo, porem se estivesse rodando na aws, já poderíamos acessar esse ip externo e ter acesso ao ngnix

Tudo que fiz hoje com o kubernets está nesse repositório: https://github.com/Yansb/full-cycle-course/tree/master/kubernets

💖 💪 🙅 🚩
yanpiing
Yan.ts

Posted on June 17, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Usando o Kubernets pela primeira vez
todayilearned Usando o Kubernets pela primeira vez

June 17, 2022