¿Cómo instalo Karpenter en mi clúster de Amazon EKS?

7 minutos de lectura
0

Quiero usar Karpenter para escalar los nodos de trabajo de mi clúster de Amazon Elastic Kubernetes Service (Amazon EKS).

Descripción breve

Karpenter es un proyecto de aprovisionamiento de nodos de código abierto creado para Kubernetes. Agregar Karpenter a un clúster de Kubernetes puede mejorar drásticamente la eficiencia y el costo de ejecutar las cargas de trabajo en ese clúster. Para obtener más información, consulte la documentación de Karpenter.

Los siguientes pasos muestran cómo implementar Karpenter en un clúster de Amazon EKS.

Resolución

Requisitos previos

Antes de comenzar, complete los siguientes pasos:

  • Instale la versión 3.11.0 o superior del cliente Helm. Consulte Helm Docs para obtener más información sobre los procedimientos de instalación.
  • Instale eksctl. Consulte la guía del usuario de eksctl para obtener más información sobre los procedimientos de instalación.
  • Cree estas variables de entorno:
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)

Nota: Ingrese el nombre del clúster de EKS en your_cluster_name y el número de versión de Karpenter requerido en your_required_version. Consulte karpenter/releases para ver las versiones de Karpenter.

Crear roles de IAM para Karpenter y el controlador de Karpenter

1.    Cree los roles de AWS Identity and Access Management (IAM) para los nodos aprovisionados con Karpenter. El rol de nodo de Karpenter (KarpenterInstanceNodeRole) es similar al rol de IAM del nodo de Amazon EKS. Consulte Amazon EKS node IAM role (Rol de IAM del nodo de Amazon EKS) para crear el rol KapenterInstanceNodeRole mediante la Consola de administración de AWS o la Interfaz de la línea de comandos de AWS (AWS CLI).

Nota: Si se producen errores al ejecutar los comandos de la CLI, asegúrese de utilizar la versión más reciente de AWS CLI. Consulte Troubleshooting AWS CLI errors - AWS Command Line Interface (Solución de problemas de AWS CLI: Interfaz de línea de comandos de AWS).

2.    Agregue estas políticas de IAM al rol de IAM KarpenterInstanceNodeRole que creó.

AmazonEKSWorkerNodePolicy
AmazonEKS_CNI_Policy
AmazonEC2ContainerRegistryReadOnly
AmazonSSMManagedInstanceCore

Configure el rol de IAM para el controlador de Karpenter

Cree un rol de IAM para KarpenterControllerRole. El controlador de Karpenter usa los roles de IAM para las cuentas de servicio (IRSA).

1.    Cree un documento controller-policy.json con los siguientes permisos:

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.    Cree una política de IAM con este documento controller-policy.json.

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

3.    Cree un proveedor de identidad de OIDC de IAM para su clúster mediante este comando eksctl

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

Nota: Asegúrese de que su versión de eksctl sea la 0.32.0 o posterior.

4.    Cree el rol de IAM para el controlador de Karpenter mediante el comando eksctl. Asocie la cuenta de servicio de Kubernetes y el rol de IAM mediante 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

Agregar etiquetas a subredes y grupos de seguridad

1.    Agregue etiquetas a las subredes del grupo de nodos para que Karpenter sepa qué subredes debe utilizar.

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.    Agregue etiquetas a los grupos de seguridad.

Nota: Los siguientes comandos agregan etiquetas solo a los grupos de seguridad del primer grupo de nodos. Si tiene varios grupos de nodos o varios grupos de seguridad, debe decidir el grupo de seguridad que utilizará Karpenter.

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}

Actualizar el ConfigMap de aws-auth

1.    Actualice el ConfigMap de aws-auth del clúster para permitir que los nodos que utilizan el rol de IAM KarpenterInstanceNodeRole se unan al clúster. Ejecute el siguiente comando:

kubectl edit configmap aws-auth -n kube-system

2.    Agregue una sección a mapRoles que tenga un aspecto similar al de este ejemplo:

Nota: Sustituya la variable ${AWS_ACCOUNT_ID} por su cuenta, pero no sustituya {{EC2PrivateDNSName}}.

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

El ConfigMap de aws-auth completo ahora tiene dos grupos: uno para su rol de nodo de Karpenter y otro para su grupo de nodos existente.

Implementar Karpenter

1.    Compruebe la versión de Karpenter que desea implementar mediante este comando:

echo $KARPENTER_VERSION

Si no ve ningún resultado o ve una versión diferente a la deseada, ejecute:

export KARPENTER_VERSION=your_required_version

Nota: En este ejemplo, sustituya your_required_version por el número de versión deseado. Consulte aws/karpenter para ver las versiones de Karpenter en el sitio web de GitHub.

2.    Genere un archivo yaml completo de implementación de Karpenter a partir del gráfico de Helm. Antes de empezar, asegúrese de que la versión del cliente de Helm sea la v3.11.0 o 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 la afinidad para que Karpenter se ejecute en uno de los nodos del grupo de nodos existentes. Busque la regla de afinidad de la implementación y modifíquela en el archivo karpenter.yaml que acaba de crear:

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

Crear el espacio de nombres de Karpenter

Cree el espacio de nombres de Karpenter y el CRD del aprovisionador necesarios. A continuación, implemente el resto de los recursos de 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

Crear un aprovisionador predeterminado

Cree un aprovisionador predeterminado para que Karpenter sepa los tipos de nodos que desea para las cargas de trabajo no programadas. Para obtener más información sobre ejemplos específicos, consulte aws/karpenter en el sitio web de 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

Escalar y verificar Karpenter

Siga estos pasos para escalar su grupo de nodos a un tamaño mínimo de al menos dos nodos para ser compatible con Karpenter y otros servicios críticos.

1.    Configure el escalado:

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

2.    Escale sus cargas de trabajo y, a continuación, compruebe que Karpenter esté creando los nuevos nodos para aprovisionarlas:

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

Nota: Si observa algún error de conciliación webhook.DefaultingWebhook en los registros del controlador, reinicie los pods de Karpenter para solucionarlo.

3.    Ejecute el siguiente comando para comprobar el estado de los nodos:

kubectl get nodes

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 8 meses