Diretrizes para criar clusters escalonáveis

Neste documento, fornecemos orientação para ajudar a decidir como criar, configurar e operar clusters do GKE, que são capazes de acomodar cargas de trabalho que se aproximam dos limites do Kubernetes conhecidos.

O que é escalonabilidade?

Em um cluster do Kubernetes, escalonabilidade refere-se à capacidade do cluster em crescer mantendo-se dentro de seus objetivos de nível de serviço (SLOs, na sigla em inglês). O Kubernetes também tem seu próprio conjunto de SLOs (conteúdo dos links em inglês).

O Kubernetes é um sistema complexo, e a capacidade de escalonamento dele é determinada por vários fatores. Alguns desses fatores incluem o tipo e número de nós em um pool de nós, os tipos e números de pools de nós, o número de pods disponíveis, como os recursos são alocados aos pods e o número de serviços ou back-ends por trás de um serviço.

Como preparar para maior disponibilidade

Como escolher um plano de controle regional ou zonal

Devido às diferenças de arquitetura, os clusters regionais são mais adequados para alta disponibilidade. Os clusters regionais têm vários nós mestres em várias zonas de computação em uma região, enquanto os clusters zonais têm um nó mestre em uma única zona de computação.

Se for feito o upgrade de um cluster zonal, até que o upgrade seja concluído a VM principal individual passará por um tempo de inatividade, em que a API Kubernetes não estará disponível.

Em clusters regionais, o plano de controle permanece disponível durante manutenções do cluster, como rotação de IPs, upgrade de VMs mestres ou redimensionamento de clusters ou pools de nós. Ao fazer upgrade de um cluster regional, duas das três VMs mestres estarão em execução durante a implementação do upgrade, por isso a API Kubernetes ainda estará disponível. Da mesma forma, uma interrupção de zona única não causará inatividade no plano de controle regional.

No entanto, os clusters regionais mais disponíveis vêm com algumas contrapartidas:

  • As alterações na configuração do cluster demoram mais porque precisam ser propagadas entre todos os mestres em um cluster regional, em vez do plano de controle único em clusters zonais.

  • Talvez não seja possível criar ou fazer upgrade de clusters regionais com a mesma frequência que clusters zonais. Se não for possível criar VMs em uma das zonas, seja por falta de capacidade ou por outro problema temporário, não será possível criar ou fazer o upgrade de clusters.

Devido a essas contrapartidas, os clusters locais e regionais têm diferentes casos de uso:

  • Use clusters zonais para criar ou atualizar clusters rapidamente quando a disponibilidade não for um problema.
  • Use clusters regionais quando disponibilidade for mais importante do que flexibilidade.

Selecione cuidadosamente o tipo de cluster a ser criado, porque não será possível alterá-lo depois de sua criação. Se necessário, crie um novo cluster e, em seguida, migre o tráfego para ele. Migrar o tráfego de produção entre clusters é possível, mas difícil em escala.

Como escolher pools de nós zonais ou de várias zonas

Para conseguir alta disponibilidade, o plano de controle do Kubernetes e seus nós precisam estar espalhados por diferentes zonas. O GKE oferece dois tipos de pools de nós: zonal e multizonal.

Para implantar um aplicativo altamente disponível, use pools de nó multizonais, que distribuem nós uniformemente em todas as zonas, para distribuir a carga de trabalho em várias zonas de computação em uma região.

Se todos os nós estiverem na mesma zona, não será possível agendar pods se essa zona ficar inacessível. O uso de pools de nós de várias zonas tem certas contrapartidas:

  • Problemas intermitentes de rede entre zonas são outro modo de falha a ser considerado. O aplicativo precisa ser projetado para funcionar se alguns nós não conseguirem se comunicar com outros.

  • GPUs estão disponíveis apenas em zonas específicas. Talvez não seja possível obtê-los em todas as zonas da região.

Espera-se que a latência de ida e volta entre os locais dentro de uma única região fique abaixo de 1 ms no percentil 95. A diferença na latência de tráfego entre o tráfego zonal e interzonal deve ser insignificante. O preço do tráfego de saída entre zonas na mesma região está disponível na página de preços do Compute Engine.

Como se preparar para escalonar

Infraestrutura base

As cargas de trabalho do Kubernetes exigem rede, computação e armazenamento. É necessário fornecer CPU e memória suficientes para executar pods. No entanto, existem mais parâmetros de infraestrutura subjacente que podem influenciar o desempenho e a escalonabilidade de um cluster do GKE.

Rede de cluster

O GKE oferece dois tipos de rede do cluster: o mais antigo baseado em rotas e o mais recente, nativo de VPC (em inglês).

  • Cluster baseado em rotas: cada vez que um nó é adicionado, uma rota personalizada é adicionada à tabela de roteamento na rede VPC.

  • Cluster nativo de VPC: neste modo, a rede VPC tem um intervalo secundário para todos os endereços IP do pod. Cada nó recebe uma fatia do intervalo secundário para seus próprios endereços IP do pod. Isso permite que a rede VPC compreenda nativamente como encaminhar o tráfego para pods sem depender de rotas personalizadas. Uma única rede VPC pode ter até 15.000 VMs conectadas. Assim, efetivamente, um cluster nativo de VPC dimensiona-se para 5.000 nós.

Como gerenciar IPs em clusters nativos de VPC

Um cluster nativo de VPC usa o intervalo de IP principal para nós e dois intervalos de IP secundários para pods e serviços. O número máximo de nós em clusters nativos de VPC (em inglês) pode ser limitado por endereços IP disponíveis. O número de nós é determinado pelo intervalo primário (sub-rede do nó) e pelo intervalo secundário (sub-rede do pod). O número máximo de pods e serviços é determinado pelo tamanho dos intervalos secundários do cluster (em inglês), pela sub-rede de pod e pela sub-rede de serviço, respectivamente.

Por padrão:

  • O intervalo secundário do pod é padronizado como /14 (262.144 endereços IP).
  • Cada nó tem o intervalo /24 atribuído para os pods dele (256 endereços IP para os pods).
  • A sub-rede do nó é /20 (4.092 endereços IP).

No entanto, é necessário haver endereços suficientes em ambos os intervalos (nó e pod) para aprovisionar um novo nó. Usando padrões, apenas 1.024 podem ser criados devido ao número de IPs de pod.

Por padrão, pode haver um máximo de 110 pods por nó, e cada nó no cluster alocou o intervalo /24 para seus pods. Isso resulta em 256 IPs de pod por nó. Tendo aproximadamente o dobro de endereços IP disponíveis, o Kubernetes é capaz de mitigar a reutilização de endereços IP à medida que os pods são adicionados e removidos dos nós. No entanto, para alguns aplicativos que planejam programar um número menor de pods por nó, isso é um pouco desnecessário. O recurso CIDR de pod flexível (em inglês) permite que o tamanho do bloco CIDR por nó de pods possa ser configurado e usar menos endereços IP.

Por padrão, o intervalo secundário de serviços é definido como /20 (4.096 endereços IP), limitando o número de serviços no cluster a 4.096.

Como configurar nós para melhorar o desempenho

Os nós do GKE são máquinas virtuais do GCP normais. Alguns de seus parâmetros como, por exemplo, o número de núcleos ou o tamanho do disco, podem influenciar o desempenho dos clusters do GKE.

Tráfego de saída

No GCP, o número de núcleos alocados à instância determina a capacidade de rede dela. Um núcleo virtual fornece largura de banda de saída de 2 Gbps. A largura de banda máxima é de 16 Gbps, ou 32 Gbps em máquinas Skylake (recurso beta). Todos os tipos de máquina com núcleo compartilhado estão limitados a 1 Gbps.

IOPS e capacidade de disco

No GCP, o tamanho dos discos permanentes determina a IOPS e a capacidade do disco. Normalmente, o GKE usa discos permanentes como discos de inicialização e suporte aos volumes permanentes do Kubernetes. Aumentar o tamanho do disco aumenta a IOPS e a capacidade, até certos limites.

Cada operação de gravação de disco permanente contribui para o limite de saída de rede cumulativo da instância da máquina virtual. Assim, o desempenho de IOPS de discos, especialmente SSDs, também depende do número de vCPUs na instância, além do tamanho do disco. As VMs de núcleo inferior têm limites de IOPS de gravação mais baixos devido às limitações de saída de rede na capacidade de gravação.

