Last active
July 16, 2022 23:32
-
-
Save vilaca/339728db1cfb489d5e596aad56d2fecf to your computer and use it in GitHub Desktop.
Auto-scaling EKS with Karpenter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eou pipefail | |
export KARPENTER_VERSION=v0.13.2 | |
export CLUSTER_NAME="my-cluster" | |
export AWS_DEFAULT_REGION="us-east-2" | |
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)" | |
# use --profile when required | |
eksctl create cluster -f - << EOF | |
--- | |
apiVersion: eksctl.io/v1alpha5 | |
kind: ClusterConfig | |
metadata: | |
name: ${CLUSTER_NAME} | |
region: ${AWS_DEFAULT_REGION} | |
version: "1.22" | |
tags: | |
karpenter.sh/discovery: ${CLUSTER_NAME} | |
managedNodeGroups: | |
- instanceType: m5.large | |
amiFamily: AmazonLinux2 | |
name: ${CLUSTER_NAME}-ng | |
desiredCapacity: 1 | |
minSize: 1 | |
maxSize: 10 | |
iam: | |
withOIDC: true | |
EOF | |
export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)" | |
# Create the KarpenterNode IAM Role | |
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}" | |
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 | |
# Create the KarpenterController IAM Role | |
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 | |
export KARPENTER_IAM_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/${CLUSTER_NAME}-karpenter" | |
# Create the EC2 Spot Service Linked Role | |
#aws iam create-service-linked-role --aws-service-name spot.amazonaws.com || true | |
# 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. | |
# Install Karpenter Helm Chart | |
#helm repo add karpenter https://charts.karpenter.sh/ | |
#helm repo update | |
helm upgrade --install --namespace karpenter --create-namespace \ | |
karpenter karpenter/karpenter \ | |
--version ${KARPENTER_VERSION} \ | |
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \ | |
--set clusterName=${CLUSTER_NAME} \ | |
--set clusterEndpoint=${CLUSTER_ENDPOINT} \ | |
--set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \ | |
--wait | |
# Provisioner | |
cat <<EOF | kubectl apply -f - | |
apiVersion: karpenter.sh/v1alpha5 | |
kind: Provisioner | |
metadata: | |
name: default | |
spec: | |
requirements: | |
- key: karpenter.sh/capacity-type | |
operator: In | |
values: ["spot"] | |
limits: | |
resources: | |
cpu: 1000 | |
provider: | |
subnetSelector: | |
karpenter.sh/discovery: ${CLUSTER_NAME} | |
securityGroupSelector: | |
karpenter.sh/discovery: ${CLUSTER_NAME} | |
ttlSecondsAfterEmpty: 30 | |
EOF | |
# TEST | |
cat <<EOF | kubectl apply -f - | |
apiVersion: apps/v1 | |
kind: Deployment | |
metadata: | |
name: inflate | |
spec: | |
replicas: 0 | |
selector: | |
matchLabels: | |
app: inflate | |
template: | |
metadata: | |
labels: | |
app: inflate | |
spec: | |
terminationGracePeriodSeconds: 0 | |
containers: | |
- name: inflate | |
image: public.ecr.aws/eks-distro/kubernetes/pause:3.2 | |
resources: | |
requests: | |
cpu: 1 | |
EOF | |
#kubectl scale deployment inflate --replicas 5 | |
#kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eou pipefail | |
helm uninstall karpenter --namespace karpenter | |
# use --profile when required | |
#aws iam detach-role-policy --role-name="${CLUSTER_NAME}-karpenter" --policy-arn="arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}" | |
aws iam delete-policy --policy-arn="arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}" | |
aws iam delete-role --role-name="${CLUSTER_NAME}-karpenter" | |
aws cloudformation delete-stack --stack-name "Karpenter-${CLUSTER_NAME}" | |
aws ec2 describe-launch-templates \ | |
| jq -r ".LaunchTemplates[].LaunchTemplateName" \ | |
| grep -i "Karpenter-${CLUSTER_NAME}" \ | |
| xargs -I{} aws ec2 delete-launch-template --launch-template-name {} | |
eksctl delete cluster --name "${CLUSTER_NAME}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment