Getting Started with eksctl
Karpenter automatically provisions new nodes in response to unschedulable pods. Karpenter does this by observing events within the Kubernetes cluster, and then sending commands to the underlying cloud provider.
In this example, the cluster is running on Amazon Web Services (AWS) Elastic Kubernetes Service (EKS). Karpenter is designed to be cloud provider agnostic, but currently only supports AWS. Contributions are welcomed.
This guide should take less than 1 hour to complete, and cost less than $0.25. Follow the clean-up instructions to reduce any charges.
Install
Karpenter is installed in clusters with a Helm chart.
Karpenter requires cloud provider permissions to provision nodes, for AWS IAM Roles for Service Accounts (IRSA) should be used. IRSA permits Karpenter (within the cluster) to make privileged requests to AWS (as the cloud provider) via a ServiceAccount.
Required Utilities
Install these tools before proceeding:
- AWS CLI
kubectl
- the Kubernetes CLIeksctl
- the CLI for AWS EKShelm
- the package manager for Kubernetes
Configure the AWS CLI
with a user that has sufficient privileges to create an EKS cluster. Verify that the CLI can
authenticate properly by running aws sts get-caller-identity
.
Environment Variables
After setting up the tools, set the following environment variable to the Karpenter version you would like to install.
Also set the following environment variables to store commonly used values.
Warning
If you open a new shell to run steps in this procedure, you need to set some or all of the environment variables again. To remind yourself of these values, type:
Create a Cluster
Create a basic cluster with eksctl
.
Each of the two examples set up an IAM OIDC provider for the cluster to enable IAM roles for pods.
The first uses AWS EKS managed node groups for the kube-system and karpenter namespaces, while the second uses Fargate for both namespaces.
Example 1: Create basic cluster
Example 2: Create basic cluster with Karpenter on Fargate
Karpenter itself can run anywhere, including on self-managed node groups, managed node groups (Example 1), or AWS Fargate(Example 2).
Karpenter will provision EC2 instances in your account.
Create the KarpenterNode IAM Role
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}
.
First, create the IAM resources using AWS CloudFormation.
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.
Now, Karpenter can launch new EC2 instances and those instances can connect to your cluster.
Create the KarpenterController IAM Role
Karpenter requires permissions like launching instances. This will create an AWS IAM Role, Kubernetes service account, and associate them using IRSA.
Create the EC2 Spot Service Linked Role
This step is only necessary if this is the first time you’re using EC2 Spot in this account. More details are available here.
Install Karpenter Helm Chart
Use Helm to deploy Karpenter to the cluster.
Before the chart can be installed the repo needs to be added to Helm, run the following commands to add the repo.
Install the chart passing in the cluster details and the Karpenter role ARN.
Deploy a temporary Prometheus and Grafana stack (optional)
The following commands will deploy a Prometheus and Grafana stack that is suitable for this guide but does not include persistent storage or other configurations that would be necessary for monitoring a production deployment of Karpenter. This deployment includes two Karpenter dashboards that are automatically onboarded to Grafana. They provide a variety of visualization examples on Karpenter metrics.
The Grafana instance may be accessed using port forwarding.
The new stack has only one user, admin
, and the password is stored in a secret. The following command will retrieve the password.
Deploy the AWS Node Termination Handler to handle Spot interruptions gracefully (optional)
The following commands will deploy the AWS Node Termination Handler as a DaemonSet to run on Spot nodes to handle spot interruption notifications, spot rebalance recommendations, and EC2 scheduled maintenance events. Learn more about the AWS Node Termination Handler and more advanced configurations here.
Provisioner
A single Karpenter provisioner is capable of handling many different pod shapes. Karpenter makes scheduling and provisioning decisions based on pod attributes such as labels and affinity. In other words, Karpenter eliminates the need to manage many different node groups.
Create a default provisioner using the command below.
This provisioner uses securityGroupSelector
and subnetSelector
to discover resources used to launch nodes.
We applied the tag karpenter.sh/discovery
in the eksctl
command above.
Depending how these resources are shared between clusters, you may need to use different tagging schemes.
The ttlSecondsAfterEmpty
value configures Karpenter to terminate empty nodes.
This behavior can be disabled by leaving the value undefined.
Review the provisioner CRD for more information. For example,
ttlSecondsUntilExpired
configures Karpenter to terminate nodes when a maximum age is reached.
Note: This provisioner will create capacity as long as the sum of all created capacity is less than the specified limit.
First Use
Karpenter is now active and ready to begin provisioning nodes. Create some pods using a deployment, and watch Karpenter provision nodes in response.
Automatic Node Provisioning
This deployment uses the pause image and starts with zero replicas.
Automatic Node Termination
Now, delete the deployment. After 30 seconds (ttlSecondsAfterEmpty
),
Karpenter should terminate the now empty nodes.
Manual Node Termination
If you delete a node with kubectl, Karpenter will gracefully cordon, drain, and shutdown the corresponding instance. Under the hood, Karpenter adds a finalizer to the node object, which blocks deletion until all pods are drained and the instance is terminated. Keep in mind, this only works for nodes provisioned by Karpenter.
Cleanup
To avoid additional charges, remove the demo infrastructure from your AWS account.