Se a instância de máquina virtual não tiver CPUs suficientes, o aplicativo não será capaz de chegar perto do limite de IOPS. Como regra geral, é necessária uma CPU disponível para cada 2.000 a 2.500 IOPS de tráfego esperado.

Cargas de trabalho que exigem alta capacidade ou grande quantidade de discos precisam considerar os limites de quantos DPs podem ser anexados a uma única VM. Para VMs regulares, esse limite é de 128 discos com um tamanho total de 64 TB, enquanto VMs de núcleo compartilhado têm um limite de 16 DPs, com um tamanho total de 3 TB. Esse limite é aplicado pelo GCP, e não pelo Kubernetes.

Como entender os limites

O Kubernetes, como qualquer outro sistema, tem limites que precisam ser considerados ao projetar aplicativos e planejar o crescimento.

O Kubernetes suporta até 5.000 nós em um único cluster. No entanto, o Kubernetes é um sistema complexo com uma grande gama de recursos. O número de nós é apenas uma entre muitas dimensões em que o Kubernetes pode ser escalonado. Outras dimensões incluem o número total de pods, serviços ou back-ends por trás de um serviço.

Você não deve estender mais de uma dimensão ao mesmo tempo. Esse estresse pode causar problemas mesmo em clusters menores.

Por exemplo, tentar agendar 100 pods por nó em um cluster de 5.000 nós provavelmente não será bem-sucedido porque o número de pods, o número de pods por nó e o número de nós estariam sendo muito estendidos.

Limites de dimensão

Leia a lista oficial dos limites do Kubernetes (em inglês).

Nem essa lista nem os exemplos abaixo formam uma relação completa dos limites do Kubernetes. Esses números são obtidos usando um cluster simples do Kubernetes sem extensões instaladas. Estender clusters do Kubernetes com webhooks ou CRDs é comum, mas pode restringir sua capacidade de escalonar o cluster.

A maioria desses limites não é aplicada, logo é possível ir além deles. Exceder os limites não tornará o cluster instantaneamente inutilizável. O desempenho é degradado (às vezes mostrado por SLOs falhos) antes da falha. Além disso, alguns dos limites são descritos para o maior cluster possível. Em clusters menores, os limites são proporcionalmente inferiores.

  • Número de pods por nó. O GKE tem um limite absoluto de 110 pods por nó. Isso pressupõe uma média de dois ou menos contêineres por pod. Ter muitos contêineres pode reduzir o limite de 110 porque alguns recursos são alocados por contêiner.

  • O número total de serviços precisa ficar abaixo de 10.000. O desempenho do iptables degrada se houver muitos serviços ou um grande número de back-ends por trás de um serviço.

  • O número de pods por trás de um único serviço será seguro se mantido abaixo de 250. O Kube-proxy é executado em cada nó e assiste a todas as alterações nos endpoints e serviços. Portanto, quanto maior for o cluster, mais dados serão enviados. O limite absoluto é de aproximadamente 5.000, dependendo do tamanho dos nomes dos pods e dos namespaces deles. Se forem mais longos, mais bytes serão armazenados no etcd, onde o objeto Endpoint excede o tamanho máximo da linha do etcd. Se houver mais tráfego de back-end, as atualizações se tornarão grandes, especialmente em clusters grandes (com mais de 500 nós). É possível ultrapassar um pouco esse número, desde que o desligamento de pods por trás do serviço seja mantido no mínimo ou o tamanho do cluster seja mantido pequeno.

  • O número de serviços por namespace não deve exceder 5.000. Depois disso, o número de variáveis de ambiente do serviço ultrapassa os limites do shell, fazendo com que os pods travem na inicialização. No Kubernetes 1.13 é possível optar por não ter essas variáveis povoadas, definindo enableServiceLinks em PodSpec como falso.

  • Número total de objetos. Há um limite de objetos em um cluster, integrados e CRDs. Isso depende do tamanho deles (quantos bytes são armazenados no etcd), da frequência em que eles mudam e dos padrões de acesso (por exemplo, a leitura frequente de todos os objetos de um determinado tipo esgotaria o etcd muito mais rápido).

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Kubernetes Engine