NOVIDADE!
Este é o primeiro artigo de um novo tipo de conteúdo que estou chamando de drop. Drops são pequenos textos (com até 5 minutos de leitura) que mostram aspectos interessantes de algum assunto. No geral, serão pequenos tutoriais ou dicas interessantes.
O objetivo destes drops são para que eu possa criar conteúdo mais frequentemente, ao invés de criar semanalmente um conteúdo longo, que estava ficando bastante pesado para mim, como único escritor/editor do blog.
Espero que gostem :)
Um dos pontos que quase todo dev concorda é que o Kubernetes é bastante complicado. Principalmente para quem está aprendendo e quem está entrando agora no mundo de aplicações distribuídas e containers.
Apesar de existirem excelentes livros sobre o assunto, o conteúdo ainda é complexo e exige que as pessoas pensem um pouco fora do que estamos acostumados a ver em um ambiente de deploy tradicional. Em parte, isto vem porque precisamos configurar muitas extensões e o Kubernetes é absurdamente extensível, e assim pensamos que o Kubernetes é um único grande sistema, mas na verdade ele é composto de diversas pequenas APIs que manipulam arquivos.
A grande ideia
A grande ideia por trás do Kubernetes é que tudo é um pequeno arquivo, assim como o unix já nos mostrou antes, essa é uma excelente ideia para quando trabalhamos com configurações extensíveis.
Simplificando MUITO o fluxo. Quando criamos um Deployment, um Pod, um Service, o que estamos fazendo é, na verdade, adicionando um item em um banco de dados (etcd) que, por sua vez, é monitorado por uma série de control loops que chamamos de controllers. E são estes controllers que, de fato, fazem o trabalho de sincronizar os estados desejados e existentes deste cluster.
O mais legal de tudo isso é que o Kubernetes possui uma API muito boa para podermos obter estes recursos.
Entendendo a API
Toda a API do Kubernetes segue à risca a ideia do ReST. Então sempre vamos ter um recurso que começa desta forma:
http://<dns do control plane>/api/<versão>/namespaces/<namespace>/<recurso>/[nome][?opções]
Primeiramente precisamos obter o endereço do nosso control plane. Isso é super simples, podemos somente executar o comando kubectl cluster-info --context <nome do context>
.
O contexto pode ser omitido se você quiser a informação do cluster que está no contexto atual.
Isso vai nos dar uma saída como esta:
Kubernetes control plane is running at https://algundns.subdominio.tld:443
CoreDNS is running at https://algundns.subdominio.tld:443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://algundns.subdominio.tld:443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
Lembrando que esta saída pode variar dependendo de onde você está hospedando seu cluster.
Segurança
A API do Kubernetes é um servidor ReST simples, porém as características de segurança utilizadas para poder manter seu cluster seguro, já que esta API tem total controle dentro do control plane, são bem elaboradas.
O uso de certificados digitais atrelados a objetos de usuário e RBAC do sistema (ou até mesmo usando técnicas mais avançadas como AD) são empregadas para proteger a informação.
Como estamos fazendo apenas uma demonstração, podemos utilizar o próprio kubectl
para gerenciar este acesso para nós, já que ele tem todos os dados de acesso de todos os clusters. Basta executarmos kubectl proxy &
para rodar um processo em segundo plano que vai fazer um port forwarding da API do kubernetes para uma porta local, assim poderemos acessar os dados da api sem precisar nos preocupar com configurações de permissão.
$ kubectl proxy &
[1] 5705
Starting to serve on 127.0.0.1:8001
Manipulando a API
Agora que temos o cluster rodando localmente, você pode usar o gerenciador de requests de sua preferência, como o cURL, wget, postman. Eu estou usando o insomnia.
Vamos obter a lista de pods do meu cluster usando a api com a request GET http://localhost:8001/api/v1/namespaces/default/pods
:
Alguns recursos, como os deployments, não estão no que chamamos de "core API" do Kubernetes. A core API é quando não precisamos especificar nada no campo apiVersion
do recurso, como nos Pods, que é apiVersion: v1
, isso significa que podemos acessar com /api/v1
.
Os deployments fazem parte de apps/v1
, para isso temos um novo recurso base chamado apis
, então podemos obter a lista de deployments com http://localhost:8001/apis/apps/v1/namespaces/default/deployments
:
O mesmo vale para os ingresses que estão em networking.k8s.io/v1beta1
(ou em v1
dependendo da versão do seu cluster). Desta forma o endereço é http://localhost:8001/apis/networking.k8s.io/v1/namespaces/default/ingresses
Quando estamos tratando com o namespacedefault
, que é o padrão, podemos omitir completamente a parte/namespaces/default
, ficando somentehttp://localhost:8001/api/v1/pods
.
Quer saber mais?
Dê uma olhada na documentação da API do Kubernetes, ou também passe a flag -v6
para qualquer comando kubectl
para ver o caminho que ele está chamando (se você passar -v8
vai ver também o body de resposta):
$ kubectl get pods -v6
I0506 15:28:38.203647 6011 loader.go:379] Config loaded from file: /home/khaosdoctor/.kube/config
I0506 15:28:38.796623 6011 round_trippers.go:445] GET https://dominio.subdominio.tld:443/api/v1/namespaces/default/pods?limit=500 200 OK in 580 milliseconds
E aqui está uma lista de livros sensacionais sobre Kubernetes que você pode utilizar para aprender mais!