跳转到内容

Karpenter 面试题

30 道题
分类
Kubernetes
子分类
scheduler
题目数
30 道
已阅读 0 / 30 题
1 Karpenter 的核心架构和目标是什么?

答案:

Karpenter 是开源的 Kubernetes 节点生命周期管理工具,由 AWS 维护,专注于提升集群效率与成本。核心工作流程为四步循环:

  1. Watch:监听被 Kubernetes Scheduler 标记为 Unschedulable 的 Pod
  2. Evaluate:评估 Pod 调度约束(资源请求、选择器、亲和性、容忍、拓扑分布)
  3. Provision:启动满足 Pod 需求的节点(EC2 实例)
  4. Disrupt:节点不再需要时主动回收(合并、过期、漂移、中断)

核心优势:

  • 无需管理节点组(Node Group),直接通过 API 启动实例
  • 原生整合 Kubernetes 调度语义(声明式 label/taint/affinity)
  • 持续成本优化(Consolidation 机制自动替换为更便宜的实例)
  • 支持现货(Spot)、按需(On-Demand)、预留容量(Capacity Reservation)
2 Karpenter 的 CRD 体系包含哪些资源?各自的作用是什么?

答案:

Karpenter 定义三类核心 CRD:

CRDAPI 版本作用
NodePoolkarpenter.sh/v1定义节点池的调度约束、实例类型限制、中断策略、资源上限
EC2NodeClasskarpenter.k8s.aws/v1AWS 特定配置:子网、安全组、AMI 选择、IAM 角色、块设备映射
NodeClaimkarpenter.sh/v1代表一次节点创建请求,不可变,Karpenter 内部管理,跟踪节点生命周期

关系:

  • NodePool 通过 spec.template.spec.nodeClassRef 引用 EC2NodeClass
  • Karpenter 为每个待调度 Pod 创建 NodeClaim,NodeClaim 成功后再创建 Kubernetes Node
  • 一个 NodePool 可引用一个 EC2NodeClass,多个 NodePool 可共享同一个 EC2NodeClass
3 NodePool 的核心配置字段有哪些?

