3. 安装部署与初始配置
Karpenter 的安装并不是“装一个控制器”这么简单。它同时依赖三类外部条件:云厂商的身份与权限、Kubernetes 集群内的准入与调度接口、以及节点启动所需的镜像与网络配置。任何一环缺失,控制器 Pod 可能正常运行,但节点就是起不来。因此本节按“权限 → 部署 → 配置 → 验证”的真实依赖顺序展开,并以 AWS/EKS 为主线,最后说明其他云环境的差异点。
一、先理清安装依赖关系
Karpenter 控制器需要以 AWS IAM 身份调用 EC2、SSM、IAM、Pricing、SQS 等 API,用于创建实例、读取 AMI 参数、查询价格和接收中断事件。同时,节点上运行的 kubelet 需要加入集群,这由 EKS 的 aws-auth 或 EKS Access Entry 机制授权。控制器本身通过 IRSA(IAM Roles for Service Accounts)或 EKS Pod Identity 获得权限,而不是把 AK/SK 写进配置。下图展示了这条依赖链:
二、IAM 权限配置
在 EKS 上推荐使用 EKS Pod Identity 或 IRSA。以 IRSA 为例,先为集群创建 OIDC Provider,再创建控制器角色并绑定策略。Karpenter 官方提供了 CloudFormation 模板,也可手动创建。核心策略需覆盖:ec2:RunInstances、ec2:CreateFleet、ec2:CreateLaunchTemplate、ec2:TerminateInstances、ec2:DescribeInstances、ssm:GetParameter、iam:PassRole、pricing:GetProducts、sqs:*(用于中断队列)。
节点角色(NodeRole)则需挂载 AmazonEKSWorkerNodePolicy、AmazonEKS_CNI_Policy、AmazonEC2ContainerRegistryReadOnly,并允许节点向集群注册。控制器角色通过 iam:PassRole 把节点角色传给 EC2,因此必须显式授权,否则实例创建会因权限不足失败。
# 创建 OIDC Provider(若尚未存在)
eksctl utils associate-iam-oidc-provider \
--cluster my-eks-cluster --approve
# 创建控制器 IRSA 角色(示例)
eksctl create iamserviceaccount \
--cluster my-eks-cluster \
--namespace karpenter \
--name karpenter \
--role-name KarpenterControllerRole \
--attach-policy-arn arn:aws:iam::123456789012:policy/KarpenterControllerPolicy \
--approve
三、Helm 部署控制器
Karpenter 通过 Helm Chart 安装,关键参数包括集群名称、控制器角色 ARN、中断队列名称和副本数。生产环境建议至少 2 副本并配置 PodDisruptionBudget。安装前先创建命名空间,再执行部署:
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--version 0.37.0 \
--namespace karpenter --create-namespace \
--set settings.clusterName=my-eks-cluster \
--set settings.interruptionQueue=my-eks-cluster \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/KarpenterControllerRole \
--set controller.resources.requests.cpu=1 \
--set controller.resources.requests.memory=1Gi \
--set replicas=2 \
--wait
部署完成后检查控制器状态:
kubectl -n karpenter get pods
kubectl -n karpenter logs deploy/karpenter --tail=50
日志中应出现 starting controller、starting workers 等字样,且无持续报错。若出现 AccessDenied,优先检查 IRSA 注解与信任策略中的 OIDC 条件是否匹配。
四、创建基础 NodePool 与 EC2NodeClass
Karpenter 0.33 之后,节点配置拆分为 EC2NodeClass(云资源)与 NodePool(调度与容量策略)。先创建 EC2NodeClass,声明 AMI 家族、子网发现标签、安全组和节点角色:
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: KarpenterNodeRole-my-eks-cluster
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks-cluster
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: my-eks-cluster
tags:
karpenter.sh/discovery: my-eks-cluster
再创建 NodePool,限定实例类型、容量类型与资源上限,并设置中断处理:
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
nodeClassRef:
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m5.large", "m5.xlarge", "c5.large", "c5.xlarge"]
- key: topology.kubernetes.io/zone
operator: In
values: ["ap-northeast-1a", "ap-northeast-1c"]
limits:
cpu: "100"
memory: 200Gi
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
注意 subnetSelectorTerms 与 securityGroupSelectorTerms 依赖标签发现,因此必须提前给子网和安全组打上 karpenter.sh/discovery=my-eks-cluster 标签,否则控制器找不到可用网络资源,节点无法启动。
五、验证与常见失败判断
验证分三层:控制器是否就绪、NodeClaim 是否成功、节点是否 Ready。先部署一个触发扩容的测试负载:
kubectl create deployment inflate --image=public.ecr.aws/eks-distro/kubernetes/pause:3.2
kubectl scale deployment inflate --replicas=5
kubectl -n karpenter get nodeclaims
kubectl get nodes -l karpenter.sh/nodepool=default
正常情况下,几秒到一分钟内会出现 NodeClaim,状态从 Launched 变为 Registered,随后节点进入 Ready。若长时间停留在 Launched,通常是节点角色权限不足或子网无公网/NAT 出口;若 NodeClaim 直接失败,查看 kubectl describe nodeclaim 的 Events,常见原因包括实例类型在所选可用区不可用、Spot 容量不足、AMI 查询失败。
kubectl delete deployment inflate,观察 Karpenter 是否在 consolidation 策略下回收空节点。这一步能同时验证扩容与缩容闭环,是初始配置是否真正可用的关键判据。六、其他云环境的差异
在 Azure(AKS)上,Karpenter 对应的是 Karpenter Provider for Azure,权限通过 Azure Workload Identity 授予,节点配置使用 AKSNodeClass,网络依赖 Azure CNI 与节点池子网。在通用 Kubernetes 或裸金属环境,可使用 Karpenter 的通用 Provider 或社区实现,但节点生命周期管理需自行对接云 API 或 IPMI/BMC。核心差异在于:云厂商的 NodeClass 实现不同,而 NodePool 的调度语义基本一致。因此迁移时重点替换 NodeClass 与身份配置,NodePool 策略可复用。
完成以上步骤后,集群即具备按需创建、按负载回收节点的能力。下一步应结合工作负载特征细化 NodePool 的实例类型与容量策略,并接入监控与中断处理,使弹性行为可观测、可治理。