Karpenter - Amazon EKS

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á.

Karpenter

O Karpenter é um projeto de código aberto que fornece gerenciamento do ciclo de vida dos nós para clusters Kubernetes. Ele automatiza o provisionamento e o desprovisionamento de nós com base nas necessidades de agendamento dos pods, permitindo escalabilidade eficiente e otimização de custos. Suas principais funções são:

  • Monitore pods que o programador do Kubernetes não pode programar devido a restrições de recursos.

  • Avalie os requisitos de agendamento (solicitações de recursos, seletores de nós, afinidades, tolerações etc.) dos pods não programáveis.

  • Provisione novos nós que atendam aos requisitos desses pods.

  • Remova os nós quando eles não forem mais necessários.

Com o Karpenter, você pode definir NodePools com restrições no provisionamento de nós, como manchas, rótulos, requisitos (tipos de instância, zonas etc.) e limites no total de recursos provisionados. Ao implantar cargas de trabalho, você pode especificar restrições de agendamento na especificação do pod, como solicitações/limites de recursos, seletores de nós, afinidades de nós/pods, tolerâncias e restrições de distribuição de topologia. O Karpenter então provisionará nós do tamanho certo para esses pods.

Razões para usar o Karpenter

Antes do lançamento do Karpenter, os usuários do Kubernetes dependiam principalmente dos grupos do Amazon Auto Scaling e do Kubernetes Cluster EC2 Autoscaler () para ajustar dinamicamente a capacidade computacional de seus clusters. CAS Com o Karpenter, você não precisa criar dezenas de grupos de nós para obter a flexibilidade e a diversidade que você obtém com o Karpenter. Além disso, o Karpenter não está tão fortemente acoplado às versões do Kubernetes (como CAS está) e não exige que você alterne entre e o Kubernetes. AWS APIs

O Karpenter consolida as responsabilidades de orquestração de instâncias em um único sistema, que é mais simples, mais estável e reconhece clusters. O Karpenter foi projetado para superar alguns dos desafios apresentados pelo Cluster Autoscaler, fornecendo maneiras simplificadas de:

  • Provisione nós com base nos requisitos da carga de trabalho.

  • Crie diversas configurações de nós por tipo de instância, usando NodePool opções flexíveis. Em vez de gerenciar muitos grupos de nós personalizados específicos, o Karpenter pode permitir que você gerencie diversas capacidades de carga de trabalho com um único e flexível. NodePool

  • Obtenha um melhor agendamento de pods em grande escala lançando nós e agendando pods rapidamente.

Para obter informações e documentação sobre o uso do Karpenter, visite o site karpenter.sh.

Recomendações

As melhores práticas são divididas em seções sobre o próprio Karpenter e o agendamento NodePools de pods.

Melhores práticas da Karpenter

As melhores práticas a seguir abrangem tópicos relacionados ao próprio Karpenter.

Use o Karpenter para cargas de trabalho com necessidades de capacidade variáveis

O Karpenter aproxima o gerenciamento de escalabilidade do Kubernetes nativo APIs do que os grupos de escalonamento automático () e os grupos de nós gerenciados ()ASGs. MNGs ASGse MNGs são abstrações AWS nativas em que o escalonamento é acionado com base em métricas AWS de nível, como carga. EC2 CPU O Cluster Autoscaler une as abstrações do Kubernetes às AWS abstrações, mas perde alguma flexibilidade por causa disso, como o agendamento para uma zona de disponibilidade específica.

O Karpenter remove uma camada de AWS abstração para trazer parte da flexibilidade diretamente para o Kubernetes. O Karpenter é melhor usado para clusters com cargas de trabalho que enfrentam períodos de alta demanda ou têm diversos requisitos de computação. MNGse ASGs são bons para clusters que executam cargas de trabalho que tendem a ser mais estáticas e consistentes. Você pode usar uma combinação de nós gerenciados de forma dinâmica e estática, dependendo dos seus requisitos.

Considere outros projetos de escalonamento automático quando...

Você precisa de recursos que ainda estão sendo desenvolvidos no Karpenter. Como o Karpenter é um projeto relativamente novo, considere outros projetos de escalonamento automático por enquanto, se você precisar de recursos que ainda não façam parte do Karpenter.

Execute o controlador Karpenter no EKS Fargate ou em um nó de trabalho que pertença a um grupo de nós

O Karpenter é instalado usando um gráfico Helm. O gráfico do Helm instala o controlador Karpenter e um pod de webhook como uma implantação que precisa ser executada antes que o controlador possa ser usado para escalar seu cluster. Recomendamos no mínimo um pequeno grupo de nós com pelo menos um nó de trabalho. Como alternativa, você pode executar esses pods no EKS Fargate criando um perfil Fargate para o namespace. karpenter Isso fará com que todos os pods implantados nesse namespace sejam executados no Fargate. EKS Não execute o Karpenter em um nó gerenciado pelo Karpenter.

Não há suporte para modelos de lançamento personalizados com o Karpenter

Não há suporte a modelos de lançamento personalizados com v1beta1 (APIsv0.32+). Você pode usar dados personalizados do usuário e/ou especificar diretamente a personalização AMIs noEC2NodeClass. Mais informações sobre como fazer isso estão disponíveis em NodeClasses.

Exclua tipos de instância que não se adequam à sua carga de trabalho

Considere excluir tipos específicos de instâncias com a chave node.kubernetes.io/instance-type se eles não forem exigidos pelas cargas de trabalho em execução no seu cluster.

O exemplo a seguir mostra como evitar o provisionamento de grandes instâncias do Graviton.

- key: node.kubernetes.io/instance-type operator: NotIn values: - m6g.16xlarge - m6gd.16xlarge - r6g.16xlarge - r6gd.16xlarge - c6g.16xlarge

Ative o tratamento de interrupções ao usar o Spot

O Karpenter suporta o tratamento nativo de interrupções e pode lidar com eventos de interrupção involuntários, como interrupções de instâncias spot, eventos de manutenção programada, eventos de terminação/parada de instâncias que podem interromper suas cargas de trabalho. Quando o Karpenter detecta esses eventos nos nós, ele automaticamente contamina, drena e encerra os nós afetados com antecedência para iniciar uma limpeza elegante das cargas de trabalho antes da interrupção. Para interrupções do Spot com 2 minutos de antecedência, o Karpenter inicia rapidamente um novo nó para que os pods possam ser movidos antes que a instância seja recuperada. Para habilitar o tratamento de interrupções, você configura o --interruption-queue CLI argumento com o nome da SQS fila provisionada para essa finalidade. Não é aconselhável usar o tratamento de interrupções do Karpenter junto com o Node Termination Handler, conforme explicado aqui.

Os pods que requerem um posto de controle ou outras formas de drenagem suave, exigindo 2 minutos antes do desligamento, devem permitir o tratamento de interrupções do Karpenter em seus clusters.

Cluster EKS privado da Amazon sem acesso externo à Internet

Ao provisionar um EKS cluster em um local VPC sem rota para a Internet, você precisa ter certeza de que configurou seu ambiente de acordo com os requisitos de cluster privado que aparecem na EKS documentação. Além disso, você precisa ter certeza de que criou um endpoint STS VPC regional no seuVPC. Caso contrário, você verá erros semelhantes aos que aparecem abaixo.

{"level":"FATAL","time":"2024-02-29T14:28:34.392Z","logger":"controller","message":"Checking EC2 API connectivity, WebIdentityErr: failed to retrieve credentials\ncaused by: RequestError: send request failed\ncaused by: Post \"https://sts.<region>.amazonaws.com/\": dial tcp 54.239.32.126:443: i/o timeout","commit":"596ea97"}

Essas alterações são necessárias em um cluster privado porque o Karpenter Controller usa IAM funções para contas de serviço ()IRSA. Pods configurados com credenciais de IRSA aquisição chamando o AWS Security Token Service () AWSSTS. API Se não houver acesso externo à Internet, você deverá criar e usar um AWSSTSVPCendpoint no seu. VPC