答案:

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      requirements:
      - key: kubernetes.io/arch
        operator: In
        values: ["amd64"]
      - key: karpenter.sh/capacity-type
        operator: In
        values: ["on-demand"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      taints:
      - key: gpu
        value: "true"
        effect: NoSchedule
      startupTaints:
      - key: node.cilium.io/agent-not-ready
        effect: NoExecute
      expireAfter: 720h
      terminationGracePeriod: 1h
  limits:
    cpu: 1000
    memory: 1000Gi
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
    budgets:
    - nodes: 10%
  weight: 10
  replicas: 0  # 静态容量模式(静态节点池)
字段说明
requirements调度约束(实例类型、架构、AZ、容量类型等)
nodeClassRef引用云提供商 NodeClass
taints节点污点,Pod 需匹配容忍
startupTaints临时污点,初始化完成后自动移除
expireAfter节点最长寿命,过期后强制驱逐(默认 720h)
terminationGracePeriod强制终止前的最大等待时间
limitsNodePool CPU/内存/GPU 上限
disruption中断策略(合并、预算)
weight多 NodePool 优先级权重
replicas静态节点池(固定节点数量)
4 EC2NodeClass 的核心配置字段有哪些?

答案:

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  role: KarpenterNodeRole
  amiFamily: AL2023
  amiSelectorTerms:
  - alias: al2023@latest
  subnetSelectorTerms:
  - tags:
      karpenter.sh/discovery: my-cluster
  securityGroupSelectorTerms:
  - tags:
      karpenter.sh/discovery: my-cluster
  blockDeviceMappings:
  - deviceName: /dev/xvda
    ebs:
      volumeSize: 100Gi
      volumeType: gp3
      encrypted: true
  tags:
    Environment: production
  metadataOptions:
    httpTokens: required
    httpPutResponseHopLimit: 1
  detailedMonitoring: true
  instanceStorePolicy: RAID0
  userData: |
    # custom bootstrap script    
  kubelet:
    maxPods: 110
    systemReserved:
      cpu: 500m
      memory: 512Mi
字段说明
role / instanceProfileIAM 角色(role 自动管理,instanceProfile 手动管理)
amiFamilyAMI 类型:AL2、AL2023、Bottlerocket、Windows2019+/Custom
amiSelectorTermsAMI 选择(alias/id/tags/name/ssmParameter)
subnetSelectorTerms子网选择(tags / id)
securityGroupSelectorTerms安全组选择(tags / name / id)
blockDeviceMappingsEBS 卷配置
tags传播到 EC2/EBS/Launch Template 的标签
metadataOptionsIMDS 配置
detailedMonitoring是否启用 EC2 详细监控(1 分钟 CloudWatch)
instanceStorePolicy实例存储策略(RAID0)
kubeletkubelet 参数覆盖
userData自定义启动脚本,与 AMI 家族默认值合并
5 Karpenter 的约束分层模型(Layered Constraints)是如何工作的?

答案:

Karpenter 使用三层约束叠加的调度模型:

第1层(云提供商) →  所有可用实例类型、架构、可用区、购买类型
第2层(NodePool)  →  集群管理员设置的 requirements、limits
第3层(Pod Spec)  →  nodeSelector、nodeAffinity、podAffinity、topologySpreadConstraints、资源请求
  • Pod 约束必须在 NodePool 约束范围内,否则不会调度
  • NodePool 约束收紧 Pod 的可选范围,但不能扩宽
  • 所有约束层叠加后,Karpenter 在交集内选择最优实例类型
  • 标签通过 Exists 运算符在 NodePool 中声明后,Pod 才能使用
6 Karpenter 如何处理 Pod 与 NodePool 的匹配?

答案:

Karpenter 的匹配流程:

  1. Pod 被 Kubernetes Scheduler 标记为 Unschedulable=True
  2. Karpenter 遍历所有 NodePool,检查 Pod 约束(资源请求、nodeSelector、亲和性、容忍)是否符合 NodePool 的 requirements
  3. Pod 必须容忍 NodePool 的 taints
  4. 匹配到多个 NodePool 时,按 spec.weight 优先级选择(高权重优先)
  5. 选择最高权重 NodePool 后,计算合适的实例类型和数量
  6. 创建 NodeClaim,由 EC2NodeClass 负责启动实例

注意事项:

  • NodePool 应尽量互斥,避免模糊匹配
  • 由于 Pod 批处理和装箱策略,高权重 NodePool 不保证总是优先选中
  • status.conditions.Ready 为 False 的 NodePool 不会被纳入调度
7 Karpenter 支持的实例类型筛选标签有哪些?

答案:

Karpenter 通过 well-known 标签和 AWS 特定标签筛选实例类型:

标签说明示例值
kubernetes.io/archCPU 架构amd64, arm64
kubernetes.io/os操作系统linux, windows
node.kubernetes.io/instance-type具体实例类型m5.large, p3.8xlarge
karpenter.k8s.aws/instance-family实例家族m5, c5, r5
karpenter.k8s.aws/instance-category实例类别c(计算), m(通用), r(内存)
karpenter.k8s.aws/instance-generation实例代数Gt 2(大于第 2 代)
karpenter.k8s.aws/instance-cpuCPU 核数Lte 8
karpenter.k8s.aws/instance-memory内存大小Gte 16384(>= 16GiB)
karpenter.k8s.aws/instance-gpu-countGPU 数量Gte 1
karpenter.k8s.aws/instance-gpu-nameGPU 型号In [t4, a10g]
karpenter.k8s.aws/instance-accelerator-manufacturer加速器厂商nvidia, amd, aws
topology.kubernetes.io/zone可用区us-west-2a
karpenter.sh/capacity-type容量类型spot, on-demand, reserved

Karpenter 扩展了标准 Kubernetes 运算符,额外支持 Gt(>)、Gte(>=)、Lt(<)、Lte(<=) 用于数值比较。

8 Karpenter 如何选择实例类型?

答案:

实例类型选择完全基于 Pod 的 resource.requests(而非 limits),遵循以下流程:

  1. 收集所有待调度 Pod 的资源需求总和(CPU、内存、GPU、Neuron 等)
  2. 结合 NodePool 的约束(instance-category、instance-generation、架构等)
  3. 从可用实例类型中筛选出满足需求的类型列表
  4. 按价格从低到高排序,选择最优实例
  5. 支持跨实例家族的灵活选择,不限定单一实例类型

装箱策略:

  • 支持 GPU 装箱(同一节点可放置多个 GPU Pod)
  • Neuron 资源要求 Pod 的 request 为 2 的幂次(1、2、4、8),否则可能导致 Pod 永久 Pending
  • nodeSelectorTerms 按定义顺序处理,取第一个成功的 term
9 Karpenter 的 Consoldation 机制是如何工作的?

答案:

Consolidation 是 Karpenter 主动降低成本的核心机制,通过三种方式回收节点:

三种合并模式(按优先级顺序执行):

1. Empty Node Consolidation → 并行删除完全空节点
2. Multi Node Consolidation → 合并两个以上节点,启动一个更便宜的替代节点
3. Single Node Consolidation → 删除单个节点,可替换为更低价实例

触发策略:

consolidationPolicy行为
WhenEmptyOrUnderutilized(默认)所有节点只要 consolidateAfter 到期即可考虑合并
WhenEmpty仅无工作负载 Pod 的空节点才合并

注意事项:

  • 合并执行前先运行调度模拟,确保工作负载能重新调度到其他节点
  • 合并失败时取消节点汚染,回滚操作
  • 多节点合并使用启发式算法,单节点合并逐个检查
  • 优先选择干扰最小的节点(Pod 少、即将过期、优先级低)
  • 使用 preferred Anti-Affinity 和 Topology Spread 会降低合并效果
10 Karpenter 的 Drift(漂移)机制是什么?

答案:

Drift 检测 NodeClaim 与其所属 NodePool 或 EC2NodeClass 配置之间的不一致,自动驱散漂移节点。

触发的字段变更:

资源触发 Drift 的字段
NodePoolspec.template.spec.requirements
EC2NodeClassspec.subnetSelectorTermsspec.securityGroupSelectorTermsspec.amiSelectorTerms

不触发 Drift 的字段:

  • spec.weightspec.limitsspec.disruption.*

漂移检测机制:

  • Karpenter 在 NodeClaim 上添加 karpenter.sh/nodepool-hashkarpenter.k8s.aws/ec2nodeclass-hash 注解
  • 配置变更时重新计算 Hash,不一致则标记 Drifted 状态条件
  • EC2NodeClass 的动态字段(如 AMI 选择器解析出新 AMI)即使 CRD 未变化也可能触发漂移
11 Karpenter 的 Expiration(过期)机制是什么?

答案:

Expiration 强制节点在达到最大生命周期后自动驱逐,由 NodePool 的 spec.template.spec.expireAfter 控制(默认 720h / 30 天)。

关键行为:

  • 过期是强制性的:跳过 Disruption Budget 检查,不等待预创建替代节点
  • 修改 expireAfter 会触发已有 NodeClaim 的 Drift,新节点使用新值
  • 过期定义的是上限而非保证寿命,其他中断机制(合并、漂移)可提前回收

安全配置:

  • 存在 karpenter.sh/do-not-disrupt 注解或 PDB 配置不当的 Pod 可能阻塞过期节点排空
  • 建议搭配 terminationGracePeriod 使用,防止节点永久卡在 Terminating 状态
12 Karpenter 的 Interruption(中断处理)机制是什么?

答案:

Karpenter 监听 AWS 基础设施中断事件,在事件发生前主动驱散节点,减少工作负载中断。

处理的事件类型:

  • Spot Interruption Warning(2 分钟提前通知)
  • Scheduled Change Health Events(计划维护事件)
  • Instance Terminating / Stopping Events
  • Instance Status Check Failures(系统状态检查 + 实例状态检查)

工作原理:

AWS EventBridge → SQS Queue → Karpenter Controller
  → Cordon + Drain Pods + Terminate Instance
  → 同时并行启动替代节点

基础设施依赖:

  • SQS 队列(通过 --interruption-queuesettings.interruptionQueue 配置)
  • EventBridge 规则转发 AWS 健康事件到 SQS
  • EC2 DescribeInstanceStatus API(无需 SQS 即可检测状态检查失败)

注意: Karpenter 目前不支持 Spot Rebalance Recommendation 的 taint/drain/terminate,建议搭配 AWS Node Termination Handler(NTH)处理此类场景。

13 Karpenter 的 Disruption Budget 如何配置?

答案:

Disruption Budget 限制 NodePool 中可同时中断的节点比例,控制合并/漂移速度。

spec:
  disruption:
    budgets:
    - nodes: "20%"
      reasons:
      - "Empty"
      - "Drifted"
    - nodes: "5"
    - nodes: "0"
      schedule: "@daily"
      duration: 10m
      reasons:
      - "Underutilized"

规则:

  • 默认 budget:nodes: 10%
  • 百分比计算:allowed = roundup(total × 百分比) - deleting - notReady
  • 固定值计算:allowed = 固定值 - deleting - notReady
  • reasons 过滤:Drifted、Underutilized、Empty
  • 支持 cron 定时预算(UTC 时区)
  • 多个 budget 同时生效时取最小值
  • 控制 Expiration(过期跳过 budget)
14 Karpenter 的 NodeClaim 生命周期是怎样的?

答案:

NodeClaim 是 Karpenter 管理节点生命周期的核心抽象,不可变,由 Karpenter 自动创建和删除。

6 步生命周期:

步骤 1: Pod Watching & Cross-Referencing
  → Karpenter 发现 Unschedulable Pod,交叉匹配 NodePool + EC2NodeClass
  
步骤 2: Compute NodeClaim Shape
  → 计算节点形状和大小以容纳待调度 Pod

步骤 3: Object Creation
  → 在集群中创建 NodeClaim 对象(kubectl get nodeclaims 可查看)

步骤 4: Launch(云提供商 API 调用)
  → 调用 EC2 API 启动实例,失败回退(标记类型不可用,换类型重试)

步骤 5: Registration
  → 实例注册到集群后,Karpenter 更新标签/注解/污点/终结器
  → 移除 karpenter.sh/unregistered 污点(15 分钟超时)

步骤 6: Initialization
  → 等待节点就绪、startupTaints 移除、资源注册完成

状态条件追踪:

条件含义
Launched云提供商实例已创建
Registered实例已加入集群
Initialized节点就绪、污点移除、资源注册
Ready完全可用
Consolidatable可参与合并决策
15 Karpenter 如何处理 PVC 和存储拓扑感知调度?

答案:

Karpenter 自动检测存储拓扑约束,确保新节点与 Pod 的存储需求在同一可用区。

自动推导流程:

  1. Pod → 引用 PVC → 检查 PV 的 zone 标签或 StorageClass 的 allowedTopologies
  2. 如果 PV 已存在,其 zone 被纳入调度约束
  3. EBS CSI 驱动标签 topology.ebs.csi.aws.com/zone 在内存中别名为 topology.kubernetes.io/zone
  4. topology.kubernetes.io/region 不支持

权限依赖:

  • Karpenter 需要 ec2:DescribeAvailabilityZones 权限来验证可用区
  • 存储拓扑约束自动缩小实例类型选择范围到对应可用区
16 Karpenter 如何处理 GPU/加速器节点?

答案:

GPU 节点通过 karpenter.k8s.aws/instance-gpu-countkarpenter.k8s.aws/instance-gpu-name 标签筛选。

典型 GPU NodePool 配置:

spec:
  template:
    spec:
      requirements:
      - key: karpenter.k8s.aws/instance-gpu-count
        operator: Gte
        values: ["1"]
      - key: karpenter.k8s.aws/instance-gpu-name
        operator: In
        values: ["t4", "a10g", "a100"]
      - key: karpenter.sh/capacity-type
        operator: In
        values: ["on-demand"]
      taints:
      - key: nvidia.com/gpu
        value: "true"
        effect: NoSchedule
      nodeClassRef:
        name: gpu

注意事项:

  • GPU 实例通常打污点防止非 GPU Pod 调度
  • NVIDIA 驱动安装依赖 AMI 选择(AL2023 + NVIDIA 加速器 AMI)
  • 多个 GPU Pod 可装箱到同一节点(基于 resources.requests["nvidia.com/gpu"]
  • 使用 karpenter.k8s.aws/instance-accelerator-manufacturer 区分 GPU 提供商(nvidia/amd/aws)
17 Karpenter 的 Spot 容量策略是什么?

答案:

Karpenter 通过 karpenter.sh/capacity-type 标签管理容量类型,优先级为 reserved → spot → on-demand

Spot 机制:

  • 容量类型不可用时缓存 3 分钟,然后降级到下一优先级
  • Spot 中断处理通过 Interruption 机制自动驱散(2 分钟提前通知)
  • Spot 节点默认启用删除合并,替换合并需要 SpotToSpotConsolidation 特性标志
  • Spot 到 Spot 的替换使用 price-capacity-optimized 策略,要求至少 15 种实例类型灵活性
requirements:
- key: karpenter.sh/capacity-type
  operator: In
  values: ["spot", "on-demand"]  # 优先 spot,不可用时回退 on-demand

安全建议:

  • 混合 spot + on-demand 提高可用性
  • 关键工作负载使用 node.kubernetes.io/instance-type 固定实例类型,避免 Spot 容量不足时频繁切换
18 Karpenter 与 Cluster Autoscaler 的核心区别是什么?

答案:

维度KarpenterCluster Autoscaler
节点管理粒度直接管理单个实例,无需节点组依赖节点组(ASG/MIG),以组为单位扩缩
调度速度快(直接创建实例,无中间层)慢(需节点组拉起实例 + 注册)
实例灵活性自动选择最优实例类型限于节点组预设实例
成本优化内置 Consolidation(自动替换更低价格实例)仅缩容空节点
配置方式声明式 CRD(NodePool + EC2NodeClass)节点组标签 + Autodiscovery
约束模型分层约束(云提供商→NodePool→Pod)节点组模板静态配置
中断处理内置 Spot 中断、漂移、过期支持需额外组件(AWS NTH)
供应商锁定AWS 优先,但架构可扩展云厂商无关
多实例池NodePool weight 多池灵活路由多个节点组 + 节点亲和配置

选择建议:

  • Karpenter 适合追求成本优化、实例灵活性和自动化运维的场景
  • Cluster Autoscaler 适合已深度使用节点组/ASG、需要与现有基础设施兼容的场景
19 Karpenter 如何处理 Windows 节点?

答案:

EC2NodeClass 的 amiFamily 支持 Windows2019Windows2022Windows2025

Windows 特征:

  • NodePool 的 requirements 中设置 kubernetes.io/os: In [windows]
  • AMI 别名仅支持 latest(不支持固定版本)
  • 默认根卷 50Gi gp3 加密
  • UserData 合并:PowerShell 命令前置到 Karpenter 的 bootstrap 部分
  • Windows 版本只能通过对应 AMI 家族选择,不支持通过 AMI 选择器混用 Linux AMI

限制:

  • 需要 Windows 节点的 EKS 集群
  • 需要容器运行时兼容 Windows 镜像
  • 部分 Kubernetes 特性(如 hostNetwork)在 Windows 上的行为不同
20 Karpenter 的静态节点池(Static NodePool)是什么?

答案:

静态节点池通过 spec.replicas 字段维护固定数量的节点,不受工作负载需求影响。

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: static-pool
spec:
  replicas: 10
  template:
    spec:
      requirements:
      - key: topology.kubernetes.io/zone
        operator: In
        values: ["us-west-2a"]
      - key: node.kubernetes.io/instance-type
        operator: In
        values: ["m5.large", "m5.xlarge"]
      nodeClassRef:
        name: default
  limits:
    nodes: 15
  disruption:
    budgets:
    - nodes: 20%
      reasons:
      - "Drifted"

关键约束:

  • 设置 replicas 后不可切换回动态模式(单向操作)
  • limits 中仅允许 nodes 字段
  • 不可同时设置 weight
  • 节点不参与合并决策
  • 通过 kubectl scale nodepool <name> --replicas=N 调整数量
  • 允许 Drift 触发节点替换
21 Karpenter 如何处理自有 AMI 的定制化需求?

答案:

EC2NodeClass 的 amiSelectorTerms 支持多种 AMI 选择方式。

选择方式:

amiSelectorTerms:
# 1. 官方别名(自动管理版本)
- alias: al2023@latest  # 或 al2023@v20240703 固定版本

# 2. 标签选择(最灵活)
- tags:
    karpenter.sh/discovery: my-cluster
    environment: custom-ami

# 3. 名称 + 所有者
- name: my-custom-ami-*
  owner: "0123456789"

# 4. SSM 参数
- ssmParameter: /aws/service/eks/optimized-ami/1.31/amazon-linux-2023/x86_64/standard/recommended/image_id

# 5. ID 直接指定
- id: ami-0abcdef1234567890

AMI 家族与 UserData 合并策略:

AMI 家族UserData 合并
AL2023支持 bash/NodeConfig/MIME,Karpenter 追加 NodeConfig
AL2用户 bash/MIME 追加到 Karpenter bootstrap 部分
BottlerocketTOML 格式,Karpenter 值优先
Custom无默认值,用户必须自行处理全部启动逻辑

生产建议:

  • 固定 AMI 而非使用 latest,避免意外漂移
  • 使用 Deprecated AMI 状态标记帮助识别过期 AMI
  • 使用 spec.blockDeviceMappings 自定义根卷大小和类型
22 Karpenter 的私有集群(Private Cluster / Isolated VPC)配置要点?

答案:

私有集群没有公网访问,Karpenter 需要额外配置。

eksctl 配置: privateCluster.enabled: true

Helm 参数: --set settings.isolatedVPC=true

所需 VPC 终端节点:

服务用途
ec2实例管理
ecr.api / ecr.dkr容器镜像拉取
s3镜像层
stsIRSA(IAM Role for Service Account)
ssm默认 AMI 解析
sqs中断处理
eks集群端点发现

IAM 实例配置文件(私有集群必须):

IAM API 没有 VPC 终端节点,spec.role 方式无法在私有集群中工作。必须手动创建实例配置文件名:

spec:
  instanceProfile: "KarpenterNodeInstanceProfile-${CLUSTER_NAME}"
  # 不指定 role(否则 Karpenter 会尝试调用 IAM API)

定价数据: 无 VPC 终端节点用于 Price List API,Karpenter 使用发布时内置的静态定价数据。

23 Karpenter 如何处理 Node 终结器(Finalizer)?

答案:

Karpenter 自动在每个由其创建(管理)的节点上添加 karpenter.sh/termination 终结器。

Termination 流程:

kubectl delete node <name>
  → Karpenter 终结器拦截删除请求
  → cordon 节点(禁用调度)
  → drain 节点(通过 Eviction API,遵守 PDB)
  → 等待 VolumeAttachment 删除
  → 终止 EC2 实例
  → 移除 node 对象和终结器

关键特性:

  • 仅对 Karpenter 管理的节点有效(非 Karpenter 创建的节点不受影响)
  • 确保节点删除前 Pod 被优雅排空
  • 使用 Kuberentes Eviction API,尊重 PodDisruptionBudget
  • 如果存在 karpenter.sh/do-not-disrupt 注解的 Pod,排空会被阻塞
24 Karpenter 的 StartupTaints 机制是什么?用于什么场景?

答案:

StartupTaints 是节点启动时设置的临时污点,系统组件完成初始化后由外部 Agent 移除。

spec:
  template:
    spec:
      startupTaints:
      - key: node.cilium.io/agent-not-ready
        effect: NoExecute

与普通 Taints 的区别:

维度TaintsStartupTaints
持久性永久临时(初始化完成后移除)
Pod 调度条件Pod 必须容忍Pod 不需要容忍
移除方式需手动或 system 组件Agent 启动后自动移除
用途限制谁可以调度阻止 Pod 在依赖初始化完成前调度

典型场景:

  • Cilium 网络初始化完成前阻止业务 Pod 启动
  • CSI 驱动或监控 Agent 先于工作负载启动
  • 节点注册后需要执行初始化脚本

警告: StartupTaints 配置不准确会导致 Karpenter 无限循环创建新节点(因为无法触发初始化完成条件时,Karpenter 认为节点未就绪)。

25 Karpenter 支持哪几种 Capacity Reservation?

答案:

EC2NodeClass 通过 spec.capacityReservationSelectorTerms 选择 On-Demand Capacity Reservations(ODCR)。

spec:
  capacityReservationSelectorTerms:
  - id: cr-123456
  - tags:
      environment: production
  - instanceMatchCriteria: open
  - instanceMatchCriteria: targeted
    tags:
      project: my-app
    ownerID: "012345678901"

选择方式:

方式说明
ID指定具体预留 ID
Tags标签匹配(AND)
instanceMatchCriteriaopen(开放匹配)或 targeted(定向匹配)
ownerID账户 ID,可与 tags 或 criteria 组合

优先级: Karpenter 优先使用 Capacity Reservation,然后回退到按需和 Spot。

状态追踪: status.capacityReservations 输出每个预留的可用区、ID、实例类型、匹配条件、类型(default/capacity-block)、状态(active/expiring)、是否可中断。

26 Karpenter 的 Drift 检测如何处理 AMI 更新场景?

答案:

AMI 更新场景是 Drift 机制中最常见的触发场景之一,行为有所不同于 CRD 字段变更。

场景举例:

  1. EC2NodeClass 使用 amiSelectorTerms[].alias: al2023@latest
  2. AWS 发布新的 AL2023 AMI(含安全补丁)
  3. AMI 选择器重新解析指向新 AMI
  4. Karpenter 检测到已运行节点的 AMI 与当前解析结果不匹配
  5. 将这些节点标记为 Drifted 状态
  6. 根据 Disruption Budget 逐批驱逐并替换节点

特殊逻辑:

  • 即使 EC2NodeClass 的 YAML 未变化(因为 latest 本身不变),但解析结果变了,仍触发 Drift
  • 使用固定别名(如 al2023@v20240703)避免意外漂移
  • AMI 的 Deprecated 状态帮助标识不可用 AMI

生产建议:

  • 生产环境不使用 latest,使用固定版本别名
  • 通过 CI/CD 流程控制 AMI 更新节奏
  • 结合 Disruption Budget 控制漂移速率,避免大规模节点同时替换
27 Karpenter 的 metrics 体系包含哪些关键指标?

答案:

Karpenter 在 :8080/metrics 暴露 Prometheus 格式指标,覆盖 20 个类别,约 100+ 指标。

关键指标分类:

类别关键指标稳定度
Provisioningkarpenter_nodeclaims_created_totalkarpenter_nodes_created_totalSTABLE
Terminationkarpenter_nodeclaims_terminated_totalkarpenter_nodes_terminated_totalSTABLE
Disruptionkarpenter_voluntary_disruption_decisions_totalkarpenter_voluntary_disruption_eligible_nodesSTABLE
Schedulerkarpenter_scheduler_scheduling_duration_secondskarpenter_scheduler_unschedulable_pods_countSTABLE
Interruptionkarpenter_interruption_received_messages_totalkarpenter_interruption_message_queue_duration_secondsSTABLE
Node 资源karpenter_nodes_total_pod_requestskarpenter_nodes_allocatableBETA
CloudProviderkarpenter_cloudprovider_errors_totalkarpenter_cloudprovider_duration_secondsBETA
Cluster Statekarpenter_cluster_state_syncedSTABLE

推荐告警规则:

  • karpenter_scheduler_unschedulable_pods_count > 0 持续 5 分钟:可能存在配置问题
  • karpenter_cloudprovider_errors_total 快速增加:检查 AWS API 权限
  • karpenter_nodeclaims_terminated_total 异常突增:排查中断原因
  • karpenter_cluster_state_synced == 0:Karpenter 状态不同步

内置 Grafana Dashboard: Karpenter 提供预构建 Dashboard,通过 Helm 安装。

28 Karpenter 的 Kubelet 配置支持哪些自定义参数?

答案:

EC2NodeClass 的 spec.kubelet 字段支持配置以下 kubelet 参数:

spec:
  kubelet:
    maxPods: 110                    # 覆盖 ENI 默认 Pod 密度上限
    podsPerCore: 10                 # 动态 Pod 密度(与 maxPods 取小值)
    systemReserved:
      cpu: 500m
      memory: 512Mi
      ephemeral-storage: 5Gi
    kubeReserved:
      cpu: 200m
      memory: 256Mi
    evictionHard:
      memory.available: 5%
      nodefs.available: 10%
      nodefs.inodesFree: 5%
    evictionSoft:
      memory.available: 10%
    evictionSoftGracePeriod:
      memory.available: 1m30s
    evictionMaxPodGracePeriod: 60
    imageGCHighThresholdPercent: 85
    imageGCLowThresholdPercent: 80
    cpuCFSQuota: true
    clusterDNS:
    - 10.100.0.10

不支持但可通过 UserData 设置的参数:

  • registryPullQPSeventRecordQPS 等 kubelet 参数
  • AL2023:通过 UserData 中的 NodeConfig spec 设置
  • Bottlerocket:通过 TOML userData 设置 [settings.kubernetes]
29 Karpenter 的节点标签传播规则是什么?

答案:

Karpenter 通过多层标签机制控制节点标签。

标签来源:

来源位置说明
NodePool labelsspec.template.metadata.labels应用到所有该 NodePool 创建的节点
NodePool requirementsspec.template.spec.requirementsIn/NotIn 约束转为节点标签
AWS well-known labels自动实例类型、可用区、架构等自动标签
EC2NodeClass tagsspec.tags传播到 EC2 实例和 EBS,不一定是 K8s 标签

自定义标签规则:

  • NodePool 必须使用 Exists 运算符声明自定义标签的 key
  • 如果 Pod 不提供 value,Karpenter 自动生成随机值
  • labels 和 requirements 合计不超过 100 项
spec:
  template:
    metadata:
      labels:
        team: platform
        environment: production
    spec:
      requirements:
      - key: custom-label-team
        operator: Exists  # 允许 Pod 使用此标签选择节点

安全标签(不可复写):

  • karpenter.sh/ 前缀
  • karpenter.k8s.aws/ 前缀
  • kubernetes.io/cluster/ 前缀
30 Karpenter 生产环境最佳实践?

答案:

NodePool 设计:

  • 使用多个 NodePool 隔离负载类型(通用计算、GPU、Windows、Spot)
  • NodePool 之间尽量互斥(通过 taints 和 requirements),避免模糊匹配
  • GPU 等特殊硬件节点打 taint + toleration 隔离

成本优化:

  • 启用 consolidationPolicy: WhenEmptyOrUnderutilized
  • 混合 Spot + On-Demand 降低计算成本
  • 使用 instance-category 和 instance-generation 约束而非固定实例类型
  • 设置 limits.cpu/limits.memory 防止无限制扩容

稳定性:

  • AMI 固定版本而非 latest,避免意外漂移
  • 配置 Disruption Budget 控制中断速率(如高峰时段限制为 0)
  • 使用 terminationGracePeriod 防止 PDB 阻塞的节点永久卡住
  • 创建 FlowSchema 防止 Karpenter API 请求被节流

安全:

  • IMDS 配置 httpTokens: required,限制 hop limit
  • karpenter.sh/managed-bykarpenter.sh/nodepool 标签实施基于标签的 IAM 策略
  • 最小权限 IAM 角色原则
  • 定期轮换节点(expireAfter: 720h

可观测性:

  • 导入预构建 Grafana Dashboard
  • 监控 karpenter_scheduler_unschedulable_pods_countkarpenter_cloudprovider_errors_total
  • 审计 NodeClaim 的 status conditions 排查节点创建失败
  • 配置 Karpenter 日志采集到集中式日志系统

容量预留:

  • 关键工作负载配置 Capacity Reservation 保证容量可用
  • 使用 reserved 容量类型作为最高优先级