/devops-005-kubernetes

Kubernetes curso FullCycle

Primary LanguageGo

devops-005-kubernetes

Laboratório para aprendizado da tecnologia Kubernetes.

Sumário

Kubernetes

  1. Definição no site kubernetes.io:

"Kubernetes (K8s) é um produto Open Source utilizado para automatizar a implantação, o dimensionamento e o gerenciamento de aplicativos em contêiner."

Provisionar Máquina Virtual com TerraForm

  1. Confugaração da VM:

  2. Provisionar:

terraform apply -auto-approve
  1. Visualizar o IP:
terraform output
  1. Destruir a VM:
terraform destroy -auto-approve

Configurar Ambiente com Ansible

  1. Configurar o arquivo de inventário (inventory.ini):
[droplet01]
ipDaVM
  1. Instalar Kubectl:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar manifesto
ansible-playbook apply -i hosts/inventory.ini playbook/collections/kubectl.yaml
  1. Instalar Docker:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar manifesto
ansible-playbook apply -i hosts/inventory.ini playbook/collections/docker.yaml
  1. Instalar Kind:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar o manifesto
kubectl apply -i hosts/inventory.ini playbook/collections/kind.yaml

Chave SSH

  1. Enviar chave SSH da máquina local para a VM:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar o mesmo
scp /home/user/.ssh/nomeDaChave root@ipDaMaquinaVirtual:/root/.ssh/nomeDaChave
scp /home/user/.ssh/nomeDaChave.pub root@ipDaMaquinaVirtual:/root/.ssh/nomeDaChave.pub

Acessar VM

  1. Executar:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar o mesmo
ssh root@ipDaMáquinaVirual

Clonar Projeto

  1. Clonar projeto na máquina virtual:
git clone
  1. Configurar usuário git na máquina virtual:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"

Ferramentas Para Executar o k8s Localmente

Kind

Criar e Destruir Cluster

  1. Criar um cluster básico:
kind create cluster
  1. Ativar o cluster:
kubectl cluster-info --context kind-kind
  1. O kind criar containers :
docker ps
  1. Para checar os nodes criados pelo Kind:
kubectl get nodes
  1. Consultar o clusters:
kind get clusters
  1. Deletar o cluster:
kind delete clusters kind

Criar Nodes

  1. Criar um cluster com 1 control pane e 3 worker nodes utilizando um arquivo de manifesto.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
  1. Para aplicar esta configuração:
kind create cluster --config=k8s/001-create-cluster.yaml --name=cluster-laboratorio
  1. Ativar o cluster:
kubectl cluster-info --context kind-fullcycle
  1. Checar os nodes:
kubectl get nodes

K3d

Chavear Clusters

  1. Consultar clusters:
kubectl config get-clusters
  1. Consultar Nodes:
kubectl get nodes
  1. Para chavear:
kubectl config use-context nomeDoCluster

App Para Aplicar os Conceitos

Ambiente Desenvolvimento

  1. Controle dos pacotes:
go mod init github.com/fabiocaettano/servergo
  1. Criar Dockerfile:
FROM golang:1.19 as base
RUN apt update
WORKDIR /app
COPY . .
CMD ["tail","-f","/dev/null"]
  1. Manifesto Docker-Compose:
version: '3.3'
services: 
  goapp:
    build:
      dockerfile: Dockerfile      
      context: .
    ports:
      - 8080:8080
    volumes:
      - .:/app
  1. Subir Container:
docker-compose up -d --build
  1. Acessar Container:
docker-compose exec goapp bash
  1. Executar o dentro do container Build:
CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server

Multi-Stage

  1. Objetivo:
  • Diminuir o tamanho da imagem de 1GB para 7MB;
  • Enviar imagem para o Docker Hub.
  1. Criar DockerFile:
FROM golang:1.19 as base
RUN apt update
WORKDIR /app
RUN go mod init github.com/fabiocaettano/servergo
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server

