Cluster Autoscaling
Using Cluster Autoscaler(CA)
Create the service account
POLICY_NAME="<policy name>"
ROLE_NAME="<role name>"
CLUSTER_NAME="<cluster name>"
PROJECT_NAME="<project name>"
REGION="<region code>"
curl -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/cluster-autoscaler-policy.json
POLICY_ARN=$(aws iam create-policy \
--policy-name $POLICY_NAME \
--policy-document file://cluster-autoscaler-policy.json \
--query 'Policy.Arn' \
--output text \
# --tags Key=project,Value=$PROJECT_NAME \ # AWS CLI v2
)
eksctl create iamserviceaccount \
--cluster=$CLUSTER_NAME \
--namespace=kube-system \
--name=cluster-autoscaler \
--role-name=$ROLE_NAME \
--attach-policy-arn=$POLICY_ARN \
--region $REGION \
--override-existing-serviceaccounts \
--approve
$POLICY_NAME="<policy name>"
$ROLE_NAME="<role name>"
$CLUSTER_NAME="<cluster name>"
$PROJECT_NAME="<project name>"
$REGION="<region code>"
curl.exe -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/cluster-autoscaler-policy.json
POLICY_ARN = aws iam create-policy `
--policy-name $POLICY_NAME `
--policy-document file://cluster-autoscaler-policy.json `
--query 'Policy.Arn' `
--output text `
--tags Key=project,Value=$PROJECT_NAME `
eksctl create iamserviceaccount `
--cluster=$CLUSTER_NAME `
--namespace=kube-system `
--name=cluster-autoscaler `
--role-name=$ROLE_NAME `
--attach-policy-arn=$POLICY_ARN `
--region $REGION `
--override-existing-serviceaccounts `
--approve
Deploy the Cluster Autoscaler using helm
CLUSTER_NAME="<cluster name>"
IMAGE_TAG="<image tag (ex. 1.27.2)>"
REGION="<region code>"
helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm install cluster-autoscaler autoscaler/cluster-autoscaler \
--namespace kube-system \
--set autoDiscovery.clusterName=$CLUSTER_NAME \
--set awsRegion=$REGION \
--set cloudProvider=aws \
--set extraArgs.logtostderr=true \
--set extraArgs.stderrthreshold=info \
--set extraArgs.v=4 \
--set extraArgs.skip-nodes-with-local-storage=false \
--set extraArgs.expander=least-waste \
--set extraArgs.balance-similar-node-groups=true \
--set extraArgs.skip-nodes-with-system-pods=false \
--set image.tag=v$IMAGE_TAG \
--set rbac.serviceAccount.create=false \
--set rbac.serviceAccount.name=cluster-autoscaler
$CLUSTER_NAME="<cluster name>"
$IMAGE_TAG="<image tag (ex. 1.27.2)>"
$REGION="<region code>"
helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm install cluster-autoscaler autoscaler/cluster-autoscaler `
--namespace kube-system `
--set autoDiscovery.clusterName=$CLUSTER_NAME `
--set awsRegion=$REGION `
--set cloudProvider=aws `
--set extraArgs.logtostderr=true `
--set extraArgs.stderrthreshold=info `
--set extraArgs.v=4 `
--set extraArgs.skip-nodes-with-local-storage=false `
--set extraArgs.expander=least-waste `
--set extraArgs.balance-similar-node-groups=true `
--set extraArgs.skip-nodes-with-system-pods=false `
--set image.tag=v$IMAGE_TAG `
--set rbac.serviceAccount.create=false `
--set rbac.serviceAccount.name=cluster-autoscaler
Kubernetes | CA | Default |
---|---|---|
1.27 | 1.27.3 | default |
1.26 | 1.26.4 | |
1.25 | 1.25.3 | |
1.24 | 1.24.3 | |
1.23 | 1.23 |
Go to here and please check the new version of your kubernetes version. (2023-08-09)
Using Karpenter
Add tags to subnets
Add tags to security groups
Create the Karpenter Controller policy
STACK_NAME=""
PROJECT_NAME=""
REGION=""
### Policy Configuration
PolicyName="" # [REQUIRED] The name of service account's IAM policy.
### EKS Configuration
ClusterName="" # [REQUIRED] The name of EKS cluster.
NodeRoleName="" # [REQUIRED] The name of EKS node's role.
### SQS Configuration
QueueName="" # [REQUIRED] The name of SQS queue for NTH.
curl -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/karpenter-controller-policy.yaml
aws cloudformation deploy \
--template-file ./karpenter-controller-policy.yaml \
--stack-name $STACK_NAME \
--parameter-overrides \
PolicyName=$PolicyName \
ClusterName=$ClusterName \
NodeRoleName=$NodeRoleName \
QueueName=$QueueName \
--tags project=$PROJECT_NAME \
--capabilities CAPABILITY_NAMED_IAM \
--disable-rollback \
--region $REGION
$STACK_NAME=""
$PROJECT_NAME=""
$REGION=""
### Policy Configuration
$PolicyName="" # [REQUIRED] The name of service account's IAM policy.
### EKS Configuration
$ClusterName="" # [REQUIRED] The name of EKS cluster.
$NodeRoleName="" # [REQUIRED] The name of EKS node's role.
### SQS Configuration
$QueueName="" # [REQUIRED] The name of SQS queue for NTH
curl.exe -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/karpenter-controller-policy.yaml
aws cloudformation deploy `
--template-file ./karpenter-controller-policy.yaml `
--stack-name $STACK_NAME `
--parameter-overrides `
PolicyName=$PolicyName `
ClusterName=$ClusterName `
NodeRoleName=$NodeRoleName `
QueueName=$QueueName `
--tags project=$PROJECT_NAME `
--capabilities CAPABILITY_NAMED_IAM `
--disable-rollback `
--region $REGION
Create the service account
POLICY_NAME="<policy name>"
ROLE_NAME="<role name>"
CLUSTER_NAME="<cluster name>"
PROJECT_NAME="<project name>"
REGION="<region code>"
POLICY_ARN=$(aws iam list-policies \
--query "Policies[?PolicyName=='$POLICY_NAME'].Arn" --output text)
eksctl create iamserviceaccount \
--cluster=$CLUSTER_NAME \
--namespace=karpenter \
--name=karpenter \
--role-name=$ROLE_NAME \
--attach-policy-arn=$POLICY_ARN \
--region $REGION \
--approve
$POLICY_NAME="<policy name>"
$ROLE_NAME="<role name>"
$CLUSTER_NAME="<cluster name>"
$PROJECT_NAME="<project name>"
$REGION="<region code>"
$POLICY_ARN = aws iam list-policies `
--query "Policies[?PolicyName=='$POLICY_NAME'].Arn" --output text
eksctl create iamserviceaccount `
--cluster=$CLUSTER_NAME `
--namespace=karpenter `
--name=karpenter `
--role-name=$ROLE_NAME `
--attach-policy-arn=$POLICY_ARN `
--region $REGION `
--approve
Note
If you use CMK in SQS queue, you should add below policy.
Install Karpenter using helm
CLUSTER_NAME=""
NODEGROUP_ROLE_NAME=""
QUEUE_NAME=""
helm repo add karpenter https://charts.karpenter.sh/
helm repo update
helm install karpenter oci://public.ecr.aws/karpenter/karpenter \
--create-namespace \
--namespace karpenter \
--version v0.29.2 \
--set serviceAccount.create=false \
--set serviceAccount.name=karpenter \
--set settings.aws.clusterName=$CLUSTER_NAME \
--set settings.aws.defaultInstanceProfile=$NODEGROUP_ROLE_NAME \
--set settings.aws.interruptionQueueName=$QUEUE_NAME
$CLUSTER_NAME=""
$NODEGROUP_ROLE_NAME=""
$QUEUE_NAME=""
helm repo add karpenter https://charts.karpenter.sh/
helm repo update
helm install karpenter oci://public.ecr.aws/karpenter/karpenter `
--create-namespace `
--namespace karpenter `
--version v0.29.2 `
--set serviceAccount.create=false `
--set serviceAccount.name=karpenter `
--set settings.aws.clusterName=$CLUSTER_NAME `
--set settings.aws.defaultInstanceProfile=$NODEGROUP_ROLE_NAME `
--set settings.aws.interruptionQueueName=$QUEUE_NAME
Go to here and please check the new version. (2023-08-09)
Create a node template
Amazon Linux 2 Example
Bottlerocket Example
Create a provisioner
provisioner | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
|
Deploy Overprovisioning Pod
overprovisioning.yaml
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: overprovisioning
value: -1
globalDefault: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
run: overprovisioning
template:
metadata:
labels:
run: overprovisioning
spec:
priorityClassName: overprovisioning
containers:
- name: reserve-resources
image: k8s.gcr.io/pause
resources:
requests:
cpu: 820m
memory: 2000Mi
# tolerations:
# - key: "key1" # taint key
# value: "value1" # taint value
# operator: "Equal"
# effect: "NoSchedule"
# nodeSelector:
# key: value # node label key and value