Skip to content

Node 生命周期管理

支持的版本: EKS 1.29+, EKS Auto Mode GA 最后更新: July 3, 2026

本指南介绍 EKS Auto Mode 中的 Node 生命周期管理,包括过期策略、AMI 管理、漂移检测和 Node 新鲜度监控。


Node 过期策略 (expireAfter)

expireAfter 字段控制 Node 在被自动替换之前可以运行多长时间。

expireAfter 工作原理

yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: with-expiration
spec:
  template:
    spec:
      requirements:
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["m", "c"]
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      # Set maximum node lifetime
      expireAfter: 168h  # Auto-replace after 7 days

过期流程

  1. Node 达到 expireAfter 时长
  2. Controller 将 Node 标记为需要替换
  3. 使用最新配置预置新的 Node
  4. 在遵守 PDB 的前提下迁移工作负载
  5. 旧 Node 被 drain 并终止

Auto Mode 的 21 天最大 Node 生命周期

EKS Auto Mode 使用基于 Karpenter 的 expireAfter 默认值,并且 Node 在创建后达到 21 天 (504h) 的最大年龄时会自动被替换。你可以将 expireAfter 设置为短于 21 天,以便更频繁地替换,但将其设置为长于 21 天不会产生效果 — Auto Mode 会强制将 21 天作为硬性上限。与 managed node groups 或 self-managed Karpenter 不同,Node 不能无限期保留。

如果你运行会长时间保持状态的工作负载(缓存预热时间较长的服务、依赖本地存储的有状态工作负载等),请提前围绕这个 21 天上限规划 Pod 重新调度和数据再平衡流程。

推荐的 expireAfter 值

使用场景expireAfter理由
安全关键24h - 72h频繁修补,满足合规要求
标准生产168h (7 days)在新鲜度和稳定性之间取得平衡
成本敏感336h (14 days)最小化替换开销(在 21 天上限内)
开发/测试504h (21 days, maximum)最大化 Node 复用;这是强制执行的上限
合规 (PCI/HIPAA)72h - 168h满足审计要求

expireAfter 配置示例

yaml
# Security-first configuration
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: security-critical
spec:
  template:
    spec:
      expireAfter: 72h  # 3 days for security compliance
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: secure-nodeclass
---
# Cost-optimized configuration
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: cost-optimized
spec:
  template:
    spec:
      expireAfter: 336h  # 14 days for cost efficiency
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot"]
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default

AMI 管理策略

Auto Mode 如何选择 AMI

EKS Auto Mode 会根据你的 NodeClass 配置自动选择并管理 AMI。

yaml
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: ami-managed
spec:
  # AMI family selection
  amiFamily: AL2023  # or Bottlerocket

AMI Family 对比

功能AL2023Bottlerocket
基础 OSAmazon Linux 2023专为容器构建的 OS
启动时间~40-60 seconds~20-40 seconds
攻击面标准最小(只读 root)
自定义完整 (userData)有限 (settings API)
Package managerdnf无(不可变)
安全更新标准修补原子更新
使用场景通用工作负载安全重点工作负载

AMI Family 选择指南

工作负载类型推荐 AMI理由
通用 Web servicesAL2023灵活性,熟悉的工具
安全关键Bottlerocket最小攻击面
合规 (PCI/SOC2)Bottlerocket不可变基础设施
GPU 工作负载AL2023NVIDIA driver 支持
自定义 kernel modulesAL2023完整 OS 访问
快速扩缩容Bottlerocket更快的启动时间

自定义 AMI 配置

yaml
# For specific AMI requirements
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: custom-ami
spec:
  amiFamily: AL2023

  # AMI selection by tags (if using custom AMIs)
  amiSelectorTerms:
    - tags:
        Name: my-custom-eks-ami
        Environment: production

AMI 更新和漂移检测

AMI 更新如何触发漂移

当 AWS 发布新的 AMI 或你更新 NodeClass 时:

  1. AMI 发布:AWS 发布新的 EKS-optimized AMI
  2. 漂移检测:Controller 检测到 AMI 版本不匹配
  3. Node 标记:现有 Node 被标记为“已漂移”
  4. 替换:根据 disruption 设置替换 Node

漂移检测触发条件

变更触发漂移替换速度
新 AMI version基于 disruption budget
NodeClass AMI family 变更立即调度
Security patch AMI基于 disruption budget
NodePool requirement 变更基于 consolidation
NodeClass block device 变更仅新 Node

监控漂移状态

bash
# Check for drifted nodes
kubectl get nodes -o custom-columns=\
NAME:.metadata.name,\
NODEPOOL:.metadata.labels.karpenter\\.sh/nodepool,\
AGE:.metadata.creationTimestamp,\
DRIFT:.metadata.annotations.karpenter\\.sh/drift-hash

# Check NodeClaim drift status
kubectl get nodeclaims -o wide

