Before we install Karpenter, there are a few things that we will need to prepare in our environment for it to work as expected.
Instances launched by Karpenter must run with an InstanceProfile that grants permissions necessary to run containers and configure networking. Karpenter discovers the InstanceProfile using the name KarpenterNodeRole-${ClusterName}
.
Karpenter also utilizes an SQS queue and EventBridge rules to handle Spot Interruption Notifications and AWS Health Events.
export KARPENTER_VERSION=v0.26.1
echo "export KARPENTER_VERSION=${KARPENTER_VERSION}" >> ~/.bash_profile
TEMPOUT=$(mktemp)
curl -fsSL https://karpenter.sh/"${KARPENTER_VERSION}"/getting-started/getting-started-with-eksctl/cloudformation.yaml > $TEMPOUT \
&& aws cloudformation deploy \
--stack-name Karpenter-${CLUSTER_NAME} \
--template-file ${TEMPOUT} \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides ClusterName=${CLUSTER_NAME}
This step may take about 2 minutes. In the meantime, you can download the file and check the content of the CloudFormation Stack. Check how the stack defines a policy, a role and and Instance profile that will be used to associate to the instances launched. You can also head to the CloudFormation console and check which resources does the stack deploy.
Second, grant access to instances using the profile to connect to the cluster. This command adds the Karpenter node role to your aws-auth configmap, allowing nodes with this role to connect to the cluster.
eksctl create iamidentitymapping \
--username system:node:{{EC2PrivateDNSName}} \
--cluster ${CLUSTER_NAME} \
--arn arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME} \
--group system:bootstrappers \
--group system:nodes
You can verify the entry is now in the AWS auth map by running the following command.
kubectl describe configmap -n kube-system aws-auth
Before adding the IAM Role for the service account we need to create the IAM OIDC Identity Provider for the cluster.
eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} --approve
Karpenter requires permissions like launching instances. This will create an AWS IAM Role, Kubernetes service account, and associate them using IAM Roles for Service Accounts (IRSA)
eksctl create iamserviceaccount \
--cluster $CLUSTER_NAME --name karpenter --namespace karpenter \
--role-name "${CLUSTER_NAME}-karpenter" \
--attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/KarpenterControllerPolicy-$CLUSTER_NAME \
--role-only \
--approve
This step may take up to 2 minutes. eksctl will create and deploy a CloudFormation stack that defines the role and create the kubernetes resources that define the Karpenter serviceaccount
and the karpenter
namespace that we will use during the workshop. You can also check in the CloudFormation console, the resources this stack creates.
Finally, we will create the spot EC2 Spot Linked role.
This step is only necessary if this is the first time you’re using EC2 Spot in this account. If the role has already been successfully created, you will see: An error occurred (InvalidInput) when calling the CreateServiceLinkedRole operation: Service role name AWSServiceRoleForEC2Spot has been taken in this account, please try a different suffix. . Just ignore the error and proceed with the rest of the workshop.
aws iam create-service-linked-role --aws-service-name spot.amazonaws.com