As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Computação e escalonamento automático
Como desenvolvedor, você fará estimativas sobre os requisitos de recursos do seu aplicativo, por exemplo, CPU e memória, mas se você não os estiver ajustando continuamente, eles podem ficar desatualizados, o que pode aumentar seus custos e piorar o desempenho e a confiabilidade. Ajustar continuamente os requisitos de recursos de um aplicativo é mais importante do que acertá-los na primeira vez.
As melhores práticas mencionadas abaixo ajudarão você a criar e operar cargas de trabalho com reconhecimento de custos que alcancem resultados comerciais, minimizando os custos e permitindo que sua organização maximize o retorno sobre o investimento. Uma ordem de importância de alto nível para otimizar os custos de computação do cluster é:
-
Cargas de trabalho do tamanho certo
-
Reduza a capacidade não utilizada
-
Otimize os tipos de capacidade computacional (por exemplo, Spot) e aceleradores (por exemplo) GPUs
Dimensione corretamente suas cargas de trabalho
Na maioria dos clusters EKS, a maior parte do custo vem das EC2 instâncias usadas para executar suas cargas de trabalho em contêineres. Você não conseguirá dimensionar corretamente seus recursos computacionais sem entender seus requisitos de cargas de trabalho. É por isso que é essencial que você use as solicitações e os limites apropriados e faça ajustes nessas configurações conforme necessário. Além disso, dependências, como tamanho da instância e seleção de armazenamento, podem afetar o desempenho da carga de trabalho, o que pode ter várias consequências não intencionais nos custos e na confiabilidade.
As solicitações devem estar alinhadas com a utilização real. Se as solicitações de um contêiner forem muito altas, haverá capacidade não utilizada, o que é um grande fator nos custos totais do cluster. Cada contêiner em um pod, por exemplo, aplicativo e sidecars, deve ter suas próprias solicitações e limites definidos para garantir que os limites agregados do pod sejam os mais precisos possíveis.
Utilize ferramentas como Goldilocks
Recomendamos usar o Horizontal Pod Autoscaler (HPA) para controlar quantas réplicas do seu aplicativo devem ser executadas, o Vertical Pod Autoscaler (VPA) para ajustar quantas solicitações e limites seu aplicativo precisa por réplica e um autoescalador de nós, como Karpenter
O Vertical Pod Autoscaler pode ajustar as solicitações e os limites atribuídos aos contêineres para que as cargas de trabalho funcionem de forma otimizada. Você deve executar o VPA no modo de auditoria para que ele não faça alterações automaticamente e reinicie seus pods. Ele sugerirá mudanças com base nas métricas observadas. Com quaisquer alterações que afetem as cargas de trabalho de produção, você deve analisar e testar essas alterações primeiro em um ambiente que não seja de produção, pois elas podem ter impacto na confiabilidade e no desempenho do seu aplicativo.
Reduzir o consumo
A melhor maneira de economizar dinheiro é provisionar menos recursos. Uma forma de fazer isso é ajustar as cargas de trabalho com base nos requisitos atuais. Você deve iniciar qualquer esforço de otimização de custos certificando-se de que suas cargas de trabalho definam seus requisitos e sejam escalonadas dinamicamente. Isso exigirá a obtenção de métricas de seus aplicativos e a definição de configurações, como PodDisruptionBudgets
O Horizontal Pod Autoscaler é um autoescalador flexível de carga de trabalho que pode ajustar quantas réplicas são necessárias para atender aos requisitos de desempenho e confiabilidade do seu aplicativo. Ele tem um modelo flexível para definir quando aumentar e diminuir a escala com base em várias métricas, como CPU, memória ou métricas personalizadas, por exemplo, profundidade da fila, número de conexões com um pod etc.
O Kubernetes Metrics Server permite o escalonamento em resposta a métricas integradas, como uso de CPU e memória, mas se você quiser escalar com base em outras métricas, como a profundidade da fila da Amazon CloudWatch ou do SQS, considere projetos de escalonamento automático orientados por eventos, como o KEDA.
A redução do consumo da carga de trabalho cria excesso de capacidade em um cluster e, com a configuração adequada de escalonamento automático, permite que você reduza os nós automaticamente e reduza seu gasto total. Recomendamos que você não tente otimizar a capacidade computacional manualmente. O programador Kubernetes e os autoescaladores de nós foram projetados para lidar com esse processo para você.
Reduza a capacidade não utilizada
Depois de determinar o tamanho correto dos aplicativos, reduzindo o excesso de solicitações, você pode começar a reduzir a capacidade computacional provisionada. Você deve ser capaz de fazer isso dinamicamente se tiver reservado um tempo para dimensionar corretamente suas cargas de trabalho nas seções acima. Há dois autoescaladores de nós principais usados com o Kubernetes na AWS.
Karpenter e Cluster Autoscaler
Tanto o Karpenter quanto o Kubernetes Cluster Autoscaler escalarão o número de nós em seu cluster à medida que os pods forem criados ou removidos e os requisitos de computação mudarem. O objetivo principal de ambos é o mesmo, mas a Karpenter adota uma abordagem diferente para gerenciamento, provisionamento e desprovisionamento de nós, o que pode ajudar a reduzir custos e otimizar o uso em todo o cluster.
À medida que os clusters aumentam de tamanho e a variedade de cargas de trabalho aumenta, fica mais difícil pré-configurar grupos de nós e instâncias. Assim como nas solicitações de carga de trabalho, é importante definir uma linha de base inicial e ajustá-la continuamente conforme necessário.
Se você estiver usando o Cluster Autoscaler, ele respeitará os valores “mínimo” e “máximo” de cada grupo de Auto Scaling (ASG) e ajustará somente o valor “desejado”. É importante prestar atenção ao definir esses valores para o ASG subjacente, pois o Cluster Autoscaler não conseguirá reduzir um ASG além de sua contagem “mínima”. Defina a contagem “desejada” como o número de nós necessários durante o horário comercial normal e “mínima” como o número de nós necessários fora do horário comercial. Consulte o documento de perguntas frequentes do Cluster Autoscaler
Expansor prioritário do escalador automático de cluster
O Kubernetes Cluster Autoscaler funciona escalando grupos de nós — chamados de grupo de nós — para cima e para baixo à medida que os aplicativos aumentam e diminuem a escala. Se você não estiver escalando dinamicamente as cargas de trabalho, o autoescalador de cluster não ajudará você a economizar dinheiro. O escalador automático de cluster exige que um administrador de cluster crie grupos de nós com antecedência para que as cargas de trabalho sejam consumidas. Os grupos de nós precisam ser configurados para usar instâncias que tenham o mesmo “perfil”, ou seja, aproximadamente a mesma quantidade de CPU e memória.
Você pode ter vários grupos de nós e o autoescalador de cluster pode ser configurado para definir níveis de escalabilidade prioritária, e cada grupo de nós pode conter nós de tamanhos diferentes. Os grupos de nós podem ter diferentes tipos de capacidade e o expansor prioritário pode ser usado primeiro para escalar grupos mais baratos.
Abaixo está um exemplo de um trecho de configuração de cluster que usa a ConfigMap` para priorizar a capacidade reservada antes de usar instâncias sob demanda. Você pode usar a mesma técnica para priorizar instâncias Graviton ou Spot em relação a outros tipos.
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster managedNodeGroups: - name: managed-ondemand minSize: 1 maxSize: 7 instanceType: m5.xlarge - name: managed-reserved minSize: 2 maxSize: 10 instanceType: c5.2xlarge
apiVersion: v1 kind: ConfigMap metadata: name: cluster-autoscaler-priority-expander namespace: kube-system data: priorities: |- 10: - .*ondemand.* 50: - .*reserved.*
O uso de grupos de nós pode ajudar os recursos computacionais subjacentes a fazer o esperado por padrão, por exemplo, distribuir nós entre si AZs, mas nem todas as cargas de trabalho têm os mesmos requisitos ou expectativas, e é melhor deixar que os aplicativos declarem seus requisitos explicitamente. Para obter mais informações sobre o Cluster Autoscaler, consulte a seção de melhores práticas.
Desagendador
O escalador automático de cluster pode adicionar e remover a capacidade de nós de um cluster com base na necessidade de programar novos pods ou na subutilização dos nós. Ele não tem uma visão holística do posicionamento do pod depois de ter sido programado para um nó. Se você estiver usando o autoescalador de cluster, você também deve consultar o desagendador do Kubernetes para evitar o desperdício
Se você tem 10 nós em um cluster e cada nó é 60% utilizado, você não está usando 40% da capacidade provisionada no cluster. Com o autoescalador de cluster, você pode definir o limite de utilização por nó para 60%, mas isso só tentaria reduzir um único nó depois que a utilização caísse abaixo de 60%.
Com o desagendador, ele pode analisar a capacidade e a utilização do cluster após os pods terem sido programados ou os nós terem sido adicionados ao cluster. Ele tenta manter a capacidade total do cluster acima de um limite especificado. Ele também pode remover pods com base em contaminações de nós ou em novos nós que se juntam ao cluster para garantir que os pods sejam executados em seu ambiente computacional ideal. Observe que o desagendador não agenda a substituição dos pods despejados, mas depende do agendador padrão para isso.
Consolidação Karpenter
O Karpenter adota uma abordagem “sem grupos” para o gerenciamento de nós. Essa abordagem é mais flexível para diferentes tipos de carga de trabalho e requer menos configuração inicial para administradores de cluster. Em vez de predefinir grupos e escalar cada grupo conforme a necessidade das cargas de trabalho, o Karpenter usa provisionadores e modelos de nós para definir amplamente quais tipos de EC2 instâncias podem ser criadas e configurações sobre as instâncias à medida que são criadas.
O empacotamento em compartimentos é a prática de utilizar mais recursos da instância ao empacotar mais cargas de trabalho em menos instâncias de tamanho ideal. Embora isso ajude a reduzir seus custos de computação ao provisionar apenas os recursos que suas cargas de trabalho usam, isso tem uma desvantagem. Pode levar mais tempo para iniciar novas cargas de trabalho porque a capacidade precisa ser adicionada ao cluster, especialmente durante grandes eventos de escalabilidade. Considere o equilíbrio entre otimização de custos, desempenho e disponibilidade ao configurar o empacotamento de lixo.
O Karpenter pode monitorar e agrupar continuamente para melhorar a utilização dos recursos da instância e reduzir seus custos de computação. O Karpenter também pode selecionar um nó de trabalho mais econômico para sua carga de trabalho. Isso pode ser feito ativando o sinalizador de “consolidação” como verdadeiro no provisionador (exemplo de trecho de código abaixo). O exemplo abaixo mostra um exemplo de provisionador que permite a consolidação. No momento em que escrevo este guia, o Karpenter não substituirá uma instância Spot em execução por uma instância Spot mais barata. Para obter mais detalhes sobre a consolidação do Karpenter, consulte este blog.
apiVersion: karpenter.sh/v1 kind: Provisioner metadata: name: enable-binpacking spec: consolidation: enabled: true
Para cargas de trabalho que podem não ser interrompidas, por exemplo, trabalhos em lotes de longa execução sem ponto de verificação, considere anotar pods com a anotação. do-not-evict Ao desativar o despejo dos pods, você está dizendo ao Karpenter que ele não deve remover voluntariamente os nós que contêm esse pod. No entanto, se um do-not-evict pod for adicionado a um nó enquanto o nó estiver sendo drenado, os pods restantes ainda serão despejados, mas esse pod bloqueará o encerramento até que seja removido. Em ambos os casos, o nó será isolado para evitar que trabalhos adicionais sejam agendados no nó. Abaixo está um exemplo mostrando como definir a anotação:
apiVersion: v1 kind: Pod metadata: name: label-demo labels: environment: production annotations: + "karpenter.sh/do-not-evict": "true" spec: containers: * name: nginx image: nginx ports: ** containerPort: 80
Remova nós subutilizados ajustando os parâmetros do autoescalador de cluster
A utilização do nó é definida como a soma dos recursos solicitados dividida pela capacidade. Por padrão, scale-down-utilization-threshold está definido como 50%. Esse parâmetro pode ser usado junto com escale-down-unneeded-time, que determina por quanto tempo um nó deve ser desnecessário antes de ser elegível para redução de escala — o padrão é 10 minutos. Os pods ainda em execução em um nó que foi reduzido serão programados em outros nós pelo kube-scheduler. O ajuste dessas configurações pode ajudar a remover nós que estão subutilizados, mas é importante testar esses valores primeiro para não forçar o cluster a ser reduzido prematuramente.
Você pode evitar que a redução ocorra garantindo que os pods que são caros de remover sejam protegidos por um rótulo reconhecido pelo escalador automático de cluster. Para fazer isso, certifique-se de que os pods que são caros de despejar tenham a anotação. cluster-autoscaler.kubernetes.io/safe-to-evict=false Abaixo está um exemplo de yaml para definir a anotação:
apiVersion: v1 kind: Pod metadata: name: label-demo labels: environment: production annotations: + "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" spec: containers: * name: nginx image: nginx ports: ** containerPort: 80
Marque nós com o Cluster Autoscaler e o Karpenter
As tags de recursos da AWS são usadas para organizar seus recursos e monitorar seus custos da AWS em um nível detalhado. Eles não se correlacionam diretamente com os rótulos do Kubernetes para controle de custos. É recomendável começar com a rotulagem de recursos do Kubernetes e utilizar ferramentas como o Kubecost para obter relatórios de custos de infraestrutura com base nos rótulos do Kubernetes
Os nós de trabalho precisam ter tags para mostrar informações de faturamento no AWS Cost Explorer. Com o escalador automático de cluster, marque seus nós de trabalho dentro de um grupo de nós gerenciados usando o modelo de lançamento. Para grupos de nós autogerenciados, marque suas instâncias usando o grupo de escalonamento EC2 automático. Para instâncias provisionadas pelo Karpenter, marque-as usando spec.tags
Clusters multilocatários
Ao trabalhar em clusters compartilhados por equipes diferentes, você pode não ter visibilidade de outras cargas de trabalho em execução no mesmo nó. Embora as solicitações de recursos possam ajudar a isolar algumas preocupações do “vizinho barulhento”, como o compartilhamento de CPU, elas podem não isolar todos os limites dos recursos, como a exaustão do disco. I/O Nem todo recurso consumível de uma carga de trabalho pode ser isolado ou limitado. As cargas de trabalho que consomem recursos compartilhados em taxas mais altas do que outras cargas de trabalho devem ser isoladas por meio de contaminações
Isolar cargas de trabalho em um nível de nó pode ser mais caro, mas pode ser possível agendar BestEffort
Os clusters compartilhados também podem ter restrições de recursos no nível do cluster, como exaustão de IP, limites de serviço do Kubernetes ou solicitações de escalonamento de API. Você deve revisar o guia de melhores práticas de escalabilidade para garantir que seus clusters evitem esses limites.
Você pode isolar recursos em um namespace ou no nível do provisionador Karpenter. As cotas de recursos
Os provisionadores do Karpenter podem definir limites para alguns dos recursos consumíveis
Escalonamento automático programado
Talvez você precise reduzir seus clusters nos fins de semana e fora do horário de expediente. Isso é particularmente relevante para clusters de teste e de não produção, nos quais você deseja reduzir para zero quando não estão em uso. Soluções como o cluster-turndown podem reduzir as
Otimize os tipos de capacidade computacional
Depois de otimizar a capacidade total de computação em seu cluster e utilizar o compartimento de armazenamento, você deve verificar o tipo de computação que você provisionou em seus clusters e como você paga por esses recursos. A AWS tem planos de economia de computação
-
Spot
-
Savings Plans
-
Sob demanda
-
Fargate
Cada tipo de capacidade tem diferentes vantagens e desvantagens em termos de despesas gerais de gerenciamento, disponibilidade e compromissos de longo prazo, e você precisará decidir qual é a melhor opção para seu ambiente. Nenhum ambiente deve depender de um único tipo de capacidade e você pode combinar vários tipos de execução em um único cluster para otimizar os requisitos e custos específicos da carga de trabalho.
Spot
O tipo de capacidade spot
A computação spot deve usar uma grande variedade de tipos de instância para reduzir a probabilidade de não ter capacidade spot disponível. As interrupções da instância precisam ser tratadas para desligar os nós com segurança. Os nós provisionados com o Karpenter ou parte de um grupo de nós gerenciados oferecem suporte automático às notificações de interrupção da instância. Se você estiver usando nós autogerenciados, precisará executar o manipulador de terminação de nós separadamente para encerrar
É possível equilibrar instâncias spot e sob demanda em um único cluster. Com o Karpenter, você pode criar provisionadores ponderados
Aqui está um exemplo do uso do Karpenter para priorizar as instâncias spot antes das instâncias sob demanda. Ao criar um provisionador, você pode especificar Spot, On-Demand ou ambos (conforme mostrado abaixo). Quando você especifica ambos, e se o pod não especifica explicitamente se precisa usar Spot ou On-Demand, o Karpenter prioriza o Spot ao provisionar um nó com estratégia de alocação. price-capacity-optimization
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
name: spot-prioritized
spec:
requirements:
- key: "karpenter.sh/capacity-type"
operator: In
values: ["spot", "on-demand"]
Savings Plans, Reserved Instances e AWS EDP
Você pode reduzir seus gastos com computação usando um plano de economia de computação.
O plano de economia de computação pode reduzir seu EC2 custo em até 66% sem exigir compromissos sobre quais tipos de instância, famílias ou regiões você deseja usar. As economias são aplicadas automaticamente às instâncias à medida que você as usa.
EC2 Os Instance Savings Plans oferecem até 72% de economia em computação com um compromisso de uso em uma região e EC2 família específicas, por exemplo, instâncias da família C. Você pode mudar o uso para qualquer AZ na região, usar qualquer geração da família de instâncias, por exemplo, c5 ou c6, e usar qualquer tamanho de instância dentro da família. O desconto será aplicado automaticamente a qualquer instância em sua conta que corresponda aos critérios do plano de poupança.
As instâncias reservadas
Os clientes também têm a opção de se inscrever em um contrato empresarial com a AWS. Os contratos empresariais oferecem aos clientes a opção de personalizar os contratos que melhor atendem às suas necessidades. Os clientes podem desfrutar de descontos nos preços com base no AWS EDP (Enterprise Discount Program). Para obter informações adicionais sobre contratos corporativos, entre em contato com seu representante de vendas da AWS.
Sob demanda
EC2 As instâncias sob demanda têm o benefício da disponibilidade sem interrupções — em comparação com a spot — e sem compromissos de longo prazo — em comparação com os planos de economia. Se você deseja reduzir custos em um cluster, deve reduzir o uso de EC2 instâncias sob demanda.
Depois de otimizar seus requisitos de carga de trabalho, você deve ser capaz de calcular a capacidade mínima e máxima para seus clusters. Esse número pode mudar com o tempo, mas raramente diminui. Considere usar um Savings Plan para tudo que estiver abaixo do mínimo e determine a capacidade que não afetará a disponibilidade do seu aplicativo. Qualquer outra coisa que não possa ser usada continuamente ou seja necessária para disponibilidade pode ser usada sob demanda.
Conforme mencionado nesta seção, a melhor maneira de reduzir seu uso é consumir menos recursos e utilizar os recursos que você provisiona ao máximo possível. Com o autoescalador de cluster, você pode remover nós subutilizados com a configuração. scale-down-utilization-threshold Com o Karpenter, é recomendável ativar a consolidação.
Para identificar manualmente os tipos de EC2 instância que podem ser usados com suas cargas de trabalho, você deve usar o ec2-instance-selector
ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 \ -r us-east-1 --service eks c5.large c5a.large c5ad.large c5d.large c6a.large c6i.large t2.medium t3.medium t3a.medium
Para ambientes que não sejam de produção, você pode reduzir automaticamente os clusters durante horas não utilizadas, como noites e fins de semana. O projeto kubecost cluster-turndown
Computação Fargate
A computação Fargate é uma opção de computação totalmente gerenciada para clusters EKS. Ele fornece isolamento de pods ao programar um pod por nó em um cluster Kubernetes. Ele permite que você dimensione seus nós de computação de acordo com os requisitos de CPU e RAM de sua carga de trabalho para controlar rigorosamente o uso da carga de trabalho em um cluster.
O Fargate pode escalar cargas de trabalho tão pequenas quanto 0,25 vCPU com 0,5 GB de memória e até 16 vCPU com 120 GB de memória. Há limites para quantas variações de tamanho de pod estão disponíveis e você precisará entender como sua carga de trabalho se encaixa melhor em uma configuração do Fargate. Por exemplo, se sua carga de trabalho exigir 1 vCPU com 0,5 GB de memória, o menor pod Fargate será 1 vCPU com 2 GB de memória.
Embora o Fargate tenha muitos benefícios, como o gerenciamento de nenhuma EC2 instância ou sistema operacional, ele pode exigir mais capacidade computacional do que as EC2 instâncias tradicionais, devido ao fato de que cada pod implantado é isolado como um nó separado no cluster. Isso requer mais duplicação para coisas como o Kubelet, agentes de registro e qualquer coisa DaemonSets que você normalmente implantaria em um nó. DaemonSets não são compatíveis com o Fargate e precisarão ser convertidos em pod “`sidecars"` e executados junto com o aplicativo.
O Fargate não pode se beneficiar do empacotamento de compartimentos ou do provisionamento excessivo de CPU porque o limite da carga de trabalho é um nó que não pode ser interrompido ou compartilhado entre cargas de trabalho. O Fargate economizará tempo de gerenciamento de EC2 instâncias, o que por si só tem um custo, mas os custos de CPU e memória podem ser mais caros do que outros tipos de EC2 capacidade. Os pods Fargate podem aproveitar o plano de economia de computação para reduzir o custo sob demanda.
Otimize o uso da computação
Outra forma de economizar dinheiro em sua infraestrutura computacional é usar uma computação mais eficiente para a carga de trabalho. Isso pode vir de uma computação de uso geral com maior desempenho, como os processadores Graviton
O EKS tem a capacidade de executar clusters com arquitetura mista (por exemplo, amd64 e arm64) e, se seus contêineres forem compilados para várias arquiteturas, você poderá aproveitar os processadores Graviton com o Karpenter permitindo ambas as arquiteturas em seu provisionador. Para manter um desempenho consistente, no entanto, é recomendável manter cada carga de trabalho em uma única arquitetura de computação e usar arquiteturas diferentes somente se não houver capacidade adicional disponível.
Os provisionadores podem ser configurados com várias arquiteturas e as cargas de trabalho também podem solicitar arquiteturas específicas em suas especificações de carga de trabalho.
apiVersion: karpenter.sh/v1 kind: Provisioner metadata: name: default spec: requirements: - key: "kubernetes.io/arch" operator: In values: ["arm64", "amd64"]
Com o Cluster Autoscaler, você precisará criar um grupo de nós para instâncias do Graviton e definir tolerâncias de nós em sua carga de trabalho
GPUs e FPGAs pode aumentar consideravelmente o desempenho de sua carga de trabalho, mas a carga de trabalho precisará ser otimizada para usar o acelerador. Muitos tipos de carga de trabalho para aprendizado de máquina e inteligência artificial podem ser usados GPUs para computação e instâncias podem ser adicionados a um cluster e montados em uma carga de trabalho usando solicitações de recursos.
spec: template: spec: - containers: ... resources: limits: nvidia.com/gpu: "1"
Alguns hardwares de GPU podem ser compartilhados entre várias cargas de trabalho para que uma única GPU possa ser provisionada e usada. Para ver como configurar o compartilhamento da GPU da carga de trabalho, consulte o plug-in do dispositivo de GPU virtual