Kubernetes ─ o inicio de uma jornada…
Começaremos nossa história entendendo dois conceitos fundamentais, que são:
Escalabilidade Vertical é quando adicionamos mais poder computacional a uma máquina, seja adquirindo uma nova, ou otimizando ela.
Escalabilidade Horizontal é quando adicionamos mais máquinas para lidar com muitos containers, VM’s, ou serviços, fazendo elas compartilharem entre si o seu poder computacional.
E para que entender esses dois tipos de escalabilidade ? Simples. O kubernetes também é uma ferramenta que auxilia na escalabilidade, mesclando os dois, pois nele podemos otimizar as VM’s criadas e aumentar o número delas.
Mas, o que é Kubernetes ?
É um gerenciador de uma ou múltiplas máquinas que trabalhem em conjunto, isto é, o que chamamos de cluster. Também chamado de orquestrador, assim como o docker swarm. Ele é capaz de decidir qual é a melhor máquina para cuidar de um determinado container, por meio do algoritmo de Raft, além de criar VM’s no cluster quando necessário, para aumentar a quantidade de containers usados.
Arquitetura do Kubernetes
Sua arquitetura é baseada em resources os quais veremos a seguir.
Suas máquinas são ordenadas e chamadas por:
- MASTER ─ quem coordena o cluster, mantendo o estado atualizado. Além de receber e executar novos comandos.
- NODE ─ executam os pods, isto é, as tarefas que encapsulam os containers e suas aplicações.
Detalhando ainda mais cada serviço veremos, primeiro os control plane e em segundo os nodes:
- API ─ recebe e executa os comandos.
- C-M ─ mantém atualizado o estado dos pods.
- Sched/scheduler ─ define onde um pod será executado no cluster.
- Etcd ─ armazena os dados vitais do cluster em um B.D. chave-valor.
_____________________________
- Kubelet ─ executa os pods dentro dos nodes.
- K-proxy ─ responsável pela comunicação entre os nodes de um cluster.
Destrinchando a API Rest
Ela é a mais importante no cluster devido a sua centralidade em se comunicar com todos do control plane e dos nodes. Sempre que nos comunicamos com um serviço, falamos diretamente com a API e ela faz a cominicação com os demais.
Para que o nosso computador consiga se comunicar com a API Rest ele usa uma ferramenta chamada kubectl, que provê as funcionalidades de criar, ler, atualizar e remover os dados do cluster, seja declarando arquivos ou executando comandos que criam requests para a API Rest.
─────────────PODS─────────────
Primeiro vamos entender a diferença entre a forma de trabalhar do docker e do kubernetes.
O docker trabalha com containers, enquanto o kubernetes trabalha com os pods.
Mas o que são pods ? Eles são capsulas que podem conter 1 ou mais containers.
Sendo assim, por meio do kubectl nós iremos declarar para a API criar um pod, e no pod haverá 1 ou mais containers.
Sobre a rede dentro de um Pod, cada Pod tem um endereço de IP único, que ao ser destruído e outro levantado em seu lugar, não voltará com o mesmo IP. Mas como vimos, cada Pod tem um ou mais containers, e cada container será localizado pela sua porta específica dentro do endereço de IP do seu Pod.
Vale ressaltar que um Pod só deixa de funcionar e existir, se, todos os containers dentro dele pararem de funcionar.
Além disso, ainda entendendo o funcionamento da rede nos Pod’s, os containers passam a terem os mesmos namespaces e por compartilharem o mesmo IP, eles também compartilham o mesmo localhost, tendo assim, comunicação direta um com o outro, além de possuir o mesmo armazenamento de volumes.
Forma Imperativa de trabalhar com Pods:
[CRIAÇÃO DE POD]:
- kubectl run <nome_do_pod> — image=ngix:latest ─> cria um pod com a imagem ngix, na versão latest.
[VERIFICAR PODS]:
- kubectl get pods ─ verifica seus pods
Possíveis flags para o comando acima:
“ — watch” poderá ver em tempo real as alterações nos pods.
“-o wide” mostra também o IP
[DESCRIÇÃO DO POD]:
- kubectl describe pod <nome_do_pod> ─ descrição detalhada do pod.
[EDITAR POD]:
- kubectl edit pod <nome_do_pod> ─ permite editar o arquivo, inclusive alterar coisas como a versão da imagem.
Forma Declarativa de trabalhar com Pods:
[APLICAÇÃO DE POD]:
- kubectl apply -f .<nome_do_arquivo> ─ o arquivo deve ser ou JSON ou YAML. Além de ser necessário estar dentro da pasta do arquivo.
Removendo Pod’s e Service’s
Há dois possíveis comandos para deletar um pod, seja ele declarativo ou não, que são:
- kubectl delete pod ngix-pod
- kubectl delete -f .<nome_do_arquivo> ─ o nome do arq deve ser em formato de caminho, exemplo ./primeiro-pod
- kubectl delete service <nome_service> ─ ao invés do nome você pode passar a flag “ — all” para apagar todos
[EXTRA]:
Assim como o Docker tem a possibilidade de entrar em um container e executar nele o terminal de forma interativa, igualmente podemos fazer em um Pod. Para isso, use o seguinte comando:
- kubectl exec -it portal-de-noticias — bash
Recurso Service | SVC
Permite a comunicação entre diversos serviços de vários Pods por meio de IP’s fixos que ele gera para cada serviço, além de prover um DNS para um ou mais Pods e fazer o balanceamento de cargas.
Na prática o Pod se comunica com um SVC que tem sempre seu IP fixo, e este por sua vez, passa a comunicação para o outro Pod, mesmo que o outro tenha mudado o IP por ter sido reconstruído. Tudo isso é feito quando passamos uma “label” no pod e um “selector” no service, como você verá em breve.
Antes de nos aprofundarmos nas funcionalidades do service/svc é importante saber o comando de visualização de svc. Suas duas formas são:
- kubectl get service
- kubectl get svc
_________________________________________________________________
O service tem três funcionalidades, que são:
- ClusterIP
Faz a comunicação entre diferentes Pods dentro de um cluster. Porém, um Pod só é comunicável, se nele houver um svc. Além disso, nenhuma máquina externa pode se comunicar com esses Pods, pois o clusterIP só serve para comunicação interna.
- NodePort
São serviços que permitem os Pods terem comunicação externa. Além disso, ele engloba as funcionalidades do ClusterIP, ou seja, ele permite fazer tanto a comunicação interna quanto externa. Como ele um Pod pode se comunicar com outros e uma máquina externa pode acessar os Pods.
Para acessar o Pod de forma externa, isto é, em um navegador, há formas específicas windows e no linux:
[WINDOWS]: use localhost e a porta do nodePort. Exemplo: localhost:30200
[LINUX]: use o INTERNAL-IP mais a nodePort. Exemplo: 192.168.90.100:30200
[AVISO]: PARA ENCONTRAR O INTERNAL-IP USE “kubectl get nodes -o wide”
- LoadBalancer
Ele é como um clusterIP que permite uma máquina externa se comunicar com os Pods, mas que faz a integração automática do Load Balance do Cloud Provider que estamos usando. Como ele será usado em um Cloud Provider, como GCP, Azure, AWS, etc, será preciso você usar um provedor na nuvem para usá-lo, mas os comandos e a lógica é a mesma que aprendemos até aqui. Você irá subir dois arquivos declarativos, no mínimo. Um do Pod e o outro do Service de LoadBalancer.
Config Map
É um arquivo responsável por armazenar a configuração de determinados Pods, evitando assim de deixar tudo em um mesmo escopo e criar uma bagunça. Além de que, cada Pod pode utilizar um ou mais config map’s, pois são reutilizáveis.
A seguir, veja alguns comandos relacionados ao configmap:
- kubectl get configmap ─> mostra todos os configmap’s criados.
- kubectl describe configmap <nome_do_configmap> ─ mostra o conteúdo do configmap.