Eu tenho uma carga de trabalho bastante cara que alguns colegas precisam executar às vezes durante a semana (não em nenhum tipo de cronograma definido). Eu uso o Google Cloud Kubernetes.
Ele consiste em três statefulsets, cada um com uma réplica.
Eu os instruí sobre como "ligar" e "desligar". Para ativá-lo, eles dimensionam cada statefulset para 1 réplica. Para desativá-lo, eles dimensionam cada statefulset para 0 réplicas.
Originalmente, eu tinha um único pool de nós de escalonamento automático com um tamanho padrão de três nós (os statefulsets consomem quase um nó inteiro de CPU e RAM). Observei que, mesmo depois de reduzir para 0, pelo menos um (e às vezes dois) nós permaneceriam após uma ou duas horas. Eu esperava que eventualmente todos os nós morressem, mas isso não acontece.
Percebi que os nós em execução ainda tinham alguns pods, apenas em um namespace diferente. Os pods restantes estão todos no kube-system
namespace, exceto um no custom-metrics
namespace.
Então pensei, ok - talvez haja outros serviços que o Kubernetes deseja executar mesmo quando não há cargas de trabalho/pods definidos pelo usuário. Então, criei outro pool de nós, com um único nó muito pequeno, mas adequado. Esse nó é grande o suficiente para executar tudo o que o Kubernetes relata que está sendo executado nesses default
namespaces.
Depois que o novo pool de nós estava sendo executado com um nó, continuei a redimensionar manualmente o pool de nós original para 0. Tudo bem. Eu esperava neste ponto que eu tivesse um pool de nós de "sistema" para executar kube-system
e outras coisas, e um pool de nós de "usuário" para executar minhas próprias coisas.
Então, para o meu próximo teste, desta vez eu apenas dimensionei uma réplica statefulset. Eventualmente, um nó ficou online e o pod statefulset estava em execução/pronto. Eu então reduzi para 0 novamente e esperei... e esperei... e o nó não foi embora.
O que é necessário para fazer com que o pool de nós de escalonamento automático alcance 0 nós? Claramente estou faltando algo (ou mais do que algo), mas tive dificuldade em encontrar informações sobre o que é necessário para acionar o dimensionador de nós para reduzir o tamanho de um pool de nós para 0.
Qualquer conselho é apreciado.
informação adicional
Quando olho para o que está sendo executado no nó no pool de nós, quero ir para 0, eis o que vejo
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
kube-system fluentd-gcp-v3.1.1-mfkxf 100m (0%) 1 (3%) 200Mi (0%) 500Mi (0%) 28m
kube-system kube-proxy-gke-tileperformance-pool-1-14d3671d-jl76 100m (0%) 0 (0%) 0 (0%) 0 (0%) 28m
kube-system prometheus-to-sd-htvnw 1m (0%) 3m (0%) 20Mi (0%) 20Mi (0%) 28m
Se eu tentar drain
o nó, ele reclama que eles são gerenciados via DaemonSet
, então eu poderia forçá-lo, mas obviamente estou tentando não ter que intervir manualmente de forma alguma.
Hackear
Para que o autoescalador "funcione" e reduza o tamanho para 0, adicionei temporariamente um nodeSelector
a todas as kube-system
implantações para que elas sejam atribuídas a um pool separado para kube-system
coisas. Mas tem que haver uma maneira melhor, certo?
O autoescalador não reduzirá seu pool de nós para 0.
Você pode reduzir explicitamente seu pool de nós para zero (0) com o comando:
$ gcloud container clusters resize CLUSTER_NAME --node-pool NAME_OF_THE_POOL --num-nodes 0
Mas esteja ciente de que essa abordagem terá uma desvantagem.
Imagine uma situação em que:
O Autoscaler não poderá aumentar um número de nós de zero . Não terá meios para saber se são necessários recursos adicionais. Os pods que estavam sendo executados
kube-system
nesses nós eram essenciais para determinar se outro nó é necessário.Há um artigo com caso de uso semelhante ao seu. Dê uma olhada: Medium.com: dimensione seu cluster kubernetes para quase zero com o gke autoscaler
Outra maneira de fazer isso é com orçamentos de interrupção de pods. Por favor, dê uma olhada nos recursos abaixo:
Possíveis motivos que podem impedir que o autoescalador de cluster remova um nó:
A CA não remove nós subutilizados se estiverem executando pods que não devem ser despejados
Outros possíveis motivos para não reduzir:
No GKE 1.18, meus experimentos mostram que eu teria que adicionar uma mancha de nó para que o pool de nós pudesse ser reduzido a zero: