Gerenciamento Kubernetes com Cluster API

CAPI permite provisionar e gerenciar K8s em multiplos provedores de infraestrutura.

Quanto mais eu estudo e faço novas descobertas, me encantado ainda mais com o poder da Infraestrutura como Código (IaC).

Minha paixão pela tecnologia cloud native me impulsiona na busca por desafios avançados, gerando uma inquietude constante por arquiteturas de baixo nível. Na minha biografia, “Quem é o Erivaldo”, compartilho o incentivo aos profissionais para explorarem além das simples cargas de trabalho, destacando a importância de conhecer mais profundamente o ecossistema tecnológico.

Cluster API

O Cluster API (CAPI) é um subprojeto do Kubernetes, dedicado a fornecer APIs declarativas e ferramentas que simplificam significativamente o provisionamento, atualização e operação de múltiplos clusters Kubernetes. Esta iniciativa, promovida pelo Special Interest Group (SIG) do ciclo de vida do cluster do Kubernetes, utiliza padrões e APIs no estilo Kubernetes para automatizar o gerenciamento do ciclo de vida do cluster, oferecendo uma abordagem mais eficiente para os operadores de plataforma.

No âmbito do Cluster API, aspectos fundamentais, como infraestrutura de suporte (máquinas virtuais, redes, balanceadores de carga, VPCs) e a configuração do cluster Kubernetes, são todos definidos de maneira análoga à operação de desenvolvedores de aplicativos. Essa abordagem garante uma consistência notável, permitindo implantações de clusters de forma repetível e uniforme em diversos ambientes de infraestrutura.

A verdadeira beleza do Cluster API reside na sua capacidade de alinhar a gestão do ciclo de vida do cluster com os princípios e práticas que os desenvolvedores já adotam para suas cargas de trabalho. Ao operar de forma integrada, o CAPI possibilita que os profissionais alcancem implantações de clusters eficientes e padronizadas em uma ampla gama de ambientes, promovendo a flexibilidade e a confiabilidade tão cruciais na administração de infraestruturas Kubernetes. Em suma, uma conquista notável para a comunidade Kubernetes e um avanço significativo na simplificação e automação da administração de clusters.

Por que usar Cluster API?

O Kubernetes é um sistema complexo que requer configuração adequada de vários componentes para garantir um cluster funcional. A comunidade reconheceu o desafio que isso representa para os usuários e, em resposta, desenvolveu mais de 100 distribuições e instaladores do Kubernetes. No entanto, a diversidade dessas opções tornou-se um obstáculo, levando o SIG Cluster Lifecycle a criar o kubeadm.

O kubeadm é uma ferramenta focalizada na inicialização de clusters Kubernetes seguindo práticas recomendadas. Seu objetivo principal é fornecer uma base para outros instaladores, reduzindo a carga de configuração que cada instalador individual precisa gerenciar. Ao longo do tempo, o kubeadm tornou-se a ferramenta subjacente para diversos aplicativos, como Kubespray, minikube e kind.

Apesar do kubeadm simplificar a instalação, ele não aborda questões de gerenciamento contínuo em ambientes de produção. Você ainda se depara com diversas dúvidas ao configurar um ambiente de produção, incluindo:

  • Como posso provisionar máquinas, balanceadores de carga, VPC etc. de forma consistente em vários provedores e locais de infraestrutura?
  • Como posso automatizar o gerenciamento do ciclo de vida do cluster, incluindo atualizações e exclusão de cluster?
  • Como posso escalar esses processos para gerenciar qualquer número de clusters?

Para preencher essas lacunas, o SIG Cluster Lifecycle lançou o projeto Cluster API. Essa iniciativa cria APIs declarativas no estilo Kubernetes para automatizar a criação, configuração e gerenciamento de clusters. Cluster API é extensível para suportar diferentes provedores de infraestrutura (AWS, GCP, Azure, vSphere, etc.) e métodos de inicialização, proporcionando uma solução mais abrangente.

Arquitetura do CAPI

A arquitetura do Cluster API pode ser visualizada através do seguinte diagrama, onde um cluster de gerenciamento é encarregado de alocar os componentes necessários para a orquestração.

Management Cluster e os componentes necessários que compõem o CAPI.

Management cluster

Um cluster Kubernetes encarregado de gerenciar o ciclo de vida dos clusters de carga de trabalho (workloads). O Cluster de Gerenciamento também serve como o ambiente em que um ou mais provedores são executados, armazenando recursos essenciais, como os objetos Machine.

Workload cluster:
Um cluster Kubernetes cujo ciclo de vida é supervisionado por um cluster de gerenciamento.

Infrastructure provider

