Skip to content

Capítulo 9: Oracle Kubernetes Engine (OKE)

9.3 Arquitetura do Kubernetes

O Kubernetes é composto por diversos componentes distribuídos e independentes, cada um com sua própria responsabilidade. A maioria deles foi desenvolvida na linguagem de programação Go e muitos fazem parte da Cloud Native Computing Foundation (CNCF).

Para que um cluster Kubernetes funcione corretamente, é necessário instalar e configurar todos esses componentes que serão detalhados a seguir.

alt_text

Além de detalhar os componentes, será apresentada a arquitetura geral do Kubernetes e a forma como esses componentes interagem entre si.

Para facilitar a identificação, a equipe de desenvolvimento do Kubernetes utiliza o prefixo kube na maioria dos componentes e utilitários que fazem parte do projeto. A exceção a essa convenção são duas dependências externas: o Container Runtime e o etcd.

NOTA

Aqui, são apresentados alguns termos e objetos do Kubernetes, como Pods, Services e Deployments. Não se preocupe, pois os detalhes de cada um deles e o seu funcionamento serão explorados na seção 8.5 Objetos Kubernetes.

9.3.1 Master Nodes e Worker Nodes

Um cluster Kubernetes típico é composto por várias máquinas, que podem ser físicas, virtuais ou uma combinação de ambas, conhecidas como Nodes. Esses nodes são organizados em dois grupos principais:

NOTA

É importante ressaltar que, embora seja possível executar todos os componentes do Kubernetes em uma única máquina, essa configuração não oferece tolerância a falhas. A abordagem recomendada é ter pelo menos duas máquinas configuradas como Master Nodes e outras duas como Worker Nodes. Essa configuração proporciona maior resiliência e disponibilidade.

NOTA

As máquinas do Master Nodes deve ser Linux. Já as máquinas dos Worker Nodes podem ser Linux ou Windows.

alt_text

Control Plane ou Master Nodes

Esse grupo de máquinas supervisiona e envia tarefas para os Worker Nodes. Ou seja, elas são responsáveis por manter o "estado desejado do cluster".

Toda a inteligência do Kubernetes está concentrada nos Master Nodes, e cada cluster deve ter pelo menos uma máquina designada para desempenhar essa função.

Há uma coleção de serviços que operam continuamente em cada Master Nodes, responsáveis por manter o estado do cluster, incluindo:

NOTA

A documentação de todos os componentes do Kubernetes está disponível no link "Core Components".

kube-apiserver

O kube-apiserver é o frontend do Kubernetes, atuando como o "ponto de administração" que permite aos usuários enviar comandos e consultar informações sobre o cluster.

Esse componente expõe uma API RESTful via HTTPS, que, por padrão, "escuta" as requisições na porta 6443/TCP. Essa API permite que os usuários gerenciem, monitorem e obtenham informações sobre todo o cluster, através do utilitário de linha de comando kubectl.

alt_text

NOTA

Devido ao fato de o kube-apiserver ser uma API RESTful, é possível interagir com ele utilizando até mesmo o utilitário de linha de comando curl. No entanto, é mais prático e fácil realizar essas interações através do kubectl.

Uma outra função desse componente, é realizar cosultas periódicas ao banco de dados etcd.

etcd

Todos os comandos enviados pelo kube-apiserver, especialmente aqueles que alteram o "estado do cluster", são persistidos ou atualizados em um banco de dados chave/valor distribuído nos Master Nodes conhecido como etcd.

A principal função do etcd é armazenar de maneira persistente todas as alterações que foram enviadas ao kube-apiserver. O Kubernetes consulta periodicamente o etcd para verificar se o "estado do cluster" está em conformidade com os dados ali armazenados.

alt_text

Outro ponto importante é que nenhum componente pode ler ou escrever no etcd sem passar pelo kube-apiserver.

O etcd não é um componente do projeto Kubernetes, mas é um projeto independente que também faz parte da Cloud Native Computing Foundation (CNCF).

