Karpenter 企业弹性容量与中断控制
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| ACK | Acknowledgement | 消息或数据接收确认 |
| AMI | Amazon Machine Image | Amazon 系统镜像 |
| API | Application Programming Interface | 应用程序编程接口 |
| AWS | Amazon Web Services | 亚马逊云服务 |
| CRD | Custom Resource Definition | Kubernetes 自定义资源定义 |
| DLQ | Dead-Letter Queue | 死信队列 |
| DNS | Domain Name System | 域名系统 |
| EC2 | Elastic Compute Cloud | AWS 云服务器服务 |
| ECR | Elastic Container Registry | AWS 容器镜像仓库 |
| EKS | Elastic Kubernetes Service | AWS 托管 Kubernetes 服务 |
| FIS | Fault Injection Service | AWS 故障注入服务 |
| HPA | Horizontal Pod Autoscaler | Pod 水平自动扩缩容器 |
| IaC | Infrastructure as Code | 基础设施即代码 |
| IAM | Identity and Access Management | 身份与访问管理 |
| ID | Identifier | 标识符 |
| KMS | Key Management Service | 密钥管理服务 |
| PDB | Pod Disruption Budget | Pod 中断预算,约束自愿驱逐 |
| SQS | Simple Queue Service | AWS 消息队列服务 |
| SSM | AWS Systems Manager | AWS 系统管理服务;SSM 是沿用的简称 |
| STS | Security Token Service | 安全令牌服务,用于签发或交换短期凭据 |
场景:为订单 worker 提供有预算上限的弹性 EC2 容量。本文用于自行管理 Karpenter 的 EKS,不是 Auto Mode 的 NodeClass 配置。前置:企业基线、组件身份,已有固定按需系统节点组承载 Karpenter/DNS。
AWS 前置资源必须齐全#
固定 Karpenter release,按该版本的官方 CloudFormation/IaC 建立 controller IAM、节点角色与 EKS access entry、实例 profile 管理权限、EventBridge→SQS 中断队列。参考 安装与基础设施。已有集群不执行教程中的建集群/删集群命令。
权限审查重点:EC2 资源创建/终止使用 cluster/nodepool 标签条件;PassRole 只给节点角色;SQS 只给专属中断队列。子网/安全组使用独立 discovery 标签或精确 ID;KMS、ECR、SSM、STS、EC2 API 的私网/出口完整。
export KARPENTER_VERSION='REPLACE_VERSION'
helm show values oci://public.ecr.aws/karpenter/karpenter --version "$KARPENTER_VERSION" > karpenter-defaults.yaml保存 karpenter-values.yaml,替换参数,系统节点上要有足够两个副本容量:
replicas: 2
nodeSelector: {workload: system}
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: REPLACE_CONTROLLER_ROLE_ARN
settings:
clusterName: REPLACE_CLUSTER
interruptionQueue: REPLACE_QUEUE_NAME
controller:
resources:
requests: {cpu: "1", memory: 1Gi}
limits: {memory: 1Gi}helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter --version "$KARPENTER_VERSION" -n karpenter --create-namespace -f karpenter-values.yaml --wait --timeout 10m
kubectl -n karpenter get pods -o wideCRD 升级独立审核(使用该 release 的 karpenter-crd Chart/官方步骤),不要只升级 controller image。安装时检查 CRD 已存在及 ownership。升级指导
Hands-on:受限 NodePool#
保存 orders-capacity.yaml;AMI 用已经预演的精确 ID,不用 @latest。示例使用按需容量先完成验收,再独立建 Spot worker pool 演练中断:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata: {name: orders}
spec:
role: REPLACE_NODE_ROLE_NAME
amiFamily: AL2023
amiSelectorTerms:
- id: ami-REPLACE_VERIFIED_AMI
subnetSelectorTerms:
- tags: {karpenter.sh/discovery: REPLACE_CLUSTER}
securityGroupSelectorTerms:
- id: sg-REPLACE_NODE_SECURITY_GROUP
metadataOptions:
httpEndpoint: enabled
httpTokens: required
httpPutResponseHopLimit: 1
tags: {Team: commerce, Environment: staging}
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata: {name: orders}
spec:
template:
metadata:
labels: {workload: orders}
spec:
nodeClassRef: {group: karpenter.k8s.aws, kind: EC2NodeClass, name: orders}
taints: [{key: workload, value: orders, effect: NoSchedule}]
requirements:
- {key: kubernetes.io/arch, operator: In, values: [amd64]}
- {key: karpenter.sh/capacity-type, operator: In, values: [on-demand]}
- {key: karpenter.k8s.aws/instance-category, operator: In, values: [c, m, r]}
- {key: karpenter.k8s.aws/instance-generation, operator: Gt, values: ["5"]}
expireAfter: 720h
terminationGracePeriod: 1h
limits: {cpu: "100", memory: 400Gi}
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 5m
budgets: [{nodes: "1"}]kubectl apply --dry-run=server -f orders-capacity.yaml
kubectl apply -f orders-capacity.yaml
kubectl get ec2nodeclasses,nodepools,nodeclaims业务 worker 清单增加 nodeSelector: {workload: orders} 和匹配 toleration,requests 必须实测;系统组件不迁入该池。NodePool limits 存在最终一致性,不能当绝对实时账单限额。NodePool
企业验收与恢复#
通过真实队列积压/HPA 创建 Pending worker,验证 NodeClaim→EC2→注册→就绪→业务消费,记录耗时和账单。停止压力后验证 consolidation 只迁移可安全驱逐的任务;PDB、ACK/幂等与退出宽限共同发挥作用。
Spot 演练使用批准范围内的 AWS FIS 中断测试,验证中断队列被消费、替代容量、未完成消息重投和 DLQ;不能只删除一个 Pod 充当 Spot 演练。disruption budget 不阻止所有强制终止,expireAfter 与 terminationGracePeriod 也可能结束长任务。中断边界
出问题先停止增加负载,把自愿 disruption budget 改为 0 并观察;这不能取消已开始/强制中断。恢复固定按需容量后迁移业务。删除 NodePool/NodeClaim 可导致节点被终止,不是普通卸载操作;升级回退也必须确认 CRD/存量对象兼容。