Componente responsável pelo provisionamento de infraestrutura/recursos computacionais exigidos pelo Cluster ou pelas Machines (ex. VMs, networking, etc.). Por exemplo, os provedores de infraestrutura em nuvem incluem AWS, Azure e Google, e os provedores de infraestrutura bare metal incluem VMware, MAAS e metal3.io.

Há uma abordagem interessante quando há mais de uma forma de obter recursos do mesmo provedor de infraestrutura (como a AWS que oferece EC2 e EKS), cada forma é chamada de variante.

Bootstrap provider

Componente responsável por transformar uma instancia (virtual machine) em um nó Kubernetes:

  1. Gerando os certificados de cluster, se não for especificado de uma forma alternativa
  2. Inicializando a primeira control plane e bloqueando a criação de outros nós até que seja concluído
  3. Realizando o join entre a control plane e worker nodes ao cluster

Control plane

Uma control plane é um conjunto de componentes que atendem à API do Kubernetes e reconciliam continuamente o estado desejado usando control loop (controllers).

  • Self-provisioned: uma control plane do Kubernetes que consiste em pods ou máquinas totalmente gerenciados por uma única implantação de API de cluster. por exemplo, kubeadm usa pods estáticos para executar componentes como kube-apiserver , kube-controller-manager e kube-scheduler em máquinas de plano de controle.
  • Pod-based: As implantações baseadas em pod requerem um cluster de hospedagem externo. Os componentes do plano de controle são implantados usando objetos Deployment e StatefulSet padrão e a API é exposta usando um Service.
  • External ou Managed: Os control planes externos ou gerenciados são oferecidos e controlados por algum sistema diferente do Cluster API, como GKE, AKS, EKS, entre outros.

provider padrão usa kubeadm para inicializar a control plane. A partir da v1alpha3, ele expõe a configuração por meio do objeto KubeadmControlPlane. O controller capi-kubeadm-control-plane-controller-manager pode então criar objetos Machine e BootstrapConfig com base nas réplicas solicitadas no objeto KubeadmControlPlane.

Custom Resources Definition (CRDs)

Um CustomResourceDefinition é um recurso integrado que permite estender a API Kubernetes. Cada CRD representa uma customização de uma instalação do Kubernetes. Cluster API fornece e depende de vários CustomResourceDefinitions:

Machine:
Um objeto Machine é a especificação declarativa de um componente de infraestrutura que hospeda um nó Kubernetes (por exemplo, uma VM). Se um novo objeto Machine for criado, o controller específico do provedor provisionará e instalará um novo host para registrar-se como um novo Nó correspondente à especificação da Machine. Se a especificação for atualizada, o controller substituirá o host por um novo que corresponda à especificação atualizada. Se um objeto Machine for excluído, sua infraestrutura subjacente e o Nó correspondente serão excluídos pelo controller.

Campos comuns, como a versão do Kubernetes, são modelados nas especificações da Machine. Qualquer informação específica do provedor faz parte da InfrastructureRef e não é portátil entre diferentes provedores.

Machine Immutability (upgrade local vs replace):
Do ponto de vista do Cluster API, todas as Machines são imutáveis: uma vez criadas, nunca são atualizadas (exceto labelsannotations e status), apenas excluídas.

Por esse motivo, MachineDeployments são preferíveis, pois lidam com alterações nas máquinas substituindo-as, da mesma forma que as implantações principais lidam com alterações nas especificações do pod.

MachineDeployment
Um objeto MachineDeployment fornece atualizações declarativas para Machines e MachineSets.

Um MachineDeployment funciona de maneira semelhante ao Deployment de aplicações que já conhecemos no Kubernetes. Um MachineDeployment reconcilia alterações em uma spec de um objeto Machine implementando alterações em 2 MachineSets, o antigo e o recém-atualizado.

MachineSet
O objetivo de um MachineSet é manter um conjunto estável de Machines em execução a qualquer momento.

Um objeto MachineSet funciona de maneira semelhante a um ReplicaSet do Kubernetes . MachineSets não devem ser usados ​​diretamente, mas são o mecanismo que MachineDeployments usa para reconciliar o estado desejado.

MachineHealthCheck
Um objeto MachineHealthCheck define as condições em que um nó (objeto Node) deve ser considerado não íntegro.

Se o Node corresponder a essas condições não saudáveis ​​por um determinado período configurado, o MachineHealthCheck iniciará a correção do Node. A remediação é realizada excluindo a Machine correspondente.

MachineHealthChecks apenas corrigirá Nodes se eles pertencerem a um MachineSet. Isso garante que o cluster Kubernetes não perca capacidade, pois o MachineSet criará uma nova máquina para substituir a Machine com falha.