Os clusters privados também exigem que você crie um VPCendpoint para SSM. Quando o Karpenter tenta provisionar um novo nó, ele consulta as configurações do modelo Launch e um parâmetro. SSM Se você não tiver um SSM VPC endpoint no seuVPC, isso causará o seguinte erro:

{"level":"ERROR","time":"2024-02-29T14:28:12.889Z","logger":"controller","message":"Unable to hydrate the AWS launch template cache, RequestCanceled: request context canceled\ncaused by: context canceled","commit":"596ea97","tag-key":"karpenter.k8s.aws/cluster","tag-value":"eks-workshop"} ... {"level":"ERROR","time":"2024-02-29T15:08:58.869Z","logger":"controller.nodeclass","message":"discovering amis from ssm, getting ssm parameter \"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id\", RequestError: send request failed\ncaused by: Post \"https://ssm.<region>.amazonaws.com/\": dial tcp 67.220.228.252:443: i/o timeout","commit":"596ea97","ec2nodeclass":"default","query":"/aws/service/eks/optimized-ami/1.27/amazon-linux-2/recommended/image_id"}

Não há um VPCponto final para a consulta API da lista de preços. Como resultado, os dados de preços ficarão obsoletos com o tempo. O Karpenter contorna isso incluindo dados de preços sob demanda em seu binário, mas só atualiza esses dados quando o Karpenter é atualizado. Solicitações falhadas de dados de preços resultarão nas seguintes mensagens de erro:

{"level":"ERROR","time":"2024-02-29T15:08:58.522Z","logger":"controller.pricing","message":"retreiving on-demand pricing data, RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.196.224.8:443: i/o timeout; RequestError: send request failed\ncaused by: Post \"https://api.pricing.<region>.amazonaws.com/\": dial tcp 18.185.143.117:443: i/o timeout","commit":"596ea97"}

Consulte esta documentação para usar o Karpenter em EKS clusters completamente privados e para saber quais VPC endpoints devem ser criados.

Criando NodePools

As práticas recomendadas a seguir abrangem tópicos relacionados à criação NodePools.

Crie vários NodePools quando...

Quando equipes diferentes estiverem compartilhando um cluster e precisarem executar suas cargas de trabalho em diferentes nós de trabalho ou tiverem requisitos diferentes de sistema operacional ou tipo de instância, crie várias NodePools. Por exemplo, uma equipe pode querer usar o Bottlerocket, enquanto outra pode querer usar o Amazon Linux. Da mesma forma, uma equipe pode ter acesso a um GPU hardware caro que não seria necessário para outra equipe. O uso de vários NodePools garante que os ativos mais adequados estejam disponíveis para cada equipe.

Crie NodePools que sejam mutuamente exclusivos ou ponderados

É recomendável criar NodePools que sejam mutuamente exclusivas ou ponderadas para fornecer um comportamento de agendamento consistente. Se não estiverem e vários NodePools forem combinados, o Karpenter escolherá aleatoriamente quais usar, causando resultados inesperados. Exemplos úteis para criar vários NodePools incluem o seguinte:

Criando um NodePool com GPU e permitindo que cargas de trabalho especiais sejam executadas nesses nós (caros):

# NodePool for GPU Instances with Taints apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: gpu spec: disruption: consolidateAfter: 1m0s consolidationPolicy: WhenEmpty expireAfter: Never template: metadata: {} spec: nodeClassRef: name: default requirements: - key: node.kubernetes.io/instance-type operator: In values: - p3.8xlarge - p3.16xlarge - key: kubernetes.io/os operator: In values: - linux - key: kubernetes.io/arch operator: In values: - amd64 - key: karpenter.sh/capacity-type operator: In values: - on-demand taints: - effect: NoSchedule key: nvidia.com/gpu value: "true"

Implantação com tolerância à mancha:

# Deployment of GPU Workload will have tolerations defined apiVersion: apps/v1 kind: Deployment metadata: name: inflate-gpu spec: ... spec: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule"

