Como faço para instalar o Karpenter no cluster do Amazon EKS?

7 minuto de leitura
0

Quero usar o Karpenter para escalar os nós de processamento no cluster do Amazon Elastic Kubernetes Service (Amazon EKS).

Breve descrição

O Karpenter é um projeto de provisionamento de nós de código aberto criado para o Kubernetes. Adicionar o Karpenter a um cluster do Kubernetes pode melhorar de forma significativa a eficiência e o custo da execução de workloads nesse cluster. Para obter mais informações, consulte a documentação do Karpenter.

As etapas a seguir mostram como implantar o Karpenter em um cluster do Amazon EKS.

Resolução

Pré-requisitos

Antes de começar, faça o seguinte:

  • Instale o cliente Helm, 3.11.0 ou superior. Consulte a documentação do Helm para obter mais informações sobre os procedimentos de instalação.
  • Instale eksctl. Consulte o guia do usuário do eksctl para obter mais informações sobre os procedimentos de instalação.
  • Crie essas variáveis de ambiente:
export CLUSTER_NAME=your_cluster_name
    
export KARPENTER_VERSION=your_required_version
    
export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)"
    
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)

Observação: insira o nome do cluster do EKS para your_cluster_name e o número de versão necessária do Karpenter para your_required_version. Verifique as versões de karpenter/releases (karpenter/lançamentos) do Karpenter.

Criar perfis do IAM para o Karpenter e o controlador do Karpenter

1.    Crie os perfis do AWS Identity and Access Management (IAM) para os nós provisionados com o Karpenter. A função do nó do Karpenter (KarpenterInstanceNodeRole) é semelhante ao perfil do IAM do nó do Amazon EKS. Consulte o perfil do IAM em nós do Amazon EKS para criar o KapenterInstanceNodeRole usando o Console de Gerenciamento da AWS ou a AWS Command Line Interface (AWS CLI).

Observação: se você receber erros ao executar os comandos da CLI, verifique se está usando a versão mais recente da AWS CLI. Consulte Solução de problemas de erros da AWS CLI.

2.    Adicione essas políticas do IAM ao KarpenterInstanceNodeRole do IAM criado.

AmazonEKSWorkerNodePolicy
AmazonEKS_CNI_Policy
AmazonEC2ContainerRegistryReadOnly
AmazonSSMManagedInstanceCore

Configurar o perfil do IAM para o controlador do Karpenter

Crie um perfil do IAM para KarpenterControllerRole. O controlador do Karpenter usa os perfis do IAM para contas de serviço (IRSA).

1.    Crie um documento controller-policy.json com as seguintes permissões:

echo '{
    "Statement": [
        {
            "Action": [
                "ssm:GetParameter",
                "iam:PassRole",
                "ec2:DescribeImages",
                "ec2:RunInstances",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeLaunchTemplates",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceTypes",
                "ec2:DescribeInstanceTypeOfferings",
                "ec2:DescribeAvailabilityZones",
                "ec2:DeleteLaunchTemplate",
                "ec2:CreateTags",
                "ec2:CreateLaunchTemplate",
                "ec2:CreateFleet",
                "ec2:DescribeSpotPriceHistory",
                "pricing:GetProducts"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Sid": "Karpenter"
        },
        {
            "Action": "ec2:TerminateInstances",
            "Condition": {
                "StringLike": {
                    "ec2:ResourceTag/Name": "*karpenter*"
                }
            },
            "Effect": "Allow",
            "Resource": "*",
            "Sid": "ConditionalEC2Termination"
        }
    ],
    "Version": "2012-10-17"
}' > controller-policy.json

2.    Crie uma política do IAM usando este documento controller-policy.json.

aws iam create-policy --policy-name KarpenterControllerPolicy-${CLUSTER_NAME} --policy-document file://controller-policy.json

3.    Crie um provedor de identidade OIDC do IAM para seu cluster usando este comando eksctl

eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} --approve

Observação: certifique-se de que sua versão do eksctl seja a 0.32.0 ou posterior.

4.    Crie o perfil do IAM para o controlador do Karpenter usando o comando eksctl. Associe a conta de serviço do Kubernetes e o perfil do IAM usando o IRSA.

eksctl create iamserviceaccount \
  --cluster "${CLUSTER_NAME}" --name karpenter --namespace karpenter \
  --role-name "$KarpenterControllerRole-${CLUSTER_NAME}" \
  --attach-policy-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}" \
  --role-only \
  --approve

Adicione tags a sub-redes e grupos de segurança

1.    Adicione tags às sub-redes do grupo de nós para que o Karpenter conheça as sub-redes a serem usadas.

for NODEGROUP in $(aws eks list-nodegroups --cluster-name ${CLUSTER_NAME} \
    --query 'nodegroups' --output text); do aws ec2 create-tags \
        --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \
        --resources $(aws eks describe-nodegroup --cluster-name ${CLUSTER_NAME} \
        --nodegroup-name $NODEGROUP --query 'nodegroup.subnets' --output text )
done

2.    Adicione tags aos grupos de segurança.

Observação: os comandos a seguir adicionam tags somente aos grupos de segurança do primeiro grupo de nós. Se você tiver vários grupos de nós ou vários grupos de segurança, deverá decidir o grupo de segurança que o Karpenter usará.

NODEGROUP=$(aws eks list-nodegroups --cluster-name ${CLUSTER_NAME} \
    --query 'nodegroups[0]' --output text)
 
LAUNCH_TEMPLATE=$(aws eks describe-nodegroup --cluster-name ${CLUSTER_NAME} \
    --nodegroup-name ${NODEGROUP} --query 'nodegroup.launchTemplate.{id:id,version:version}' \
    --output text | tr -s "\t" ",")
 
# If your EKS setup is configured to use only Cluster security group, then please execute -
 
SECURITY_GROUPS=$(aws eks describe-cluster \
    --name ${CLUSTER_NAME} --query cluster.resourcesVpcConfig.clusterSecurityGroupId | tr -d '"')
 
# If your setup uses the security groups in the Launch template of a managed node group, then :
 
SECURITY_GROUPS=$(aws ec2 describe-launch-template-versions \
    --launch-template-id ${LAUNCH_TEMPLATE%,*} --versions ${LAUNCH_TEMPLATE#*,} \
    --query 'LaunchTemplateVersions[0].LaunchTemplateData.[NetworkInterfaces[0].Groups||SecurityGroupIds]' \
    --output text)
 
aws ec2 create-tags \
    --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \
    --resources ${SECURITY_GROUPS}

Atualizar aws-auth ConfigMap

1.    Atualize o aws-auth ConfigMap no cluster para permitir que os nós que usam o perfil do IAM KarpenterInstanceNodeRole se juntem ao cluster. Execute o seguinte comando:

kubectl edit configmap aws-auth -n kube-system

2.    Adicione uma seção a mapRoles que seja semelhante a este exemplo:

Observação: substitua a variável ${AWS_ACCOUNT_ID} pela sua conta, mas não substitua {{EC2PrivateDNSName}}.

- groups:
  - system:bootstrappers
  - system:nodes
  rolearn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterInstanceNodeRole
  username: system:node:{{EC2PrivateDNSName}}

O aws-auth ConfigMap completo agora tem dois grupos: um para sua função de nó do Karpenter e outro para seu grupo de nós existente.

Implantar o Karpenter

1.    Verifique a versão do lançamento do Karpenter que você deseja implantar usando este comando:

echo $KARPENTER_VERSION

Se você não vê nenhuma saída ou vê uma versão diferente da desejada, execute:

export KARPENTER_VERSION=your_required_version

Observação: substitua your_required_version pelo número da versão desejada neste exemplo. Consulte aws/karpenter para ver as versões do Karpenter no site do GitHub.

2.    Gere um arquivo yaml completo de implantação do Karpenter do chart do Helm. Antes de começar, certifique-se de que a versão do cliente Helm seja a v3.11.0 ou posterior.

helm template karpenter oci://public.ecr.aws/karpenter/karpenter --version ${KARPENTER_VERSION} --namespace karpenter \
    --set settings.aws.defaultInstanceProfile=KarpenterInstanceProfile \
    --set settings.aws.clusterEndpoint="${CLUSTER_ENDPOINT}" \
    --set settings.aws.clusterName=${CLUSTER_NAME} \
    --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"="arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterControllerRole-${CLUSTER_NAME}" > karpenter.yaml

3.    Defina a afinidade para que o Karpenter seja executado em um dos nós existentes do grupo de nós. Encontre a regra de afinidade de implantação e modifique-a no arquivo karpenter.yaml criado:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: karpenter.sh/provisioner-name
          operator: DoesNotExist
      - matchExpressions:
        - key: eks.amazonaws.com/nodegroup
          operator: In
          values:
          - ${NODEGROUP}

Criar o namespace do Karpenter

Crie o namespace do Karpenter necessário e o CRD do provisionador. Em seguida, implante o restante dos recursos do Karpenter.

kubectl create namespace karpenter
kubectl create -f https://raw.githubusercontent.com/aws/karpenter/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.sh_provisioners.yaml
kubectl create -f https://raw.githubusercontent.com/aws/karpenter/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.k8s.aws_awsnodetemplates.yaml
kubectl apply -f karpenter.yaml

Criar um provisionador padrão

Crie um provisionador padrão para que o Karpenter conheça os tipos de nós que você deseja para workloads não programadas. Para obter mais informações sobre exemplos específicos, consulte aws/karpenter no site do GitHub.

cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
    - key: karpenter.k8s.aws/instance-category
      operator: In
      values: [c, m, r]
    - key: karpenter.k8s.aws/instance-generation
      operator: Gt
      values: ["2"]
  providerRef:
    name: default
  ttlSecondsAfterEmpty: 30
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: default
spec:
  subnetSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelector:
    karpenter.sh/discovery: "${CLUSTER_NAME}"
EOF

Dimensionar e verificar o Karpenter

Use as etapas a seguir para dimensionar o seu grupo de nós para um tamanho mínimo de pelo menos dois nós para dar suporte ao Karpenter e a outros serviços essenciais.

1.    Configure o redimensionamento:

aws eks update-nodegroup-config --cluster-name ${CLUSTER_NAME} \
    --nodegroup-name ${NODEGROUP} \
    --scaling-config "minSize=2,maxSize=2,desiredSize=2"

2.    Dimensione suas workloads e, em seguida, verifique se o Karpenter está criando os novos nós para provisioná-las:

kubectl logs -f -n karpenter -c controller -l app.kubernetes.io/name=karpenter

Observação: se você notar algum erro webhook.DefaultingWebhook Reconcile nos logs do controlador, reinicie os pods do Karpenter para corrigi-lo.

3.    Use o seguinte comando para verificar o status dos nós:

kubectl get nodes

AWS OFICIAL
AWS OFICIALAtualizada há 8 meses