Um cluster Kubernetes consiste em um control plane mais um conjunto de máquinas trabalhadoras, chamadas de nodes,
que executam aplicações containerizadas. Todo cluster precisa de pelo menos um worker node para executar Pods.
Os worker nodes hospedam os Pods que são os componentes da carga de trabalho da aplicação.
O control plane gerencia os worker nodes e os Pods no cluster. Em ambientes de produção,
o control plane geralmente executa em múltiplos computadores e um cluster
geralmente executa múltiplos nodes, fornecendo tolerância a falhas e alta disponibilidade.
Este documento descreve os vários componentes que você precisa ter para um cluster Kubernetes completo e funcional.
Figura 1. Componentes do cluster Kubernetes.
Sobre esta arquitetura
O diagrama na Figura 1 apresenta um exemplo de arquitetura de referência para um cluster Kubernetes.
A distribuição real dos componentes pode variar com base em configurações e requisitos específicos do cluster.
No diagrama, cada node executa o componente kube-proxy. Você precisa de um
componente de proxy de rede em cada node para garantir que a
API de Service e comportamentos associados
estejam disponíveis na rede do seu cluster. No entanto, alguns plugins de rede fornecem sua própria
implementação de proxy de terceiros. Quando você usa esse tipo de plugin de rede,
o node não precisa executar o kube-proxy.
Componentes do control plane
Os componentes do control plane tomam decisões globais sobre o cluster (por exemplo, agendamento),
bem como detectam e respondem a eventos do cluster (por exemplo, iniciar um novo
pod quando o campo
replicas de um Deployment não está satisfeito).
Os componentes do control plane podem ser executados em qualquer máquina do cluster. No entanto, para simplicidade, scripts de
configuração normalmente iniciam todos os componentes do control plane na mesma máquina, e não executam containers de usuário nesta máquina.
Consulte Criando clusters altamente disponíveis com kubeadm
para um exemplo de configuração do control plane que executa em múltiplas máquinas.
kube-apiserver
O servidor da API é um componente da camada de gerenciamento
do Kubernetes que expõe a API do Kubernetes.
O servidor da API é o front end para a camada de gerenciamento do Kubernetes.
A principal implementação de um servidor de API do Kubernetes é o
kube-apiserver.
O kube-apiserver foi projetado para ser escalonado horizontalmente — ou seja,
ele pode ser escalonado com a criação de mais instâncias.
Você pode executar várias instâncias do kube-apiserver e distribuir o tráfego
entre essas instâncias.
etcd
Armazenamento do tipo chave-valor consistente e de alta-disponibilidade, usado
como armazenamento de apoio do Kubernetes para todos os dados do cluster.
Se o seu cluster Kubernetes usa o etcd como seu armazenamento de apoio,
certifique-se de ter um plano de
backup
para seus dados.
Você pode encontrar informações detalhadas sobre o etcd na documentação
oficial.
kube-scheduler
Componente da camada de gerenciamento que observa os
Pods recém-criados e que ainda não
foram atribuídos a um nó, e
seleciona um nó para executá-los.
Os fatores levados em consideração para as decisões de alocação incluem:
requisitos de recursos individuais e coletivos, restrições de hardware/software/política,
especificações de afinidade e antiafinidade, localidade de dados, interferência
entre cargas de trabalho, e prazos.
kube-controller-manager
Componente da camada de gerenciamento que executa os processos de
controlador.
Logicamente, cada controlador
está em um processo separado, mas para reduzir a complexidade, eles todos são
compilados num único binário e executam em um processo único.
Existem muitos tipos diferentes de controllers. Alguns exemplos deles são:
Node controller: Responsável por notar e responder quando nodes ficam indisponíveis.
Job controller: Observa objetos Job que representam tarefas pontuais, depois cria Pods para executar essas tarefas até a conclusão.
EndpointSlice controller: Preenche objetos EndpointSlice (para fornecer um link entre Services e Pods).
ServiceAccount controller: Cria ServiceAccounts padrão para novos namespaces.
A lista acima não é exaustiva.
cloud-controller-manager
Um componente da camada de gerenciamento do Kubernetes
que incorpora a lógica de controle específica da nuvem. O gerenciador de controle de nuvem permite que você vincule seu
cluster na API do seu provedor de nuvem, e separar os componentes que interagem com essa plataforma de nuvem a partir de componentes que apenas interagem com seu cluster.
O cloud-controller-manager executa apenas controllers que são específicos do seu provedor de nuvem.
Se você está executando o Kubernetes em suas próprias instalações, ou em um ambiente de aprendizado dentro do seu
próprio PC, o cluster não tem um cloud controller manager.
Assim como o kube-controller-manager, o cloud-controller-manager combina vários loops de controle logicamente
independentes em um único binário que você executa como um único processo. Você pode escalar
horizontalmente (executar mais de uma cópia) para melhorar o desempenho ou para ajudar a tolerar falhas.
Os seguintes controllers podem ter dependências do provedor de nuvem:
Node controller: Para verificar o provedor de nuvem para determinar se um node foi
excluído na nuvem após parar de responder
Route controller: Para configurar rotas na infraestrutura de nuvem subjacente
Service controller: Para criar, atualizar e excluir load balancers do provedor de nuvem
Componentes do node
Os componentes do node executam em cada node, mantendo pods em execução e fornecendo o ambiente de runtime do Kubernetes.
kubelet
Um agente que é executado em cada nó
no cluster. Ele garante que os contêineres
estejam sendo executados em um Pod.
O kubelet utiliza um conjunto de PodSpecs que são fornecidos por vários mecanismos
e garante que os contêineres descritos nesses PodSpecs estejam funcionando corretamente.
O kubelet não gerencia contêineres que não foram criados pelo Kubernetes.
kube-proxy (opcional)
kube-proxy é um proxy de rede executado em cada nó no seu cluster,
implementando parte do conceito de serviço do Kubernetes.
kube-proxy
mantém regras de rede nos nós. Estas regras de rede permitem a comunicação de rede com seus pods a partir de sessões de rede dentro ou fora de seu cluster.
kube-proxy usa a camada de filtragem de pacotes do sistema operacional se houver uma e estiver disponível. Caso contrário, o kube-proxy encaminha o tráfego ele mesmo.
Se você usar um plugin de rede que implementa encaminhamento de pacotes para Services
por si só, e fornece comportamento equivalente ao kube-proxy, então você não precisa executar
kube-proxy nos nodes do seu cluster.
Container runtime
O agente de execução (runtime) de contêiner é o software responsável por executar os contêineres.
Addons usam recursos do Kubernetes (DaemonSet,
Deployment, etc) para implementar funcionalidades do cluster.
Como estes estão fornecendo funcionalidades no nível do cluster, recursos com namespace para
addons pertencem ao namespace kube-system.
Addons selecionados são descritos abaixo; para uma lista estendida de addons disponíveis,
consulte Addons.
DNS
Embora os outros addons não sejam estritamente necessários, todos os clusters Kubernetes devem ter
DNS do cluster, pois muitos exemplos dependem dele.
DNS do cluster é um servidor DNS, além do(s) outro(s) servidor(es) DNS em seu ambiente,
que serve registros DNS para services do Kubernetes.
Containers iniciados pelo Kubernetes automaticamente incluem este servidor DNS em suas buscas DNS.
Web UI (Dashboard)
Dashboard é uma UI baseada na web de propósito geral
para clusters Kubernetes. Ela permite aos usuários gerenciar e solucionar problemas de aplicações
executando no cluster, bem como o próprio cluster.
Monitoramento de recursos de container
Monitoramento de Recursos de Container
grava métricas genéricas de séries temporais sobre containers em um banco de dados central, e fornece uma UI para navegar nesses dados.
Logging no nível do cluster
Um mecanismo de logging no nível do cluster é responsável
por salvar logs de containers em um armazenamento central de logs com uma interface de busca/navegação.
Plugins de rede
Plugins de rede
são componentes de software que implementam a especificação da interface de rede de containers (CNI).
Eles são responsáveis por alocar endereços IP para pods e permitir que eles se comuniquem
uns com os outros dentro do cluster.
Variações de arquitetura
Embora os componentes principais do Kubernetes permaneçam consistentes, a forma como eles são implantados e
gerenciados pode variar. Entender essas variações é crucial para projetar e manter
clusters Kubernetes que atendam às necessidades operacionais específicas.
Opções de implantação do control plane
Os componentes do control plane podem ser implantados de várias maneiras:
Implantação tradicional
Os componentes do control plane executam diretamente em máquinas dedicadas ou VMs, frequentemente gerenciados como serviços systemd.
Pods estáticos
Os componentes do control plane são implantados como Pods estáticos, gerenciados pelo kubelet em nodes específicos.
Esta é uma abordagem comum usada por ferramentas como kubeadm.
Auto-hospedado
O control plane executa como Pods dentro do próprio cluster Kubernetes, gerenciado por Deployments
e StatefulSets ou outras primitivas do Kubernetes.
Serviços gerenciados do Kubernetes
Provedores de nuvem frequentemente abstraem o control plane, gerenciando seus componentes como parte de sua oferta de serviço.
Considerações de posicionamento de carga de trabalho
O posicionamento de cargas de trabalho, incluindo os componentes do control plane, pode variar com base no tamanho do cluster,
requisitos de desempenho e políticas operacionais:
Em clusters menores ou de desenvolvimento, componentes do control plane e cargas de trabalho de usuário podem executar nos mesmos nodes.
Clusters de produção maiores frequentemente dedicam nodes específicos aos componentes do control plane,
separando-os das cargas de trabalho de usuário.
Algumas organizações executam addons críticos ou ferramentas de monitoramento em nodes do control plane.
Ferramentas de gerenciamento de cluster
Ferramentas como kubeadm, kops e Kubespray oferecem diferentes abordagens para implantar e gerenciar clusters,
cada uma com seu próprio método de layout e gerenciamento de componentes.
A flexibilidade da arquitetura do Kubernetes permite que organizações adaptem seus clusters às necessidades específicas,
equilibrando fatores como complexidade operacional, desempenho e sobrecarga de gerenciamento.
Customização e extensibilidade
A arquitetura do Kubernetes permite customização significativa:
Schedulers customizados podem ser implantados para trabalhar junto com o scheduler padrão do Kubernetes ou para substituí-lo completamente.
Servidores de API podem ser estendidos com CustomResourceDefinitions e API Aggregation.
Provedores de nuvem podem se integrar profundamente com o Kubernetes usando o cloud-controller-manager.
A flexibilidade da arquitetura do Kubernetes permite que organizações adaptem seus clusters às necessidades específicas,
equilibrando fatores como complexidade operacional, desempenho e sobrecarga de gerenciamento.
O Kubernetes executa sua carga de trabalho colocando contêineres em Pods para serem executados em Nós. Um nó pode ser uma máquina virtual ou física, dependendo do cluster. Cada nó é gerenciado pela camada de gerenciamento e contém os serviços necessários para executar Pods.
Normalmente, você tem vários nós em um cluster; em um ambiente de aprendizado ou limitado por recursos, você pode ter apenas um nó.
Existem duas maneiras principais de adicionar Nós ao Servidor da API:
O kubelet em um nó se registra automaticamente na camada de gerenciamento
Você (ou outro usuário humano) adiciona manualmente um objeto Nó
Depois de criar um objeto Nó, ou o kubelet em um nó se registra automaticamente, a camada de gerenciamento verifica se o novo objeto Nó é válido. Por exemplo, se você tentar criar um nó a partir do seguinte manifesto JSON:
O Kubernetes cria um objeto nó internamente (a representação). O Kubernetes verifica se um kubelet se registrou no servidor da API que corresponde ao campo metadata.name do Nó. Se o nó estiver íntegro (ou seja, todos os serviços necessários estiverem em execução), ele será elegível para executar um Pod. Caso contrário, esse nó é ignorado para qualquer atividade de cluster até que se torne íntegro.
Nota:
O Kubernetes mantém o objeto nó inválido e continua verificando se ele se torna íntegro.
Você, ou um controlador, deve excluir explicitamente o objeto Nó para interromper essa verificação de integridade.
O nome identifica um nó. Dois nós não podem ter o mesmo nome ao mesmo tempo. O Kubernetes também assume que um recurso com o mesmo nome é o mesmo objeto. No caso de um nó, assume-se implicitamente que uma instância usando o mesmo nome terá o mesmo estado (por exemplo, configurações de rede, conteúdo do disco raiz) e atributos como label de nó. Isso pode levar a inconsistências se uma instância for modificada sem alterar seu nome. Se o nó precisar ser substituído ou atualizado significativamente, o objeto Nó existente precisa ser removido do servidor da API primeiro e adicionado novamente após a atualização.
Auto-registro de Nós
Quando a opção --register-node do kubelet for verdadeira (padrão), o kubelet tentará se registrar no servidor da API. Este é o padrão preferido, usado pela maioria das distribuições.
Para auto-registro, o kubelet é iniciado com as seguintes opções:
--kubeconfig - O caminho das credenciais para se autenticar no servidor da API.
--cloud-provider - Como comunicar com um provedor de nuvem
para ler metadados sobre si mesmo.
--register-node - Registrar automaticamente no servidor da API.
--register-with-taints - Registra o nó com a lista fornecida de taints (separadas por vírgula <key>=<value>:<effect>).
Como mencionado na seção de singularidade do nome do nó, quando a configuração do nó precisa ser atualizada, é uma boa prática registrar novamente o nó no servidor da API. Por exemplo, se o kubelet estiver sendo reiniciado com o novo conjunto de --node-labels, mas o mesmo nome de nó for usado, a alteração não entrará em vigor, pois os labels estão sendo definidos no registro do Nó.
Pods já agendados no Nó podem ter um comportamento anormal ou causar problemas se a configuração do Nó for alterada na reinicialização do kubelet. Por exemplo, o Pod já em execução pode estar marcado diferente dos labels atribuídos ao Nó, enquanto outros Pods, que são incompatíveis com esse Pod, serão agendados com base nesse novo label. O novo registro do nó garante que todos os Pods sejam drenados e devidamente reiniciados.
Administração manual de nós
Você pode criar e modificar objetos Nó usando o kubectl.
Quando você quiser manualmente criar objetos Nó, defina a opção do kubelet --register-node=false.
Você pode modificar os objetos Nó, independentemente da configuração de --register-node. Por exemplo, você pode definir labels em um nó existente ou marcá-lo como não disponível.
Você pode usar labels nos Nós em conjunto com seletores de nós nos Pods para controlar a disponibilidade. Por exemplo, você pode restringir um Pod a ser elegível apenas para ser executado em um subconjunto dos nós disponíveis.
Marcar um nó como não disponível impede que o escalonador coloque novos pods nesse nó, mas não afeta os Pods existentes no nó. Isso é útil como uma etapa preparatória antes da reinicialização de um nó ou outra manutenção.
Os Pods que fazem parte de um DaemonSet toleram ser executados em um nó não disponível. Os DaemonSets geralmente fornecem serviços locais de nós que devem ser executados em um Nó, mesmo que ele esteja sendo drenado de aplicativos de carga de trabalho.
Status do Nó
O status de um nó contém as seguintes informações:
Você pode usar o kubectl para visualizar o status de um nó e outros detalhes:
kubectl describe node <insira-nome-do-nó-aqui>
Cada seção da saída está descrita abaixo.
Endereços
O uso desses campos pode mudar dependendo do seu provedor de nuvem ou configuração dedicada.
HostName: O nome do host relatado pelo kernel do nó. Pode ser substituído através do parâmetro kubelet --hostname-override.
ExternalIP: Geralmente, o endereço IP do nó que é roteável externamente (disponível fora do cluster).
InternalIP: Geralmente, o endereço IP do nó que é roteável somente dentro do cluster.
Condições
O campo conditions descreve o status de todos os nós em execução. Exemplos de condições incluem:
Condições do nó e uma descrição de quando cada condição se aplica.
Condições do nó
Descrição
Ready
True Se o nó estiver íntegro e pronto para aceitar pods, False se o nó não estiver íntegro e não estiver aceitando pods, e desconhecido Unknown se o controlador do nó tiver sem notícias do nó no último node-monitor-grace-period (o padrão é de 40 segundos)
DiskPressure
True Se houver pressão sobre o tamanho do disco, ou seja, se a capacidade do disco for baixa; caso contrário False
MemoryPressure
True Se houver pressão na memória do nó, ou seja, se a memória do nó estiver baixa; caso contrário False
PIDPressure
True Se houver pressão sobre os processos, ou seja, se houver muitos processos no nó; caso contrário False
NetworkUnavailable
True Se a rede do nó não estiver configurada corretamente, caso contrário False
Nota:
Se você usar as ferramentas de linha de comando para mostrar os detalhes de um nó isolado, a Condition inclui SchedulingDisabled. SchedulingDisabled não é uma condição na API do Kubernetes; em vez disso, os nós isolados são marcados como Unschedulable em suas especificações.
Na API do Kubernetes, a condição de um nó é representada como parte do .status do recurso do nó. Por exemplo, a seguinte estrutura JSON descreve um nó íntegro:
Se o status da condição Ready permanecer desconhecido (Unknown) ou falso (False) por mais tempo do que o limite da remoção do pod (pod-eviction-timeout) (um argumento passado para o kube-controller-manager), o controlador de nó acionará o remoção iniciado pela API para todos os Pods atribuídos a esse nó. A duração padrão do tempo limite da remoção é de cinco minutos. Em alguns casos, quando o nó está inacessível, o servidor da API não consegue se comunicar com o kubelet no nó. A decisão de excluir os pods não pode ser comunicada ao kubelet até que a comunicação com o servidor da API seja restabelecida. Enquanto isso, os pods agendados para exclusão podem continuar a ser executados no nó particionado.
O controlador de nós não força a exclusão dos pods até que seja confirmado que eles pararam de ser executados no cluster. Você pode ver os pods que podem estar sendo executados em um nó inacessível como estando no estado de terminando (Terminating) ou desconhecido (Unknown). Nos casos em que o Kubernetes não retirar da infraestrutura subjacente se um nó tiver deixado permanentemente um cluster, o administrador do cluster pode precisar excluir o objeto do nó manualmente. Excluir o objeto do nó do Kubernetes faz com que todos os objetos Pod em execução no nó sejam excluídos do servidor da API e libera seus nomes.
Quando ocorrem problemas nos nós, a camada de gerenciamento do Kubernetes cria automaticamente taints que correspondem às condições que afetam o nó. O escalonador leva em consideração as taints do Nó ao atribuir um Pod a um Nó. Os Pods também podem ter tolerations que os permitem funcionar em um nó, mesmo que tenha uma taint específica.
Descreve os recursos disponíveis no nó: CPU, memória e o número máximo de pods que podem ser agendados no nó.
Os campos no bloco de capacidade indicam a quantidade total de recursos que um nó possui. O bloco alocado indica a quantidade de recursos em um nó que está disponível para ser consumido por Pods normais.
Descreve informações gerais sobre o nó, como a versão do kernel, a versão do Kubernetes (versão do kubelet e kube-proxy), detalhes do tempo de execução do contêiner e qual sistema operacional o nó usa. O kubelet coleta essas informações do nó e as publica na API do Kubernetes.
Heartbeats
Os Heartbeats, enviados pelos nós do Kubernetes, ajudam seu cluster a determinar a disponibilidade de cada nó e a agir quando as falhas forem detectadas.
Para nós, existem duas formas de heartbeats:
atualizações para o .status de um Nó
Objetos Lease dentro do namespacekube-node-lease. Cada nó tem um objeto de Lease associado.
Em comparação com as atualizações no .status de um nó, um Lease é um recurso mais leve. O uso de Leases para heartbeats reduz o impacto no desempenho dessas atualizações para grandes clusters.
O kubelet é responsável por criar e atualizar o .status dos Nós e por atualizar suas Leases relacionadas.
O kubelet atualiza o .status do nó quando há mudança de status ou se não houve atualização para um intervalo configurado. O intervalo padrão para atualizações .status para Nós é de 5 minutos, o que é muito maior do que o tempo limite padrão de 40 segundos para nós inacessíveis.
O kubelet cria e atualiza seu objeto Lease a cada 10 segundos (o intervalo de atualização padrão). As atualizações de Lease ocorrem independentemente das atualizações no .status do Nó. Se a atualização do Lease falhar, o kubelet voltará a tentativas, usando um recuo exponencial que começa em 200 milissegundos e limitado a 7 segundos.
Controlador de Nós
O controlador de nós é um componente da camada de gerenciamento do Kubernetes que gerencia vários aspectos dos nós.
O controlador de nó tem várias funções na vida útil de um nó. O primeiro é atribuir um bloco CIDR ao nó quando ele é registrado (se a atribuição CIDR estiver ativada).
O segundo é manter a lista interna de nós do controlador de nós atualizada com a lista de máquinas disponíveis do provedor de nuvem. Ao ser executado em um ambiente de nuvem e sempre que um nó não é íntegro, o controlador de nó pergunta ao provedor de nuvem se a VM desse nó ainda está disponível. Caso contrário, o controlador de nós exclui o nó de sua lista de nós.
O terceiro é monitorar a saúde dos nós. O controlador do nó é responsável por:
No caso de um nó se tornar inacessível, atualizar a condição NodeReady dentro do campo .status do nó. Nesse caso, o controlador do nó define a condição de pronto (NodeReady) como condição desconhecida (ConditionUnknown).
Se um nó permanecer inacessível: será iniciado a remoção pela API para todos os Pods no nó inacessível. Por padrão, o controlador do nó espera 5 minutos entre marcar o nó como condição desconhecida (ConditionUnknown) e enviar a primeira solicitação de remoção.
O controlador de nó verifica o estado de cada nó a cada --node-monitor-period segundos.
Limites de taxa de remoção
Na maioria dos casos, o controlador de nós limita a taxa de remoção a --node-eviction-rate (0,1 por padrão) por segundo, o que significa que ele não removerá pods de mais de 1 nó por 10 segundos.
O comportamento de remoção do nó muda quando um nó em uma determinada zona de disponibilidade se torna não íntegro. O controlador de nós verifica qual porcentagem de nós na zona não são íntegras (a condição NodeReady é desconhecida ConditionUnknown ou falsa ConditionFalse) ao mesmo tempo:
Se a fração de nós não íntegros for ao menos --unhealthy-zone-threshold (padrão 0,55), então a taxa de remoção será reduzida.
Se o cluster for pequeno (ou seja, tiver número de nós menor ou igual ao valor da opção --large-cluster-size-threshold - padrão 50), então as remoções serão interrompidas.
Caso contrário, a taxa de remoção é reduzida para --secondary-node-eviction-rate de nós secundários (padrão 0,01) por segundo.
A razão pela qual essas políticas são implementadas por zona de disponibilidade é porque a camada de gerenciamento pode perder conexão com uma zona de disponibilidade, enquanto as outras permanecem conectadas. Se o seu cluster não abranger várias zonas de disponibilidade de provedores de nuvem, o mecanismo de remoção não levará em conta a indisponibilidade por zona.
Uma das principais razões para espalhar seus nós pelas zonas de disponibilidade é para que a carga de trabalho possa ser transferida para zonas íntegras quando uma zona inteira cair. Portanto, se todos os nós em uma zona não estiverem íntegros, o controlador do nó removerá na taxa normal de --node-eviction-rate. O caso especial é quando todas as zonas estiverem completamente insalubres (nenhum dos nós do cluster será íntegro). Nesse caso, o controlador do nó assume que há algum problema com a conectividade entre a camada de gerenciamento e os nós e não realizará nenhuma remoção. (Se houver uma interrupção e alguns nós reaparecerem, o controlador do nó expulsará os pods dos nós restantes que estiverem insalubres ou inacessíveis).
O controlador de nós também é responsável por remover pods em execução nos nós com NoExecute taints, a menos que esses pods tolerem essa taint. O controlador de nó também adiciona as taints correspondentes aos problemas de nó, como nó inacessível ou não pronto. Isso significa que o escalonador não colocará Pods em nós não íntegros.
Rastreamento de capacidade de recursos
Os objetos do nó rastreiam informações sobre a capacidade de recursos do nó: por exemplo, a quantidade de memória disponível e o número de CPUs. Os nós que se auto-registram relatam sua capacidade durante o registro. Se você adicionar manualmente um nó, precisará definir as informações de capacidade do nó ao adicioná-lo.
O escalonador do Kubernetes garante que haja recursos suficientes para todos os Pods em um nó. O escalonador verifica se a soma das solicitações de contêineres no nó não é maior do que a capacidade do nó. Essa soma de solicitações inclui todos os contêineres gerenciados pelo kubelet, mas exclui quaisquer contêineres iniciados diretamente pelo agente de execução de contêiner e também exclui quaisquer processos executados fora do controle do kubelet.
Se você ativou os [recursos]](/docs/reference/command-line-tools-reference/feature-gates/) de TopologyManager, o kubelet pode usar dicas da topologia ao tomar decisões de atribuição de recursos. Consulte Controle das Políticas de Gerenciamento de Topologia em um Nó para obter mais informações.
Desligamento gracioso do nó
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [beta]
O kubelet tenta detectar o desligamento do sistema do nó e encerra os pods em execução no nó.
O Kubelet garante que os pods sigam o processo normal de término do podpod-lifecycle/#pod-termination) durante o desligamento do nó.
O recurso de desligamento gradual do nó depende do systemd, pois aproveita os bloqueios do inibidor do systemd para atrasar o desligamento do nó com uma determinada duração.
O desligamento gradual do nó é controlado com recursosGracefulNodeShutdown, que é ativado por padrão na versão 1.21.
Observe que, por padrão, ambas as opções de configuração descritas abaixo, shutdownGracePeriod and shutdownGracePeriodCriticalPods estão definidas como zero, não ativando assim a funcionalidade de desligamento gradual do nó. Para ativar o recurso, as duas configurações do kubelet devem ser configuradas adequadamente e definidas como valores diferentes de zero.
Durante um desligamento gradual, o kubelet encerra os pods em duas fases:
O recurso de desligamento gradual do nó é configurado com duas opções KubeletConfiguration:
shutdownGracePeriod:
Especifica a duração total pela qual o nó deve atrasar o desligamento. Este é o período de carência total para o término dos pods regulares e os críticos.
shutdownGracePeriodCriticalPods:
Especifica a duração utlizada para encerrar pods críticos durante um desligamento de nó. Este valor deve ser menor que shutdownGracePeriod.
Por exemplo, se shutdownGracePeriod=30s e shutdownGracePeriodCriticalPods=10s, o kubelet atrasará o desligamento do nó em 30 segundos. Durante o desligamento, os primeiros 20 (30-10) segundos seriam reservados para encerrar gradualmente os pods normais, e os últimos 10 segundos seriam reservados para encerrar pods críticos.
Nota:
Quando os pods forem removidos durante o desligamento gradual do nó, eles serão marcados como desligados. Executar o kubectl get pods para mostrar o status dos pods removidos como Terminated. E o kubectl describe pod indica que o pod foi removido por causa do desligamento do nó:
Reason: Terminated
Message: Pod was terminated in response to imminent node shutdown.
Desligamento gradual do nó baseado em prioridade do Pod
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [beta]
Para fornecer mais flexibilidade durante o desligamento gradual do nó em torno da ordem de pods durante o desligamento, o desligamento gradual do nó respeita a PriorityClass dos Pods, desde que você tenha ativado esse recurso em seu cluster. O recurso permite que o cluster defina explicitamente a ordem dos pods durante o desligamento gradual do nó com base em classes de prioridade.
O recurso Desligamento Gradual do Nó, conforme descrito acima, desliga pods em duas fases, pods não críticos, seguidos por pods críticos. Se for necessária flexibilidade adicional para definir explicitamente a ordem dos pods durante o desligamento de uma maneira mais granular, o desligamento gradual baseado na prioridade do pod pode ser usado.
Quando o desligamento gradual do nó respeita as prioridades do pod, isso torna possível fazer o desligamento gradual do nó em várias fases, cada fase encerrando uma classe de prioridade específica de pods. O kubelet pode ser configurado com as fases exatas e o tempo de desligamento por fase.
Assumindo as seguintes classes de prioridade de pod personalizadas em um cluster,
Nome das classes de prioridade
Valor das classes de prioridade
custom-class-a
100000
custom-class-b
10000
custom-class-c
1000
regular/unset
0
Na configuração do kubelet, as configurações para shutdownGracePeriodByPodPriority são semelhantes a:
Valor das classes de prioridade
Tempo de desligamento
100000
10 segundos
10000
180 segundos
1000
120 segundos
0
60 segundos
A configuração correspondente do YAML do kubelet seria:
A tabela acima implica que qualquer pod com valor priority >= 100000 terá apenas 10 segundos para parar qualquer pod com valor >= 10000 e < 100000 e terá 180 segundos para parar, qualquer pod com valor >= 1000 e < 10000 terá 120 segundos para parar. Finalmente, todos os outros pods terão 60 segundos para parar.
Não é preciso especificar valores correspondentes para todas as classes. Por exemplo, você pode usar estas configurações:
Valor das classes de prioridade
Tempo de desligamento
100000
300 segundos
1000
120 segundos
0
60 segundos
No caso acima, os pods com custom-class-b irão para o mesmo bucket que custom-class-c para desligamento.
Se não houver pods em um intervalo específico, o kubelet não irá espera por pods nesse intervalo de prioridades. Em vez disso, o kubelet pula imediatamente para o próximo intervalo de valores da classe de prioridade.
Se esse recurso estiver ativado e nenhuma configuração for fornecida, nenhuma ação de pedido será tomada.
O uso desse recurso requer ativar os recursos GracefulNodeShutdownBasedOnPodPriority e definir o ShutdownGracePeriodByPodPriority da configuração do kubelet para a configuração desejada, contendo os valores da classe de prioridade do pod e seus respectivos períodos de desligamento.
Gerenciamento da memória swap
ESTADO DA FUNCIONALIDADE:Kubernetes v1.22 [alpha]
Antes do Kubernetes 1.22, os nós não suportavam o uso de memória swap, e um kubelet, por padrão, não iniciaria se a troca fosse detectada em um nó. A partir de 1.22, o suporte a memória swap pode ser ativado por nó.
Para ativar a troca em um nó, o recursos NodeSwap deve estar ativado no kubelet, e a configuração de comando de linha --fail-swap-on ou failSwapOn deve ser definida como falsa.
Aviso:
Quando o recurso de memória swap está ativado, os dados do Kubernetes, como o conteúdo de objetos Secret que foram gravados no tmpfs, agora podem ser trocados para o disco.
Opcionalmente, um usuário também pode configurar memorySwap.swapBehavior para especificar como um nó usará memória swap. Por exemplo,
memorySwap:swapBehavior:LimitedSwap
As opções de configuração disponíveis para swapBehavior são:
LimitedSwap: As cargas de trabalho do Kubernetes são limitadas na quantidade de troca que podem usar. Cargas de trabalho no nó não gerenciadas pelo Kubernetes ainda podem ser trocadas.
UnlimitedSwap: As cargas de trabalho do Kubernetes podem usar tanta memória de swap quanto solicitarem, até o limite do sistema.
Se a configuração do memorySwap não for especificada e o recurso estiver ativado, por padrão, o kubelet aplicará o mesmo comportamento que a configuração LimitedSwap.
O comportamento da configuração LimitedSwap depende se o nó estiver sendo executado com v1 ou v2 de grupos de controle (também conhecidos como "cgroups"):
cgroupsv1: As cargas de trabalho do Kubernetes podem usar qualquer combinação de memória e swap, até o limite de memória do pod, se definido.
cgroupsv2: As cargas de trabalho do Kubernetes não podem usar memória swap.
Para obter mais informações e para ajudar nos testes e fornecer feedback, consulte KEP-2400 e sua proposta de design.
Este documento cataloga os caminhos de comunicação entre o control plane (o
apiserver) e o cluster Kubernetes. A intenção é permitir que os usuários
personalizem sua instalação para proteger a configuração de rede
então o cluster pode ser executado em uma rede não confiável (ou em IPs totalmente públicos em um
provedor de nuvem).
Nó para o Control Plane
Todos os caminhos de comunicação do cluster para o control plane terminam no
apiserver (nenhum dos outros componentes do control plane são projetados para expor
Serviços remotos). Em uma implantação típica, o apiserver é configurado para escutar
conexões remotas em uma porta HTTPS segura (443) com uma ou mais clientes autenticação habilitado.
Uma ou mais formas de autorização
deve ser habilitado, especialmente se requisições anônimas
ou tokens da conta de serviço
são autorizados.
Os nós devem ser provisionados com o certificado root público para o cluster
de tal forma que eles podem se conectar de forma segura ao apiserver junto com o cliente válido
credenciais. Por exemplo, em uma implantação padrão do GKE, as credenciais do cliente
fornecidos para o kubelet estão na forma de um certificado de cliente. Vejo
bootstrapping TLS do kubelet
para provisionamento automatizado de certificados de cliente kubelet.
Os pods que desejam se conectar ao apiserver podem fazê-lo com segurança, aproveitando
conta de serviço para que o Kubernetes injetará automaticamente o certificado raiz público
certificado e um token de portador válido no pod quando ele é instanciado.
O serviço kubernetes (no namespace default) é configurado com um IP virtual
endereço que é redirecionado (via kube-proxy) para o endpoint com HTTPS no
apiserver.
Os componentes do control plane também se comunicam com o apiserver do cluster através da porta segura.
Como resultado, o modo de operação padrão para conexões do cluster
(nodes e pods em execução nos Nodes) para o control plane é protegido por padrão
e pode passar por redes não confiáveis e/ou públicas.
Control Plane para o nó
Existem dois caminhos de comunicação primários do control plane (apiserver) para os nós.
O primeiro é do apiserver para o processo do kubelet que é executado em
cada nó no cluster. O segundo é do apiserver para qualquer nó, pod,
ou serviço através da funcionalidade de proxy do apiserver.
apiserver para o kubelet
As conexões do apiserver ao kubelet são usadas para:
Buscar logs para pods.
Anexar (através de kubectl) pods em execução.
Fornecer a funcionalidade de encaminhamento de porta do kubelet.
Essas conexões terminam no endpoint HTTPS do kubelet. Por padrão,
o apiserver não verifica o certificado de serviço do kubelet,
o que torna a conexão sujeita a ataques man-in-the-middle, o que o torna
inseguro para passar por redes não confiáveis e / ou públicas.
Para verificar essa conexão, use a flag --kubelet-certificate-authority para
fornecer o apiserver com um pacote de certificado raiz para usar e verificar o
certificado de serviço da kubelet.
Se isso não for possível, use o SSH túnel
entre o apiserver e kubelet se necessário para evitar a conexão ao longo de um
rede não confiável ou pública.
As conexões a partir do apiserver para um nó, pod ou serviço padrão para simples
conexões HTTP não são autenticadas nem criptografadas. Eles
podem ser executados em uma conexão HTTPS segura prefixando https: no nó,
pod, ou nome do serviço no URL da API, mas eles não validarão o certificado
fornecido pelo ponto de extremidade HTTPS, nem fornece credenciais de cliente, enquanto
a conexão será criptografada, não fornecerá nenhuma garantia de integridade.
Estas conexões não são atualmente seguras para serem usados por redes não confiáveis e/ou públicas.
SSH Túnel
O Kubernetes suporta túneis SSH para proteger os caminhos de comunicação do control plane para os nós. Nesta configuração, o apiserver inicia um túnel SSH para cada nó
no cluster (conectando ao servidor ssh escutando na porta 22) e passa
todo o tráfego destinado a um kubelet, nó, pod ou serviço através do túnel.
Este túnel garante que o tráfego não seja exposto fora da rede aos quais
os nós estão sendo executados.
Atualmente, os túneis SSH estão obsoletos, portanto, você não deve optar por usá-los, a menos que saiba o que está fazendo. O serviço Konnectivity é um substituto para este canal de comunicação.
Konnectivity service
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [beta]
Como uma substituição aos túneis SSH, o serviço Konnectivity fornece proxy de nível TCP para a comunicação do control plane para o cluster. O serviço Konnectivity consiste em duas partes: o servidor Konnectivity na rede control plane e os agentes Konnectivity na rede dos nós. Os agentes Konnectivity iniciam conexões com o servidor Konnectivity e mantêm as conexões de rede. Depois de habilitar o serviço Konnectivity, todo o tráfego do control plane para os nós passa por essas conexões.
O conceito do Cloud Controller Manager (CCM) (não confundir com o binário) foi originalmente criado para permitir que o código específico de provedor de nuvem e o núcleo do Kubernetes evoluíssem independentemente um do outro. O Cloud Controller Manager é executado junto com outros componentes principais, como o Kubernetes controller manager, o servidor de API e o scheduler. Também pode ser iniciado como um addon do Kubernetes, caso em que é executado em cima do Kubernetes.
O design do Cloud Controller Manager é baseado em um mecanismo de plug-in que permite que novos provedores de nuvem se integrem facilmente ao Kubernetes usando plug-ins. Existem planos para integrar novos provedores de nuvem no Kubernetes e para migrar provedores de nuvem que estão utilizando o modelo antigo para o novo modelo de CCM.
Este documento discute os conceitos por trás do Cloud Controller Manager e fornece detalhes sobre suas funções associadas.
Aqui está a arquitetura de um cluster Kubernetes sem o Cloud Controller Manager:
Projeto de Arquitetura (Design)
No diagrama anterior, o Kubernetes e o provedor de nuvem são integrados através de vários componentes diferentes:
Kubelet
Kubernetes controller manager
Kubernetes API server
O CCM consolida toda a lógica que depende da nuvem dos três componentes anteriores para criar um único ponto de integração com a nuvem. A nova arquitetura com o CCM se parece com isso:
Componentes do CCM
O CCM separa algumas das funcionalidades do KCM (Kubernetes Controller Manager) e o executa como um processo separado. Especificamente, isso elimina os controladores no KCM que dependem da nuvem. O KCM tem os seguintes loops de controlador dependentes de nuvem:
Node controller
Volume controller
Route controller
Service controller
Na versão 1.9, o CCM executa os seguintes controladores da lista anterior:
Node controller
Route controller
Service controller
Nota:
O Volume Controller foi deliberadamente escolhido para não fazer parte do CCM. Devido à complexidade envolvida e devido aos esforços existentes para abstrair a lógica de volume específica do fornecedor, foi decidido que o Volume Controller não será movido para o CCM.
O plano original para suportar volumes usando o CCM era usar volumes Flex para suportar volumes plugáveis. No entanto, um esforço concorrente conhecido como CSI está sendo planejado para substituir o Flex.
Considerando essas dinâmicas, decidimos ter uma medida de intervalo intermediário até que o CSI esteja pronto.
Funções do CCM
O CCM herda suas funções de componentes do Kubernetes que são dependentes de um provedor de nuvem. Esta seção é estruturada com base nesses componentes.
1. Kubernetes Controller Manager
A maioria das funções do CCM é derivada do KCM. Conforme mencionado na seção anterior, o CCM executa os seguintes ciclos de controle:
Node Controller
Route Controller
Service Controller
Node Controller
O Node Controller é responsável por inicializar um nó obtendo informações sobre os nós em execução no cluster do provedor de nuvem. O Node Controller executa as seguintes funções:
Inicializar um node com labels de região/zona específicos para a nuvem.
Inicialize um node com detalhes de instância específicos da nuvem, por exemplo, tipo e tamanho.
Obtenha os endereços de rede e o nome do host do node.
No caso de um node não responder, verifique a nuvem para ver se o node foi excluído da nuvem.
Se o node foi excluído da nuvem, exclua o objeto Node do Kubernetes.
Route Controller
O Route Controller é responsável por configurar as rotas na nuvem apropriadamente, de modo que os contêineres em diferentes nodes no cluster do Kubernetes possam se comunicar entre si. O Route Controller é aplicável apenas para clusters do Google Compute Engine.
Service controller
O Service controller é responsável por ouvir os eventos de criação, atualização e exclusão do serviço. Com base no estado atual dos serviços no Kubernetes, ele configura os balanceadores de carga da nuvem (como o ELB, o Google LB ou o Oracle Cloud Infrastrucutre LB) para refletir o estado dos serviços no Kubernetes. Além disso, garante que os back-ends de serviço para balanceadores de carga da nuvem estejam atualizados.
2. Kubelet
O Node Controller contém a funcionalidade dependente da nuvem do kubelet. Antes da introdução do CCM, o kubelet era responsável por inicializar um nó com detalhes específicos da nuvem, como endereços IP, rótulos de região / zona e informações de tipo de instância. A introdução do CCM mudou esta operação de inicialização do kubelet para o CCM.
Nesse novo modelo, o kubelet inicializa um nó sem informações específicas da nuvem. No entanto, ele adiciona uma marca (taint) ao nó recém-criado que torna o nó não programável até que o CCM inicialize o nó com informações específicas da nuvem. Em seguida, remove essa mancha (taint).
Mecanismo de plugins
O Cloud Controller Manager usa interfaces Go para permitir implementações de qualquer nuvem a ser conectada. Especificamente, ele usa a Interface CloudProvider definidaaqui.
A implementação dos quatro controladores compartilhados destacados acima, e algumas estruturas que ficam junto com a interface compartilhada do provedor de nuvem, permanecerão no núcleo do Kubernetes. Implementações específicas para provedores de nuvem serão construídas fora do núcleo e implementarão interfaces definidas no núcleo.
Esta seção divide o acesso necessário em vários objetos da API pelo CCM para executar suas operações.
Node Controller
O Node Controller só funciona com objetos Node. Ele requer acesso total para obter, listar, criar, atualizar, corrigir, assistir e excluir objetos Node.
v1/Node:
Get
List
Create
Update
Patch
Watch
Delete
Rote Controller
O Rote Controller escuta a criação do objeto Node e configura as rotas apropriadamente. Isso requer acesso a objetos Node.
v1/Node:
Get
Service Controller
O Service Controller escuta eventos de criação, atualização e exclusão de objeto de serviço e, em seguida, configura pontos de extremidade para esses serviços de forma apropriada.
Para acessar os Serviços, é necessário listar e monitorar o acesso. Para atualizar os Serviços, ele requer patch e atualização de acesso.
Para configurar endpoints para os Serviços, é necessário acesso para criar, listar, obter, assistir e atualizar.
v1/Service:
List
Get
Watch
Patch
Update
Outros
A implementação do núcleo do CCM requer acesso para criar eventos e, para garantir a operação segura, requer acesso para criar ServiceAccounts.
Voce vai encontrar instruções completas para configurar e executar o CCM
aqui.
4 - Controladores
Em robótica e automação um control loop, ou em português ciclo de controle, é
um ciclo não terminado que regula o estado de um sistema.
Um exemplo de ciclo de controle é um termostato de uma sala.
Quando você define a temperatura, isso indica ao termostato
sobre o seu estado desejado. A temperatura ambiente real é o
estado atual. O termostato atua de forma a trazer o estado atual
mais perto do estado desejado, ligando ou desligando o equipamento.
No Kubernetes, controladores são ciclos de controle que observam o estado do seu
cluster, e então fazer ou requisitar
mudanças onde necessário.
Cada controlador tenta mover o estado atual do cluster mais perto do estado desejado.
Padrão Controlador (Controller pattern)
Um controlador rastreia pelo menos um tipo de recurso Kubernetes.
Estes objetos
têm um campo spec que representa o estado desejado.
O(s) controlador(es) para aquele recurso são responsáveis por trazer o estado atual
mais perto do estado desejado.
O controlador pode executar uma ação ele próprio, ou,
o que é mais comum, no Kubernetes, o controlador envia uma mensagem para o
API server (servidor de API) que tem
efeitos colaterais úteis. Você vai ver exemplos disto abaixo.
Controlador via API server
O controlador Job é um exemplo de um
controlador Kubernetes embutido. Controladores embutidos gerem estados através da
interação com o cluster API server.
Job é um recurso do Kubernetes que é executado em um
Pod, ou talvez vários Pods, com o objetivo de
executar uma tarefa e depois parar.
(Uma vez agendado, objetos Pod passam a fazer parte
do estado desejado para um kubelet.
Quando o controlador Job observa uma nova tarefa ele garante que,
algures no seu cluster, os kubelets num conjunto de nós (Nodes) estão correndo o número
correto de Pods para completar o trabalho.
O controlador Job não corre Pods ou containers ele próprio.
Em vez disso, o controlador Job informa o API server para criar ou remover Pods.
Outros componentes do plano de controle
(control plane)
atuam na nova informação (existem novos Pods para serem agendados e executados),
e eventualmente o trabalho é feito.
Após ter criado um novo Job, o estado desejado é que esse Job seja completado.
O controlador Job faz com que o estado atual para esse Job esteja mais perto do seu
estado desejado: criando Pods que fazem o trabalho desejado para esse Job para que
o Job fique mais perto de ser completado.
Controladores também atualizam os objetos que os configuram.
Por exemplo: assim que o trabalho de um Job está completo,
o controlador Job atualiza esse objeto Job para o marcar como Finished (terminado).
(Isto é um pouco como alguns termostatos desligam uma luz para
indicar que a temperatura da sala está agora na temperatura que foi introduzida).
Controle direto
Em contraste com Job, alguns controladores necessitam de efetuar
mudanças fora do cluster.
Por exemplo, se usar um ciclo de controle para garantir que existem
Nodes suficientes
no seu cluster, então esse controlador necessita de algo exterior ao
cluster atual para configurar novos Nodes quando necessário.
Controladores que interagem com estados externos encontram o seu estado desejado
a partir do API server, e então comunicam diretamente com o sistema externo para
trazer o estado atual mais próximo do desejado.
Kubernetes tem uma visão cloud-native de sistemas e é capaz de manipular
mudanças constantes.
O seu cluster pode mudar em qualquer momento à medida que as ações acontecem e
os ciclos de controle corrigem falhas automaticamente. Isto significa que,
potencialmente, o seu cluster nunca atinge um estado estável.
Enquanto os controladores no seu cluster estiverem rodando e forem capazes de
fazer alterações úteis, não importa se o estado é estável ou se é instável.
Design
Como um princípio do seu desenho, o Kubernetes usa muitos controladores onde cada
um gerencia um aspecto particular do estado do cluster. Comumente, um particular
ciclo de controle (controlador) usa uma espécie de recurso como o seu estado desejado,
e tem uma espécie diferente de recurso que o mesmo gere para garantir que esse estado desejado
é cumprido.
É útil que haja controladores simples em vez de um conjunto monolítico de ciclos de controle
que estão interligados. Controladores podem falhar, então o Kubernetes foi desenhado para
permitir isso.
Por exemplo: um controlador de Jobs rastreia objetos Job (para
descobrir novos trabalhos) e objetos Pod (para correr o Jobs, e então
ver quando o trabalho termina). Neste caso outra coisa cria os Jobs,
enquanto o controlador Job cria Pods.
Nota:
Podem existir vários controladores que criam ou atualizam a mesma espécie (kind) de objeto.
Atrás das cortinas, os controladores do Kubernetes garantem que eles apenas tomam
atenção aos recursos ligados aos seus recursos controladores.
Por exemplo, você pode ter Deployments e Jobs; ambos criam Pods.
O controlador de Job não apaga os Pods que o seu Deployment criou,
porque existe informação (labels)
que os controladores podem usar para diferenciar esses Pods.
Formas de rodar controladores
O Kubernetes vem com um conjunto de controladores embutidos que correm
dentro do kube-controller-manager.
Estes controladores embutidos providenciam comportamentos centrais importantes.
O controlador Deployment e o controlador Job são exemplos de controladores
que veem como parte do próprio Kubernetes (controladores "embutidos").
O Kubernetes deixa você correr o plano de controle resiliente, para que se qualquer
um dos controladores embutidos falhar, outra parte do plano de controle assume
o trabalho.
Pode encontrar controladores fora do plano de controle, para extender o Kubernetes.
Ou, se quiser, pode escrever um novo controlador você mesmo.
Pode correr o seu próprio controlador como um conjunto de Pods,
ou externo ao Kubernetes. O que encaixa melhor vai depender no que esse
controlador faz em particular.