NOTA

Existe um playground online acessível pelo link http://play.etcd.io/play, que permite aprender e gerenciar clusters com o etcd.

kube-scheduler

A principal função do kube-scheduler é monitorar periodicamente o kube-apiserver em busca de novos Pods que precisam ser criados. Com base nas informações disponíveis, o kube-scheduler seleciona um ou mais Worker Nodes adequados para a execução desses Pods, garantindo que os requisitos de recursos e restrições de afinidade sejam atendidos.

alt_text

NOTA

Uma explicação mais detalhada sobre objetos do Kubernetes será apresentada no capítulo 8.4 Objetos Kubernetes. Por enquanto, é importante compreender que um Pod é um objeto do Kubernetes utilizado para definir uma unidade de execução que pode conter um ou mais contêineres.

Um Pod recém-criado não possui um Worker Node designado para sua execução. Chamamos de "Unschedule Pod" o Pod que não possui um Worker Node elegível para execução, e seu status fica como "Pending". Já o termo "Schedule" refere-se ao processo de atribuição do Pod a um Worker Node capaz de realizar a sua execução. Em outras palavras, quando um Pod é "scheduled", isso significa que ele foi atribuído a um Worker Node específico que é capaz de executá-lo.

Além disso, o kube-scheduler desempenha outras funções importantes, como a verificação de regras de afinidade e antiafinidade, a checagem da disponibilidade de portas de rede e a validação dos recursos de CPU e memória.

NOTA

O processo de Scheduling do Kubernetes é bem mais complexo do que foi descrito aqui. Para maiores detalhes, consulte o "Scheduling, Preemption and Eviction".

kube-controller-manager

O kube-controller-manager, também conhecido como controller, é responsável por executar o "loop de reconciliação" (reconciliation loop), que tem como objetivo manter o "estado do cluster" em sincronia com as informações armazenadas no etcd.

Por exemplo, quando solicitado, o Kubernetes é capaz de manter um número específico de Pods distribuídos entre os diferentes Worker Nodes. Se, por qualquer motivo, o número total de Pods ativos divergir do número de Pods registrados no etcd, o "loop de reconciliação" garantirá que os Pods ausentes sejam criados e iniciados. Vale ressaltar que essa verificação é um processo contínuo, o que justifica o uso da palavra "loop" para descrever sua funcionalidade.

alt_text

Há diferentes controller que fazem parte do "loop de reconciliação" e cada um deles é responsável por gerenciar e cuidar de um tipo específico de objeto Kubernetes. Alguns deles são:

  • Replication Controller
  • Deployment Controller
  • Job Controller
  • Namespace Controller

OCI Cloud Controller Manager (CCM)

O OCI Cloud Controller Manager (oci-cloud-controller-manager), é a implementação do cloud-controller-manager responsável por conectar o Kubernetes às APIs do OCI.

NOTA

O oci-cloud-controller-manager é um projeto de código aberto mantido pela Oracle. O código-fonte da implementação pode ser acessado por meio do link https://github.com/oracle/oci-cloud-controller-manager.

Uma das funcionalidades do oci-cloud-controller-manager é a criação de Load Balance no OCI por meio do do objeto Service.

alt_text

Compute Nodes ou Worker Nodes

Em resumo, os Worker Nodes têm a função de executar aplicações contêinerizadas, ou, mais precisamente, executar Pods.

Existem, basicamente, três componentes do cluster Kubernetes que são executados nos Worker Nodes e são responsáveis pela execução dos Pods. São eles:

Container Runtime

O Container Runtime é o software responsável pela criação, execução e gerenciamento de contêineres nos Worker Nodes. É necessário instalar um Container Runtime em cada Worker Node para que os Pods possam ser criados e executados.

Existem diferentes Container Runtime suportados e disponíveis para instalação, incluindo:

alt_text