Para uma implantação geral para outra equipe, a NodePool especificação pode incluirnodeAffinity. Uma implantação poderia então ser usada nodeSelectorTerms para corresponderbilling-team.

# NodePool for regular EC2 instances apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: generalcompute spec: disruption: expireAfter: Never template: metadata: labels: billing-team: my-team spec: nodeClassRef: name: default requirements: - key: node.kubernetes.io/instance-type operator: In values: - m5.large - m5.xlarge - m5.2xlarge - c5.large - c5.xlarge - c5a.large - c5a.xlarge - r5.large - r5.xlarge - key: kubernetes.io/os operator: In values: - linux - key: kubernetes.io/arch operator: In values: - amd64 - key: karpenter.sh/capacity-type operator: In values: - on-demand

Implantação usandonodeAffinity:

# Deployment will have spec.affinity.nodeAffinity defined kind: Deployment metadata: name: workload-my-team spec: replicas: 200 ... spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "billing-team" operator: "In" values: ["my-team"]

Use timers (TTL) para excluir automaticamente os nós do cluster

Você pode usar temporizadores em nós provisionados para definir quando excluir nós que estão desprovidos de pods de carga de trabalho ou que atingiram um prazo de expiração. A expiração do nó pode ser usada como um meio de atualização, para que os nós sejam retirados e substituídos por versões atualizadas. Consulte Expiração na documentação do Karpenter para obter informações sobre como usar para configurar spec.disruption.expireAfter a expiração do nó.

Evite restringir excessivamente os tipos de instância que o Karpenter pode provisionar, especialmente ao utilizar o Spot

Ao usar o Spot, a Karpenter usa a estratégia de alocação otimizada para capacidade de preço para provisionar instâncias. EC2 Essa estratégia instrui EC2 a provisionar instâncias dos pools mais profundos para o número de instâncias que você está iniciando e com o menor risco de interrupção. EC2Em seguida, o Fleet solicita instâncias spot do menor preço desses pools. Quanto mais tipos de instância você permitir que o Karpenter utilize, melhor EC2 poderá otimizar o tempo de execução da sua instância spot. Por padrão, o Karpenter usará todas as EC2 ofertas de Tipos de Instância na região e nas zonas de disponibilidade em que seu cluster está implantado. O Karpenter escolhe de forma inteligente o conjunto de todos os tipos de instância com base nos pods pendentes para garantir que seus pods sejam programados em instâncias de tamanho e equipamento adequados. Por exemplo, se seu pod não precisar de umGPU, o Karpenter não agendará seu pod para um tipo de EC2 instância compatível com a. GPU Quando não tiver certeza sobre quais tipos de instância usar, você pode executar o Amazon ec2-instance-selector para gerar uma lista de tipos de instância que correspondam aos seus requisitos computacionais. Por exemplo, o CLI usa memória vCPU, arquitetura e região como parâmetros de entrada e fornece uma lista de EC2 instâncias que satisfazem essas restrições.

$ ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 -r ap-southeast-1 c5.large c5a.large c5ad.large c5d.large c6i.large t2.medium t3.medium t3a.medium

Você não deve colocar muitas restrições no Karpenter ao usar instâncias spot, pois isso pode afetar a disponibilidade de seus aplicativos. Digamos, por exemplo, que todas as instâncias de um determinado tipo sejam recuperadas e não haja alternativas adequadas disponíveis para substituí-las. Seus pods permanecerão em um estado pendente até que a capacidade spot dos tipos de instância configurados seja reabastecida. Você pode reduzir o risco de erros de capacidade insuficientes distribuindo suas instâncias em diferentes zonas de disponibilidade, porque os pools de pontos são diferentes entre siAZs. Dito isso, a melhor prática geral é permitir que o Karpenter use um conjunto diversificado de tipos de instância ao usar o Spot.

Pods de agendamento

As melhores práticas a seguir estão relacionadas à implantação de pods em um cluster usando o Karpenter para provisionamento de nós.

Siga as EKS melhores práticas para obter alta disponibilidade

