Please enable JavaScript.
Coggle requires JavaScript to display documents.
Deep Dive Kubernetes Architeture (Scheduler) - Coggle Diagram
Deep Dive Kubernetes Architeture (Scheduler)
Scheduler
O Scheduler do Kubernetes está constantemente verificando a API server (por meio de uma solicitação Watch) para pods que não têm um nodeName, esses são pods qualificados para scheduling
O Scheduler seleciona um nó apropriado para o pod e atualiza a definição do pod com o nodeName que o Scheduler selecionou.
Depois que o nodeName é definido, o Kubelet em execução nesse nó é notificado sobre a existência do Pod (novamente por meio de uma solicitação Watch) e começa a realmente executar esse Pod nesse nó.
No caso de uso geral, você deve confiar no scheduler para tomar a decisão certa, assim como você confia no sistema operacional para encontrar um núcleo para executar seu programa quando você o inicia em uma única máquina.
Politicas de Schedulling
Predicates
Simplificando, um Predicate indica se um Pod “se encaixa” em um nó específico.
Os predicates são restrições rígidas que, se violadas, levariam a um pod que não funcionasse corretamente (ou não funcionasse) nesse nó.
Um exemplo de tal restrição é a quantidade de memória solicitada pelo Pod.
Outro exemplo de um predicate é uma consulta de label de selector de nó especificada pelo usuário, pedindo que um nó seja executado em um especifico nó
O papel dos Predicates no processo de escalonamento é agir como um Filtro, ou seja, ele “filtra” uma série de nós elegíveis de todos os nós do cluster atual.
Tipos
1. General Predicates
As regras de filtragem GeneralPredicates são responsáveis pela estratégia de scheduling mais básica. Por exemplo, PodFitsResources calcula se os recursos de CPU e memória do host são suficientes.
PodFitsHost verifica se um pod especifica um nó específico por seu nome de host. PodFitsHostPorts verifica se um Node tem portas livres (o tipo de protocolo de rede) para as portas do Pod que o Pod está solicitando. MatchNodeSelector verifica se o selector de nó de um pod corresponde aos labels do nó.
Um grupo de GeneralPredicates como o acima é a condição de filtro mais básica para o k8s examinar se um Pod pode ser executado em um Node.
Antes de o kubelet iniciar o Pod, ele realizará uma operação de admissão para uma segunda confirmação. A regra da segunda confirmação aqui é executar GeneralPredicates uma vez.
2. Volume Predicates
Esse conjunto de regras de filtragem é responsável por escalonar políticas relacionadas ao Volume persistente do container.
Exemplos: NoDiskConflict; MaxCSIVolumeCount; NoVolumeZoneConflict; CheckVolumeBinding
3. Host Predicates
Esse conjunto de regras examina principalmente se o Pod a ser escalonado atende a determinadas condições do próprio Node.
Exemplo: PodToleratesNodeTaints; NodeMemoryPressurePredicate;
4. Pod Predicates
Esse conjunto de regras se sobrepõe principalmente a GeneralPredicates.
Exemplo: PodAffinityPredicate;
Os predicates permitem que os controllers filtrem eventos antes de serem fornecidos aos EventHandlers. A filtragem é útil porque seu controller pode querer lidar apenas com tipos específicos de eventos. A filtragem também ajuda a reduzir a conversa com o API Server, pois Reconcile() é chamado apenas para eventos transformados por EventHandlers.
Predicates não são necessários para muitos operators, embora a filtragem reduza a quantidade de conversas para o API Server do Reconcile(). Eles são particularmente úteis para controllers que observam recursos em todo o cluster, ou seja, sem um namespace.
Priorities
Enquanto os Predicates indicam situações que são verdadeiras ou falsas, o pod se encaixa ou não, as priorites determinam a preferência de um nó em relação a outro
O papel de uma função de priority é pontuar o valor relativo do escalonamento de um Pod em um nó específico.
Em contraste com os Predicates, a função de priority não indica se o Pod que está sendo escalonado no nó é viável ou não, supõe-se que o Pod pode ser executado com sucesso no nó, mas, em vez disso, a função Priorities tenta julgar o valor relativo do escalonamento de um Pod nesse nó específico.
Tipos
Spreading priority
: Essa função é responsável por priorizar os nodes onde não estão presentes Pods membros do mesmo Kubernetes Service. Esse Spreading é usado para garantir a confiabilidade, pois reduz as chances de que uma falha de máquina desabilite todos os contêineres em um determinado serviço.
NodeAffinityPriority
TaintTolerationPriority
InterPodAffinityPriority
ImageLocalityPriority
: Essa função de priority pesa os nós onde a imagem já foi extraída e, portanto, o contêiner iniciará mais rapidamente em nós onde a imagem não está presente e precisará ser extraída, atrasando a inicialização do
Pod.
High level algorithm
O scheduler obtém a lista de todos os nós atualmente conhecidos e íntegros.
Para cada predicate, o scheduler avalia o predicate em relação ao nó e ao pod que está sendo escalonado. Se o nó for viável (o pod pode ser executado nele), o nó será adicionado à lista de nós possíveis para escalonamento.
Todas as priorities executam novamente contra a combinação de pod e nó. Os resultados são enviados para uma fila de priority ordenada por pontuação, com os melhores nós de pontuação no topo da fila
Todos os nós que têm a mesma pontuação (alta) são retirados da fila de priority e colocados em uma lista final
Todos esses nós são considerados totalmente idênticos e, portanto, um deles é escolhido de forma round-robin e é retornado como o nó onde o Pod deve ser escalonado. Round robin é usado em vez de escolha aleatória para garantir uma distribuição uniforme de pods entre nós idênticos.
Scheduler Conflicts
Como há um tempo de atraso entre quando um Pod é escalonado (tempo T_1 ) e quando o contêiner realmente é executado (tempo T_N ), a decisão de escalonamento pode se tornar inválida devido a outras ações durante o intervalo de tempo entre o escalonamento e a execução.
As decisões de escalonamento são ótimas apenas para um único momento, elas sempre podem se tornar piores à medida que o tempo passa e o cluster muda.
descheduler: Projeto incubado que avalia se o nó atual é o melhor para o pod atualmente, senão retira e envia para scheduler avaliar novamente.
Em casos mais graves, como avaliar se o nó tem espaço para um pod, mas no momento de criação esses recursos não existem mais. Quando o nó percebe que foi solicitado a executar um pod que não passa mais os predicates do pod e do nó, o pod é marcado como com failed
É importante entender esse comportamento de falha porque significa que não se pode confiar no Kubernetes para executar pods autônomos de maneira confiável. Sempre mantenha ele ligado a um replicaset ou deployment.