Sumário
- O que é Kubernetes ?
- Provisionar Máquina Virtual com TerraForm
- Configurar Ambiente com Ansible
- Chave SSH
- Acessar VM
- Clonar Projeto
- Ferramentas Para Executar o k8s Localmente
- Chavear Clusters
- App Para Aplicar os Conceitos
- Objetos Kubernetes
- RollOut e Revision
- Services
- 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."
-
Confugaração da VM:
-
Provisionar:
terraform apply -auto-approve
- Visualizar o IP:
terraform output
- Destruir a VM:
terraform destroy -auto-approve
- Configurar o arquivo de inventário (inventory.ini):
[droplet01]
ipDaVM
- 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
- 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
- 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
- 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
- Executar:
#ativar o agent ssh
ssh-agent bash
ssh-add ~/.ssh/chaveSSH
#executar o mesmo
ssh root@ipDaMáquinaVirual
- Clonar projeto na máquina virtual:
git clone
- Configurar usuário git na máquina virtual:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- Criar um cluster básico:
kind create cluster
- Ativar o cluster:
kubectl cluster-info --context kind-kind
- O kind criar containers :
docker ps
- Para checar os nodes criados pelo Kind:
kubectl get nodes
- Consultar o clusters:
kind get clusters
- Deletar o cluster:
kind delete clusters kind
- 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
- Para aplicar esta configuração:
kind create cluster --config=k8s/001-create-cluster.yaml --name=cluster-laboratorio
- Ativar o cluster:
kubectl cluster-info --context kind-fullcycle
- Checar os nodes:
kubectl get nodes
- Consultar clusters:
kubectl config get-clusters
- Consultar Nodes:
kubectl get nodes
- Para chavear:
kubectl config use-context nomeDoCluster
- Controle dos pacotes:
go mod init github.com/fabiocaettano/servergo
- Criar Dockerfile:
FROM golang:1.19 as base
RUN apt update
WORKDIR /app
COPY . .
CMD ["tail","-f","/dev/null"]
- Manifesto Docker-Compose:
version: '3.3'
services:
goapp:
build:
dockerfile: Dockerfile
context: .
ports:
- 8080:8080
volumes:
- .:/app
- Subir Container:
docker-compose up -d --build
- Acessar Container:
docker-compose exec goapp bash
- Executar o dentro do container Build:
CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server
- Objetivo:
- Diminuir o tamanho da imagem de 1GB para 7MB;
- Enviar imagem para o Docker Hub.
- 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"]
- Desabilitar o volume no Docker-Compose.
Docker-Compose:
version: '3.3'
services:
goapp:
build:
dockerfile: Dockerfile
context: .
ports:
- 8080:8080
- Enviar imagem para o DockerHub
Autenticar no Docker Hub, será solicitado uma senha.
Gerar um token no site do Docker Hub:
docker login
- Criar a imagem:
docker build -t fabiocaettano74/servergo:v01 .
- Testar a imagem localmente:
docker run --rm -p 8000:8080 fabiocaettano74/servergo
- Subir a image para o DockerHub:
docker push fabiocaettano74/servergo:v01
- 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
- Criar um Pod:
kubectl apply -f k8s/002-create-pod.yaml
- Consultar:
kubectl get pods
kubectl get po
- 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>
- Deletar um Pod:
kubectl delete pod server
- O próximo objeto Replica Set resolve a questão de Criar e Recriar os Pods.
- Conceitos:
- Gerencia os Pods;
- Escalonamento dos Pods;
- Cria e Recria os Pods.
- Criar o Replicaset:
Executar:
kubectl apply -f k8s/003-create-replicaset.yaml
- 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
- Consultar Replicaset
Executar:
kubectl get replicaset
Resultado:
NAME DESIRED CURRENT READY AGE
server 2 2 2 3m19s
- 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
- 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
- Deletar o Replicaset
kubectl delete replicaset server
- Com relação atualização das imagens não é muito produtivo com o ReplicaSet. O próximo objeto *Deployment" resolve esa questão.
- 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
- 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.
- 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
- Consultar Deployment:
kubectl get deployment
Resultado:
NAME READY UP-TO-DATE AVAILABLE AGE
server 10/10 10 10 5m34s
- Visualizar o histório.
Executar:
kubectl rollout history deployment server
Resultado:
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
- 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
- Retornar versão anterior
Executar:
kubectl rollout undo deployment server
- Retornar para uma versão especifica:
kubectl rollout undo deployment server --to-revision=6
- 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.
- Aplicar o Service:
kubectl aplly -f 005-create.service.yaml
- Expor o service localmente:
kubectl port-forward service/server-service 8000:80
- 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)
- Range de Porta:
30.000 a 32.767
- Expor a porta localmente:
kubectl port-forward svc/server-service 8000:80
spec:
containers:
- name: server
image: fabiocaettano74/servergo:v09
env:
- name: NAME
value: "fabiocaettano"
- name: AGE
value: "49"
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