O Docker Engine foi, por muito tempo, o Container Runtime padrão para a execução de contêineres no Kubernetes. No entanto, em dezembro de 2020, com o lançamento da versão 1.20, o projeto Kubernetes anunciou a descontinuação do suporte ao Docker Engine como runtime de contêineres. Na versão 1.24, o suporte ao Docker Engine foi completamente removido.

Essa decisão foi motivada para permitir a adoção de outros runtimes de contêiner, como containerd, CRI-O, além de qualquer outro que siga as definições do Container Runtime Interface (CRI).

Isso não significa que imagens de contêineres Docker não são compatíveis com o Kubernetes. Todas as imagens que seguem a especificação da Open Container Initiative, são totalmente suportadas no Kubernetes, incluindo as imagens Docker.

Atualmente, é comum ter instalações do containerd ou CRI-O sendo utilizados como runtimes de contêiner. Por exemplo, o Oracle Kubernetes Engine (OKE) utiliza o containerd como seu runtime padrão.

NOTA

Consulte o artigo "Don't Panic: Kubernetes and Docker" que aborda a remoção do Docker Engine como um runtime de contêiner suportado diretamente pelo Kubernetes.

kubelet

O kubelet, componente principal do Worker Node, é responsável por realizar consultas regulares ao kube-apiserver, buscando informações sobre os Pods a serem criados ou removidos. Após obter essas informações, o kubelet interage diretamente com o Container Runtime no Worker Node para a criação ou exclusão efetiva dos Pods.

alt_text

Mais especificamente, o kubelet obtém e processa o chamado PodSpec, que é um conjunto de informações que define as instruções de criação e o comportamento desejado do Pod. O PodSpec inclui detalhes como a imagem do contêiner a ser utilizada, as configurações de rede, as variáveis de ambiente, os recursos solicitados (como CPU e memória) e as políticas de restart. Com base nessas informações, o kubelet gerencia a execução do Pod no Worker Node, garantindo que ele atenda ao "estado desejado" especificado.

kube-proxy

Em cada Worker Node, há uma instância em execução do kube-proxy, que funciona como um proxy de rede, garantindo a conectividade interna e externa. É o kube-proxy que torna os Pods acessíveis na rede por meio do objeto Service.

alt_text

Assim como o kubelet, o kube-proxy também interage regularmente com o kube-apiserver.

9.3.2 Addons

Addons são ferramentas que estendem as funcionalidades do Kubernetes.

Alguns Addons são essenciais para o funcionamento adequado do cluster, enquanto outros são opcionais.

NOTA

Para uma lista mais completa sobre os Addons disponíveis, consulte o link "Installing Addons".

Alguns exemplos de Addons essenciais incluem:

  • CoreDNS
    • O CoreDNS é um servidor DNS mais simples em comparação com servidores mais completos, como o BIND. Ele foi projetado para ser utilizado como o servidor DNS padrão no Kubernetes, desempenhando a função de resolver nomes de Services e Pods dentro do cluster. No entanto, ele também pode ser configurado para atuar como um servidor DNS recursivo, permitindo a resolução de nomes externos.

alt_text

  • CNI plugin for pod networking

    • CNI (Container Network Interface) é uma especificação e um conjunto de padrões que define uma interface para a configuração de redes em ambientes de contêineres. As implementações CNI mais utilizados no OKE são:

    • Flannel

      • O plug-in CNI Flannel fornece uma rede para os Pods sem utilizar os endereços IP disponíveis de uma sub-rede do OCI. A rede disponibilizada pelo CNI Flannel é frequentemente chamada de "rede de sobreposição", pois consiste em uma rede IP que existe somente dentro do cluster, mais especificamente, nos Worker Nodes.
    • OCI VCN-Native

      • O plugin OCI VCN-Native Pod Networking CNI, aloca endereços IP de uma sub-rede do OCI diretamente para os Pods. Isso permite que os Pods se comuniquem entre si de forma direta, sem a necessidade de utilizar um Service. Com essa abordagem, os Pods se tornam roteáveis, assim como qualquer outro recurso que utilize um endereço IP, facilitando a comunicação e a integração dentro do ambiente de rede.