FROM scratch as binary
WORKDIR /app
COPY --from=base /app/server .
EXPOSE 8080
CMD ["./server"]
  1. Desabilitar o volume no Docker-Compose.

Docker-Compose:

version: '3.3'
services: 
  goapp:
    build:
      dockerfile: Dockerfile      
      context: .
    ports:
      - 8080:8080
  1. Enviar imagem para o DockerHub

Autenticar no Docker Hub, será solicitado uma senha.

Gerar um token no site do Docker Hub:

docker login
  1. Criar a imagem:
docker build -t fabiocaettano74/servergo:v01 .
  1. Testar a imagem localmente:
docker run --rm -p 8000:8080 fabiocaettano74/servergo
  1. Subir a image para o DockerHub:
docker push fabiocaettano74/servergo:v01

Objetos Kubernetes

Pod

  1. Conceitos:
  • É o menor objeto do Kubernetes
  • Responsável por executar o Container
  • O Pod é efemero (nasce e morre)
  • Não é resiliente
  • O Pod sozinho não é muito útil
  1. Criar um Pod:
kubectl apply -f k8s/002-create-pod.yaml
  1. Consultar:
kubectl get pods
kubectl get po
  1. Liberar acesso ao Pod:
kubectl port-forward pod/server 8080:8080

Mas esse acesso é somente interno. Abrir outro terminal:

curl http://localhost:8080

Resultado Esperado:

<h1>Hello Kubernetes com Kind!!!</h1>
  1. Deletar um Pod:
kubectl delete pod server
  1. O próximo objeto Replica Set resolve a questão de Criar e Recriar os Pods.

ReplicaSet

  1. Conceitos:
  • Gerencia os Pods;
  • Escalonamento dos Pods;
  • Cria e Recria os Pods.
  1. Criar o Replicaset:

Executar:

kubectl apply -f k8s/003-create-replicaset.yaml
  1. Consultar Pods:

Executar:

kubectl get pods

Resultado:

NAME           READY   STATUS    RESTARTS   AGE
server-fsv6k   1/1     Running   0          8s
server-v6798   1/1     Running   0          8s
  1. Consultar Replicaset

Executar:

kubectl get replicaset

Resultado:

NAME     DESIRED   CURRENT   READY   AGE
server   2         2         2       3m19s
  1. Ao deletar um Pod, agora ele será recriado de forma automática por conta do ReplicaSet.

O papel do Replicaset é manter o número de pods desejados (DESIRED).

Deletar um pod:

kubectl delete pod server-fsv6k

Ao consultar o POD observar a coluna AGE:

NAME           READY   STATUS    RESTARTS   AGE
server-5kq7d   1/1     Running   0          11s
server-v6798   1/1     Running   0          7m27s
  1. O kubernetes disponibliza um comando para checar a descrição de um POD.

Visualizar a descrição do POD:

kubectl describe pod 5kq7d

Os pods server-5kq7d e server-v6798 tem como base a imagem fabiocaettano74@servergo:v03.

A imagem do manifesto será alterado para fabiocaettano74@servergo:v04.

E o número de réplicas alterado para 4.

Esta nova configuração será aplicará a nova imagem somente os novos Pods.

Excluir os Pods para o Replicaset atuar e subir 02 novos Pods atualizados.:

kubectl delete pod server-5kq7d server-v6798
  1. Deletar o Replicaset
kubectl delete replicaset server
  1. Com relação atualização das imagens não é muito produtivo com o ReplicaSet. O próximo objeto *Deployment" resolve esa questão.

Deployment

  1. Conceitos
  • O Deployment gerencia o Replicaset
  • Quando o manifesto for atualizado, os Pods serão destruibos, e recriados com a nova configuração.
  • Os Pods são destruidos de forma progressiva para não gerar um Downtime
  1. Alterações no manifesto 004-create-deployment.yaml:
  • Mudança na imagem para versão 05.
  • Alteração na quantidade de réplicas para 10.
  1. Aplicar manifesto:

Executar:

kbuectl apply -f k8es/004-create-deployment.yaml

Resultado:

NAME                     READY   STATUS    RESTARTS   AGE
server-b5984575f-556b7   1/1     Running   0          4m36s
server-b5984575f-5wrz5   1/1     Running   0          4m36s
server-b5984575f-fbwfj   1/1     Running   0          4m36s
server-b5984575f-fdt6b   1/1     Running   0          4m36s
server-b5984575f-kx24q   1/1     Running   0          4m36s
server-b5984575f-pqnhw   1/1     Running   0          4m36s
server-b5984575f-qbsns   1/1     Running   0          4m36s
server-b5984575f-rhnwh   1/1     Running   0          4m36s
server-b5984575f-wvhgn   1/1     Running   0          4m36s
server-b5984575f-zmpvc   1/1     Running   0          4m36s
  1. Consultar Deployment:
kubectl get deployment

Resultado:

NAME     READY   UP-TO-DATE   AVAILABLE   AGE
server   10/10   10           10          5m34s

Rollout e Revisões

  1. Visualizar o histório.

Executar:

kubectl rollout history deployment server

Resultado:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>
4         <none>
  1. A coluna CHANGE-CAUSE possibilita deixar uma anotação, facilitando identificar a versão:

Anotação será realizada na última REVISION, ou seja, na versão que está em execução.

Exemplo:

 kubectl annotate deployment/server kubernetes.io/change-cause="update image version v04 to v05"

Resultado:

REVISION  CHANGE-CAUSE
8         <none>
9         <none>
10        update image version v07 to v08
11        update image version v04 to v05
  1. Retornar versão anterior

Executar:

kubectl rollout undo deployment server
  1. Retornar para uma versão especifica:
kubectl rollout undo deployment server --to-revision=6

Services

  1. Conceitos:
  • Services é a porta de entrada da aplicação;
  • O Kuberntes faz o papel de Service Discovery;
  • Tipos de Services: Cluster IP, Node Port, Load Balancer e External Name;
  • O Service é vinculado com o Deployment, através do selectors.

Cluster IP

  1. Aplicar o Service:
kubectl aplly -f 005-create.service.yaml
  1. Expor o service localmente:
kubectl port-forward service/server-service 8000:80
  1. Sobre as Portas
  • Na url http://localhost:8000, a porta 8000 é da máquina local;

  • No comando kubectl port-forward informamos a porta 8000:80, onde 8000 é a porta local, e a porta 80 é do service do kubernetes;

kubectl port-forward pod/nomeDoPod 8000:80
  • No manifesto yaml a port 80 é vinculado o service. Já a porta 8080 é vinculado ao TargetPort é do container.
apiVersion: v1
kind: Service
metadata:
  name: server-service
spec:
  selector:
    app: server
  type: ClusterIP
  ports:
  - name: server-service
    port: 80
    targetPort: 8080
    protocol: TCP
  • O aplicativo executado pelo container fica escutando a porta 8080:
http.ListenAndServe(":8080", nil)

Node Port

  1. Range de Porta:

30.000 a 32.767

  1. Expor a porta localmente:
 kubectl port-forward svc/server-service 8000:80

Variável de Ambiente

    spec:
      containers:
        - name: server
          image: fabiocaettano74/servergo:v09
          env:
          - name: NAME
            value: "fabiocaettano"
          - name: AGE
            value: "49"

Config Map

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: server-envinronment
data:
  NAME: "michele"
  AGE: "42"

Configuração do ConfigMap no Deployment:

spec:
      containers:
        - name: server
          image: fabiocaettano74/servergo:v09          
          env:
          - name: NAME
            valueFrom:
              configMapKeyRef:
                name: server-envinronment
                key: NAME
          - name: AGE
            valueFrom:
              configMapKeyRef:
                name: server-envinronment
                key: AGE