Se você precisar executar aplicativos de alta disponibilidade, siga as recomendações gerais de EKS melhores práticas. Consulte a documentação Topology Spread in Karpenter para obter detalhes sobre como distribuir pods entre nós e zonas. Use o Disruption Budgets para definir o mínimo de pods disponíveis que precisam ser mantidos, caso haja tentativas de despejar ou excluir os pods.

Use restrições em camadas para restringir os recursos de computação disponíveis no seu provedor de nuvem

O modelo de restrições em camadas do Karpenter permite que você crie um conjunto complexo de restrições de implantação de pods para obter as NodePool melhores correspondências possíveis para o agendamento de pods. Exemplos de restrições que uma especificação de pod pode solicitar incluem o seguinte:

  • Necessidade de execução em zonas de disponibilidade onde somente aplicativos específicos estão disponíveis. Digamos, por exemplo, que você tenha um pod que precisa se comunicar com outro aplicativo executado em uma EC2 instância residente em uma zona de disponibilidade específica. Se seu objetivo é reduzir o tráfego entre AZ em seuVPC, talvez você queira colocar os pods no AZ em que a EC2 instância está localizada. Esse tipo de segmentação geralmente é realizado usando seletores de nós. Para obter informações adicionais sobre seletores de nós, consulte a documentação do Kubernetes.

  • Exigindo certos tipos de processadores ou outro hardware. Consulte a seção Accelerators da documentação do Karpenter para ver um exemplo de podspec que exige que o pod seja executado em um. GPU

Crie alarmes de cobrança para monitorar seus gastos com computação

Ao configurar seu cluster para escalar automaticamente, você deve criar alarmes de cobrança para avisá-lo quando seus gastos excederem um limite e adicionar limites de recursos à sua configuração do Karpenter. Definir limites de recursos com o Karpenter é semelhante a definir a capacidade máxima de um grupo AWS de escalonamento automático, pois representa a quantidade máxima de recursos computacionais que podem ser instanciados por um Karpenter. NodePool

nota

Não é possível definir um limite global para todo o cluster. Os limites se aplicam a determinados NodePools.

O trecho abaixo diz ao Karpenter para provisionar apenas um máximo de 1000 CPU núcleos e 1000Gi de memória. O Karpenter deixará de adicionar capacidade somente quando o limite for atingido ou excedido. Quando um limite é excedido, o controlador Karpenter grava uma mensagem semelhante nos registros do controlador. memory resource usage of 1001 exceeds limit of 1000 Se você estiver roteando seus registros de contêiner para CloudWatch registros, poderá criar um filtro de métricas para procurar padrões ou termos específicos em seus registros e, em seguida, criar um CloudWatchalarme para alertá-lo quando o limite de métricas configurado for violado.

Para obter mais informações sobre como usar limites com o Karpenter, consulte Definindo limites de recursos na documentação do Karpenter.

spec: limits: cpu: 1000 memory: 1000Gi

Se você não usar limites ou restringir os tipos de instância que o Karpenter pode provisionar, o Karpenter continuará adicionando capacidade computacional ao seu cluster conforme necessário. Embora a configuração do Karpenter dessa forma permita que seu cluster seja escalado livremente, ela também pode ter implicações de custo significativas. É por esse motivo que recomendamos a configuração de alarmes de cobrança. Os alarmes de cobrança permitem que você seja alertado e notificado proativamente quando as cobranças estimadas calculadas em sua (s) conta (s) excederem um limite definido. Consulte Configurar um alarme de CloudWatch cobrança da Amazon para monitorar proativamente as cobranças estimadas para obter informações adicionais.

Você também pode habilitar a Detecção de Anomalias de AWS Custos, que é um recurso de gerenciamento de custos que usa aprendizado de máquina para monitorar continuamente seus custos e uso para detectar gastos incomuns. Mais informações podem ser encontradas no guia de introdução à detecção de anomalias de AWS custo. Se você chegou ao ponto de criar um orçamento em AWS Orçamentos, também pode configurar uma ação para notificá-lo quando um limite específico for violado. Com as ações orçamentárias, você pode enviar um e-mail, publicar uma mensagem em um SNS tópico ou enviar uma mensagem para um chatbot como o Slack. Para obter mais informações, consulte Configurando ações de AWS orçamentos.