alt_text

Alguns exemplos de Addons opcionais incluem:

  • Kubernetes Dashboard

    • O Kubernetes Dashboard é uma aplicação Web projetada para administrar, monitorar e gerenciar Pods, Services, Deployments e outros componentes, além de fornecer uma visão geral do próprio cluster Kubernetes.
  • Kubernetes Autoscaler

    • O Kubernetes Autoscaler é um addon que ajusta automaticamente a capacidade de um cluster Kubernetes com base na demanda de recursos. Ele opera em duas frentes principais: o HPA (Horizontal Pod Autoscaler), que tem como objetivo escalar horizontalmente, ou seja, aumentar ou diminuir o número de réplicas de um Pod, e o VPA (Vertical Pod Autoscaler), que modifica a quantidade de recursos, como CPU e memória, alocados para um Pod.
  • OCI Native Ingress Controller

    • É um componente desenvolvido pela Oracle que permite gerenciar o tráfego de entrada (ingress) para aplicações em execução em um cluster Kubernetes que está hospedado no OCI. Ele fornece uma maneira de expor serviços de aplicações para o mundo externo, permitindo que os usuários acessem essas aplicações através de URLs e domínios.
  • NVIDIA GPU Plugin

    • É um addon que permite expor um número de GPUs NVIDIA para utilização em cada Worker Node.

9.3.3 Como o Kubernetes Funciona do Início ao Fim (resumo)

  1. Você configura um cluster Kubernetes – ele é composto de Master Nodes e Worker Nodes.

  2. Você define sua aplicação usando arquivos YAML – normalmente com Deployment, Service, ConfigMap, etc.

  3. Você aplica o YAML usando o comando kubectl apply -f. A solicitação vai para o API Server nos Master Nodes.

  4. O Kubernetes verifica a solicitação para decidir o que fazer:
    a. Criar um novo objeto como um Pod ou Deployment?
    b. Atualizar ou excluir um objeto existente?
    c. Acionar um controlador para executar alguma ação? etc.

  5. O API Server armazena a especificação do objeto no etcd, o banco de dados do cluster.

  6. O controlador apropriado vê a nova especificação – como um controlador ReplicaSet monitorando novos Deployments.

  7. O controlador cria os recursos necessários – por exemplo, dizendo ao scheduler para posicionar novos Pods.

  8. O scheduler escolhe um nó adequado para cada Pod – com base na disponibilidade de recursos e regras de agendamento.

  9. A especificação do Pod é enviada para o Kubelet do nó – ele solicita ao runtime do contêiner que inicie o contêiner.

  10. O runtime do contêiner faz o pull da imagem, cria o contêiner e o executa dentro do Pod.

  11. O plugin CNI atribui uma identidade de rede – o Pod recebe um endereço IP e se junta à rede do cluster.

  12. O kube-proxy configura regras de roteamento – permitindo que os Services encaminhem tráfego para Pods saudáveis.

  13. O Kubelet relata o status dos Pods de volta ao API Server – usado para rastrear prontidão e saúde.

  14. Se um Pod falhar ou for excluído, o controlador percebe e o recria – mantendo o sistema sincronizado.

  15. Esse loop inteiro continua funcionando – o Kubernetes observa constantemente e reconcilia para corresponder ao estado desejado.

9.3.4 Conclusão

Neste capítulo, foi apresentada uma visão geral do funcionamento e da arquitetura de um cluster Kubernetes. Foram explorados os diversos componentes de software que o compõem, destacando suas funções e a maneira como interagem entre si para formar o ecossistema do Kubernetes. Compreender a totalidade do sistema é fundamental não apenas para entender como o Kubernetes opera, mas também para auxiliar na identificação e resolução de problemas que possam surgir.