在安装Karpenter
之前,需要完成以下工作:
创建好一个EKS集群
创建Karpenter需要使用到的Policy及service account
等资源。
配置环境变量:
export CLUSTER_NAME=$(eksctl get clusters -o json | jq -r '.[0].Name')
export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)"
export AZ1="$AWS_REGION"a
export AZ2="$AWS_REGION"b
echo Cluster Name:$CLUSTER_NAME AWS Region:$AWS_REGION Account ID:$AWS_ACCOUNT_ID Cluster Endpoint:$CLUSTER_ENDPOINT AZ1:$AZ1 AZ2:$AZ2
如果手头已经有EKS集群,可以跳过本部分;如果没有,用eksctl快速创建一个出来:
eksctl create cluster -f - <<EOF
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${CLUSTER_NAME}
region: ${AWS_REGION}
version: "1.27"
tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
managedNodeGroups:
- instanceType: m5.large
amiFamily: AmazonLinux2
name: ${CLUSTER_NAME}-ng
desiredCapacity: 2
minSize: 1
maxSize: 10
EOF
先将EKS集群名称、帐号id等信息保存到环境变量:
export CLUSTER_NAME=${eks_cluster_name}
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')
export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)"
由Karpenter创建出来的EC2实例也需要绑定一个Role,在这里我们创建 KarpenterNodeRole-${ClusterName}
这个InstanceProfile,来为实例授予访问ECR, 创建容器、配置ENI等相关权限:
TEMPOUT=$(mktemp)
export KARPENTER_VERSION=v0.31.1
curl -fsSL https://raw.githubusercontent.com/aws/karpenter/"${KARPENTER_VERSION}"/website/content/en/preview/getting-started/getting-started-with-karpenter/cloudformation.yaml > $TEMPOUT \
&& aws cloudformation deploy \
--stack-name Karpenter-${CLUSTER_NAME} \
--template-file ${TEMPOUT} \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides ClusterName=${CLUSTER_NAME}
这个CloudFormation创建出来的资源如下,包括一个KarpenterControllerPolicy
(绑在Karpenter Pod上)和一个NodeRole(绑在Karpenter创建出来的节点上),KarpenterControllerPolicy
后面我们会用到:
将Karpenter创建出来的节点(上面绑定着KarpenterNodeRole-xxx
),让它可以连接到EKS集群(如执行kubectl命令):
eksctl create iamidentitymapping \
--username system:node:{{EC2PrivateDNSName}} \
--cluster ${CLUSTER_NAME} \
--arn arn:aws:iam::${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
由于Karpenter POD需要有创建实例的权限,这里使用IRSA机制——创建一个service account,用于给后面的karpenter pod绑定:
eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} --approve
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"
从IAM控制台看到,这个KarpenterControllerPolicy
具有创建EC2 Fleet等权限:
这一步将花费大概两分钟,创建完成后,可以执行以下命令来检查创建的service account:
$ kubectl get serviceaccounts --namespace karpenter
NAME SECRETS AGE
default 0 73s
karpenter 0 73s