Use a do-not-disrupt anotação karpenter.sh/ para evitar que o Karpenter desprovisione um nó

Se você estiver executando um aplicativo crítico em um nó provisionado pelo Karpenter, como um trabalho em lotes de longa execução ou um aplicativo com estado, e o nó TTL tiver expirado, o aplicativo será interrompido quando a instância for encerrada. Ao adicionar uma karpenter.sh/do-not-disrupt anotação ao pod, você está instruindo o Karpenter a preservar o nó até que o pod seja encerrado ou a anotação seja removida. karpenter.sh/do-not-disrupt Consulte a documentação sobre distrupção para obter mais informações.

Se os únicos pods sem daemonset restantes em um nó forem aqueles associados a trabalhos, o Karpenter poderá direcionar e encerrar esses nós, desde que o status do trabalho seja bem-sucedido ou falhe.

Configure solicitações=limites para todos os que não são recursos ao usar a consolidação CPU

A consolidação e o agendamento em geral funcionam comparando as solicitações de recursos dos pods com a quantidade de recursos alocáveis em um nó. Os limites de recursos não são considerados. Por exemplo, pods com um limite de memória maior do que a solicitação de memória podem ultrapassar a solicitação. Se vários pods no mesmo nó explodirem ao mesmo tempo, isso pode fazer com que alguns deles sejam encerrados devido a uma condição de falta de memória (). OOM A consolidação pode aumentar a probabilidade de isso ocorrer, pois funciona para empacotar pods em nós considerando apenas suas solicitações.

Use LimitRanges para configurar padrões para solicitações e limites de recursos

Como o Kubernetes não define solicitações ou limites padrão, o consumo de recursos do host subjacente e da memória de um contêiner não é CPU vinculado. O programador do Kubernetes analisa o total de solicitações de um pod (o maior número de solicitações dos contêineres do pod ou o total de recursos dos contêineres Init do pod) para determinar em qual nó de trabalho programar o pod. Da mesma forma, o Karpenter considera as solicitações de um pod para determinar qual tipo de instância ele provisiona. Você pode usar um intervalo limite para aplicar um padrão sensato a um namespace, caso as solicitações de recursos não sejam especificadas por alguns pods.

Consulte Configurar solicitações e limites de memória padrão para um namespace

Aplique solicitações de recursos precisas a todas as cargas de trabalho

O Karpenter é capaz de lançar nós que melhor se adaptam às suas cargas de trabalho quando as informações sobre os requisitos de suas cargas de trabalho são precisas. Isso é particularmente importante ao usar o recurso de consolidação do Karpenter.

Consulte Configurar e dimensionar solicitações/limites de recursos para todas as cargas de trabalho

DNSRecomendações principais

Atualize a configuração do Core DNS para manter a confiabilidade

Ao implantar DNS pods Core em nós gerenciados pelo Karpenter, dada a natureza dinâmica do Karpenter em terminar/criar rapidamente novos nós para se alinhar à demanda, é aconselhável seguir as seguintes melhores práticas:

Duração do DNS pato principal

Sonda de DNS prontidão do núcleo

Isso garantirá que DNS as consultas não sejam direcionadas para um Core DNS Pod que ainda não esteja pronto ou tenha sido encerrado.

Plantas de Karpenter

Como o Karpenter adota uma abordagem que prioriza o aplicativo para provisionar a capacidade computacional para o plano de dados do Kubernetes, há cenários comuns de carga de trabalho nos quais você pode estar se perguntando como configurá-los adequadamente. O Karpenter Blueprints é um repositório que inclui uma lista de cenários comuns de carga de trabalho seguindo as melhores práticas descritas aqui. Você terá todos os recursos necessários até mesmo para criar um EKS cluster com o Karpenter configurado e testar cada um dos blueprints incluídos no repositório. Você pode combinar diferentes esquemas para finalmente criar o que você precisa para sua (s) carga (s) de trabalho.

Recursos adicionais