Comment installer Karpenter dans mon cluster Amazon EKS ?

Lecture de 7 minute(s)
0

Je souhaite utiliser Karpenter pour dimensionner les composants master au sein de mon cluster Amazon Elastic Kubernetes Service (Amazon EKS).

Brève description

Karpenter est un projet open source de mise en service des nœuds conçu pour Kubernetes. En ajoutant Karpenter à un cluster Kubernetes, vous pouvez améliorer considérablement l'efficacité et le coût d'exécution des charges de travail sur ce cluster. Pour plus d'informations, consultez la documentation de Karpenter.

Les étapes suivantes expliquent comment déployer Karpenter dans un cluster Amazon EKS.

Résolution

Prérequis

Avant de commencer, effectuez les opérations suivantes :

  • Installez le client Helm, version 3.11.0 ou ultérieure. Consultez la documentation Helm Docs pour connaître les procédures d'installation détaillées.
  • Installez eksctl. Consultez le guide de l'utilisateur d'eksctl pour connaître les procédures d'installation détaillées.
  • Créez les variables d'environnement suivantes :
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)

Remarque : saisissez le nom de votre cluster EKS dans le champ your_cluster_name et le numéro de votre version Karpenter requise dans le champ your_required_version. Consultez Karpenter/releases pour connaître les versions de Karpenter.

Créer des rôles IAM pour Karpenter et le contrôleur Karpenter

1.    Créez les rôles AWS Identity and Access Management (IAM) pour les nœuds mis en service avec Karpenter. Le rôle de nœud Karpenter (KarpenterInstanceNodeRole) est similaire au rôle IAM du nœud Amazon EKS. Reportez-vous au rôle IAM du nœud Amazon EKS pour créer le rôle KapenterInstanceNodeRole à l'aide de la console de gestion AWS ou de l'interface de la ligne de commande AWS (AWS CLI).

Remarque : si vous rencontrez des erreurs lors de l'exécution des commandes CLI, vérifiez que vous utilisez la version la plus récente d'AWS CLI. Consultez la section Résolution des erreurs d'AWS CLI – Interface de la ligne de commande AWS.

2.    Ajoutez ces stratégies IAM au KarpenterInstanceNodeRole IAM que vous avez créé.

AmazonEKSWorkerNodePolicy
AmazonEKS_CNI_Policy
AmazonEC2ContainerRegistryReadOnly
AmazonSSMManagedInstanceCore

Configurer le rôle IAM pour le contrôleur Karpenter

Créez un rôle IAM pour KarpenterControllerRole. Le contrôleur Karpenter utilise les rôles IAM pour les comptes de service (IRSA).

1.    Créez un document controller-policy.json comprenant les autorisations suivantes :

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.    Créez une politique IAM à l'aide de ce document controller-policy.json.

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

3.    Créez un fournisseur d'identité OIDC IAM pour votre cluster avec cette commande eksctl.

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

Remarque : assurez-vous d'utiliser la version 0.32.0 ou ultérieure d'eksctl.

4.    Créez le rôle IAM pour le contrôleur Karpenter à l'aide de la commande eksctl. Associez le compte de service Kubernetes et le rôle IAM à l'aide d'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

Ajouter des identifications aux sous-réseaux et aux groupes de sécurité

1.    Ajoutez des identifications aux sous-réseaux des groupes de nœuds pour indiquer à Karpenter les sous-réseaux à utiliser.

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.    Ajoutez des identifications aux groupes de sécurité.

Remarque : les commandes suivantes ajoutent des identifications uniquement aux groupes de sécurité du premier groupe de nœuds. Si vous avez plusieurs groupes de nœuds ou plusieurs groupes de sécurité, vous devez sélectionner le groupe de sécurité à utiliser par 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}

Mettre à jour le ConfigMap aws-auth

1.    Mettez à jour le ConfigMap aws-auth dans le cluster pour autoriser les nœuds qui utilisent le rôle IAM KarpenterInstanceNodeRole à rejoindre le cluster. Exécutez la commande suivante :

kubectl edit configmap aws-auth -n kube-system

2.    Ajoutez à mapRoles une section du type :

Remarque : remplacez la variable ${AWS_ACCOUNT_ID} par votre compte, mais ne remplacez pas {{EC2PrivateDNSName}}.

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

Le ConfigMap aws-auth complet possède désormais deux groupes : un pour votre rôle de nœud Karpenter et un pour votre groupe de nœuds existant.

Déployer Karpenter

1.    Vérifiez la version de Karpenter que vous souhaitez déployer à l'aide de cette commande :

echo $KARPENTER_VERSION

Si vous ne voyez aucun résultat ou si vous voyez une version différente de celle souhaitée, exécutez :

export KARPENTER_VERSION=your_required_version

Remarque : remplacez your_required_version par le numéro de version souhaité dans cet exemple. Consultez aws/karpenter pour connaître les versions de Karpenter sur le site Web de GitHub.

2.    Générez un fichier yaml complet de déploiement de Karpenter à partir des Charts de Helm. Avant de commencer, assurez-vous d'utiliser la version v3.11.0 ou ultérieure du client Helm.

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.    Définissez l'affinité de manière à exécuter Karpenter sur l'un des nœuds du groupe de nœuds existants. Recherchez la règle d'affinité de déploiement, puis modifiez-la dans le fichier karpenter.yaml que vous venez de créer :

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

Créer l'espace de noms Karpenter

Créez l'espace de noms Karpenter requis et le CRD du fournisseur. Déployez ensuite les autres ressources 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

Créer une mise en service par défaut

Créez une mise en service par défaut de manière à indiquer à Karpenter les types de nœuds que vous souhaitez utiliser pour les charges de travail non planifiées. Pour plus d'informations sur des exemples spécifiques, consultez aws/karpenter sur le site 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

Dimensionner et vérifier Karpenter

Suivez les étapes suivantes pour dimensionner votre groupe de nœuds de manière à atteindre une taille minimale d'au moins deux nœuds afin de prendre en charge Karpenter et d'autres services critiques.

1.    Configurez le dimensionnement :

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

2.    Dimensionnez vos charges de travail, puis vérifiez que Karpenter crée les nouveaux nœuds pour la mise en service de vos charges de travail :

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

Remarque : si vous constatez la présence d'erreurs DefaultingWebhook Reconcile dans les journaux du contrôleur, redémarrez vos pods Karpenter pour la corriger.

3.    Exécutez la commande suivante pour vérifier le statut des nœuds :

kubectl get nodes

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 4 mois