# Watch for drift events
kubectl get events --sort-by='.lastTimestamp' | grep -i drift

控制漂移替换

yaml
# Slow drift replacement for stability
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: controlled-drift
spec:
  template:
    spec:
      expireAfter: 168h
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 10m
    budgets:
      # Slow, controlled replacement
      - nodes: "1"
      # No replacement during business hours
      - nodes: "0"
        schedule: "0 9-17 * * mon-fri"
        duration: 8h

Node 新鲜度策略和安全补丁

Node 新鲜度为何重要

关注点影响缓解措施
安全补丁未修补的漏洞较短的 expireAfter
AMI 更新缺少功能/修复启用漂移替换
配置漂移行为不一致定期 Node rotation
合规审计发现有文档记录的 rotation policy

安全补丁策略

yaml
# Security-focused NodePool
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: security-patched
spec:
  template:
    spec:
      # Maximum node age for security compliance
      expireAfter: 72h  # 3 days
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: secure-nodeclass
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 5m
    budgets:
      # Allow faster replacement for security patches
      - nodes: "20%"
---
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: secure-nodeclass
spec:
  amiFamily: Bottlerocket  # Security-hardened OS

  metadataOptions:
    httpTokens: required  # IMDSv2 only
    httpPutResponseHopLimit: 1

  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        encrypted: true
        volumeType: gp3

Consolidation 与过期的权衡

各机制何时适用

机制触发条件目的优先级
Consolidation利用率不足成本优化较低
过期年龄阈值安全/新鲜度较高
漂移配置变更一致性最高

机制间的交互

Node Lifecycle Priority:
1. Drift (immediate) - Configuration mismatch
2. Expiration (scheduled) - Age threshold reached
3. Consolidation (opportunistic) - Underutilization detected

不同优先级的配置

yaml
# Cost-priority (consolidation aggressive, expiration relaxed)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: cost-priority
spec:
  template:
    spec:
      expireAfter: 336h  # 14 days - relaxed
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m  # Aggressive consolidation
---
# Security-priority (expiration aggressive, consolidation relaxed)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: security-priority
spec:
  template:
    spec:
      expireAfter: 72h  # 3 days - aggressive
  disruption:
    consolidationPolicy: WhenEmpty  # Relaxed consolidation
    consolidateAfter: 10m

监控 Node Age 分布

基于 kubectl 的监控

bash
# List nodes with age
kubectl get nodes --sort-by='.metadata.creationTimestamp' \
  -o custom-columns=\
NAME:.metadata.name,\
NODEPOOL:.metadata.labels.karpenter\\.sh/nodepool,\
INSTANCE:.metadata.labels.node\\.kubernetes\\.io/instance-type,\
CREATED:.metadata.creationTimestamp,\
AGE:.metadata.creationTimestamp

# Calculate node ages in days
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.creationTimestamp}{"\n"}{end}' | \
while read name created; do
  age_seconds=$(($(date +%s) - $(date -d "$created" +%s)))
  age_days=$((age_seconds / 86400))
  age_hours=$(((age_seconds % 86400) / 3600))
  echo "$name: ${age_days}d ${age_hours}h"
done

Prometheus/Grafana 监控

用于 Node age 的关键 Prometheus 查询:

promql
# Node age in days
(time() - kube_node_created) / 86400

# Nodes older than 7 days
count(((time() - kube_node_created) / 86400) > 7)

# Average node age by NodePool
avg((time() - kube_node_created) / 86400) by (label_karpenter_sh_nodepool)

# Node age distribution histogram
histogram_quantile(0.50,
  sum(rate(kube_node_created_bucket[24h])) by (le)
)

告警规则

yaml
# Prometheus alerting rules for node age
groups:
  - name: node-lifecycle
    rules:
      - alert: NodeTooOld
        expr: (time() - kube_node_created) / 86400 > 10
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "Node {{ $labels.node }} is older than 10 days"

      - alert: NodeAgeDistributionSkewed
        expr: stddev((time() - kube_node_created) / 86400) > 3
        for: 4h
        labels:
          severity: info
        annotations:
          summary: "Node ages are highly variable, check rotation"

Node Age Dashboard

创建包含以下内容的 Grafana dashboard:

面板查询可视化
按 age bucket 的 Node 数量Node age 直方图条形图
按 NodePool 的平均 ageavg by (nodepool)Stat panel
最旧的 Node按 age 排序的 Top N表格
即将过期的 Node接近 expireAfter 的 age告警列表
替换率NodeClaims 创建/终止时间序列

Node 生命周期最佳实践

实践建议
设置 expireAfter始终配置,默认 7 天
出于安全目的使用 Bottlerocket最小攻击面
监控 Node age对超过预期 age 的 Node 发出告警
尊重 PDBs确保工作负载平滑迁移
错开替换使用 disruption budgets
跟踪 AMI versions监控安全补丁

< 上一页:成本管理 | 目录 | 下一页:工作负载优化 >