BootstrapData
O objeto BootstrapData contém os dados de inicialização específicos da função da Machine/Node (geralmente cloud-init) usados ​​pelo Provedor de Infraestrutura para inicializar uma nova Machine/Node.

Mera coincidência

Uma forma simples de compreender o Cluster API é a comparação dos principais objetos (MachineMachineSet e MachineDeployment) aos objetos de uma aplicação comum do Kubernetes (PodReplicaSet e Deployment).

Hands on

Melhor do que palavras é fazer acontecer, então vamos colocar as mãos na massa e construir um cluster de gerenciamento para rodar o CAPI usando um provedor AWS, para então construir nossos primeiro clusters de workload. Está animado? =)

Criando o Management cluster

Lembrando que mamagement cluster conforme já vimos acima é o upstream que vai orquestrar os workload clusters (downstreams).

Em um cenário produção é altamente recomendado as boas práticas de alta disponibilidade, então eu recomendo meu artigo Criando um cluster kubernetes em alta disponibilidade com ambiente on-premises como base para a construção de um cluster de gerenciamento altamente disponível. No entanto, como o nosso objetivo neste artigo é o CAPI eu vou focar na sua exposição e utilizar um simples cluster criado com KIND ou K3D. Sinta-se a vontade para criar um cluster da maneira que achar conveniente.

Requisitos

  1. Um cluster K8s básico (não há problemas se for um cluster single node)
  2. Uma conta AWS com credenciais IAM.

Com o cluster já criado, vamos definitivamente criar e configurar nosso cluster de gerenciamento.

Instalação do clusterctl

A ferramenta clusterctl é uma CLI (command line interface) que lida com o ciclo de vida de um cluster de gerenciamento do CAPI.

Neste cenário estou utilizando Linux em arquitetura AMD64.

Download do binário:

curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.6.1/clusterctl-linux-amd64 -o clusterctl

Fazendo a instalação:

sudo install -o root -g root -m 0755 clusterctl /usr/local/bin/clusterctl

Verificando a versão:

clusterctl version

Overview da configuração do provider

Quando executado pela primeira vez, clusterctl init requer alguns parametros e, se não forem especificados, serão utilizados como default “Cluster API” para CoreProvider e “kubeadm” para BootstrapProvider e de ControlPlaneProvider.

clusterctl init --help
  --bootstrap strings Bootstrap providers and versions (e.g. kubeadm:v1.1.5) to add to the management cluster. If unspecified, Kubeadm bootstrap provider's latest release is used.
  --control-plane strings Control plane providers and versions (e.g. kubeadm:v1.1.5) to add to the management cluster. If unspecified, the Kubeadm control plane provider's latest release is used.
  --core string Core provider version (e.g. cluster-api:v1.1.5) to add to the management cluster. If unspecified, Cluster API's latest release is used.
  --infrastructure strings Infrastructure providers and versions (e.g. aws:v0.5.0) to add to the management cluster.

Veja um exemplo de configuração:

Exemplo de configuração dos recursos do CAPI.

Você também pode atualizar estas configurações no futuro, alterando o recurso e versão:

clusterctl upgrade apply \
  --core cluster-api:v1.6.1 \
  --bootstrap kubeadm:v1.6.1 \
  --control-plane kubeadm:v1.6.1 \
  --infrastructure aws:v2.3.1

Inicialização para provedores comuns

Dependendo do provedor de infraestrutura que você planeja usar, alguns pré-requisitos adicionais devem ser atendidos antes de começar a usar a API Cluster. Veja todos os provedores disponíveis para o CAPI.

Seguindo o nosso caso vamos trabalhar com o provedor AWS, logo, vamos instalar a CLI necessária para interagir com o provedor.

Baixe o binário mais recente das versões do provedor AWS. O utilitário de linha de comando clusterawsadm auxilia no gerenciamento de identidade e acesso (IAM) para Cluster API Provider AWS (CAPA).

Baixe a versão mais recente; lembrando que estamos usando Linux:

curl -L https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/download/v2.3.1/clusterawsadm-linux-amd64 -o clusterawsadm

Torne-o executável:

chmod +x clusterawsadm

Mova o binário para um diretório presente no seu PATH:

sudo mv clusterawsadm /usr/local/bin

Verifique a versão:

clusterawsadm version

Exemplo de uso

Exporte as variáveis necessárias:

export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=<your-access-key>
export AWS_SECRET_ACCESS_KEY=<your-secret-access-key>
export AWS_SESSION_TOKEN=<session-token> # Use somente em caso de autenticação de 2 fatores.

Com base nas credenciais anteriores, vamos configurar a conta AWS:

clusterawsadm bootstrap iam create-cloudformation-stack

Veja o resultado do comando anterior:

Com base nas variáveis de credenciais, vamos codificar com base64, neste etapa é criada uma secret:

export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile)

Finalmente, inicialize o management cluster:

clusterctl init --infrastructure aws

Veja o resultado do comando anterior:

Agora o Provider AWS está configurado para interagir com a sua conta AWS e criar, gerenciar e deletar recursos de computação através do CAPI.

Vamos verificar se temos algum cluster configurado (certamente ainda não criamos cluster e o resultado será o seguinte:

kubectl get cluster -A
No resources found

Algumas variáveis são necessárias para criar seu primeiro workload cluster:

Variables exigidas:

  • AWS_CONTROL_PLANE_MACHINE_TYPE
  • AWS_NODE_MACHINE_TYPE
  • AWS_REGION
  • AWS_SSH_KEY_NAME
  • KUBERNETES_VERSION

Variáveis opcionais:

  • CLUSTER_NAME
  • CONTROL_PLANE_MACHINE_COUNT (default é 1)
  • WORKER_MACHINE_COUNT (default é 0)

Com o comando a seguir gere então o arquivo yaml com as configurações do seu workload cluster:

clusterctl generate cluster k8s-workload \
  --kubernetes-version=v1.27.4 \
  --target-namespace=k8s-workload \
  --control-plane-machine-count=3 \
  --worker-machine-count=3 \
> k8s-workload.yaml

Veja que no comando acima é informado a quantidade de nós que control planes e workers que o cluster deve ter.

Crie um namespace para o seu cluster:

kubectl create namespace k8s-workload
namespace/k8s-workload created

Um arquivo yaml foi criado com todos os objetos necessários para criar o seu cluster, tornando a configuração declarativa. Então agora você vai criar de fato o seu cluster:

kubectl apply -f k8s-workload.yaml

Em seguida é possível acompanhar o status através de algumas verificações, são elas:

Cluster:

kubectl get cluster -n k8s-workload
NAME          CLUSTERCLASS PHASE        AGE VERSION
k8s-workload               Provisioning 36s

Machines em provisionamento:

kubectl get machines -n k8s-workload
NAME                             CLUSTER      NODENAME PROVIDERID                            PHASE        AGE  VERSION
k8s-workload-control-plane-6fqxx k8s-workload          aws:///us-east-1a/i-007c896120ad93d55 Provisioned  8m8s v1.27.4
k8s-workload-md-0-s4cxp-pqn5v    k8s-workload                                                Provisioning 34s  v1.27.4
k8s-workload-md-0-s4cxp-4rx78    k8s-workload                                                Provisioning 34s  v1.27.4
k8s-workload-md-0-s4cxp-xkbc5    k8s-workload                                                Provisioning 34s  v1.27.4

Como obter o kubeconfig do seu novo cluster de workload:

clusterctl get kubeconfig k8s-workload -n k8s-workload > k8s-workload.kubeconfig

Após o seu cluster atingir o status Provisioned, obtenha o kubeconfig para acessar remotamente:

kubectl --kubeconfig k8s-workload.kubeconfig get nodes
NAME                         STATUS   ROLES         AGE   VERSION
ip-10-0-100-106.ec2.internal NotReady <none>        5m36s v1.27.4
ip-10-0-109-215.ec2.internal NotReady <none>        5m39s v1.27.4
ip-10-0-79-97.ec2.internal   NotReady <none>        5m29s v1.27.4
ip-10-0-91-57.ec2.internal   NotReady control-plane 12m   v1.27.4

Veja que o estado dos nós estão em NotReady, isso acontece porque o cluster ainda não possui um CNI (Container Network Interface).

Instalando um CNI Calico:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml

Lembrando que você pode instalar qualquer CNI de sua preferência.

Veja os pods do CNI Calico sendo criados:

Com todos os pods do calico em estado Running, veja agora o estado que o estado dos nós mudaram para Ready:

Consulte o documento de pré-requisitos do provedor AWS para obter mais detalhes.

São muitos os benefícios que o CAPI entrega que vão além do técnico, o ganho financeiro em larga escala pode representar significativamente para a organização, que poderá optar por direcionar os investimento em outras tecnologias e, inclusive, e mão de obra qualificada.

Esta é a forma mais simples de instalar e gerenciar o Cluster API, sinta-se à vontade para explorar o Cluster API com outros provedores de infraestrutura. Os meus proximos artigos vou mostrar como gerenciar multiplos clusters em providers diferentes, de forma declarativa com uso de GitOps e empacotamento HELM.

O projeto também mantém um livro oficial que vale muito a pena dar uma olhada: https://cluster-api.sigs.k8s.io

Espero ter contribuído de alguma forma com este artigo. Até o próximo!

Veja este artigo também no LinkedIn.

Leave a Reply

Your email address will not be published. Required fields are marked *