【云原生实战】从零构建无节点 EKS:Karpenter 极简注入与全自动算力接管指南

在传统的 EKS 架构中,我们总要先买几台 EC2 作为底座。但今天,我们将挑战最高难度的"真空启动":在一个没有任何节点的 EKS-Dev-SGB-Demo-02 集群中,直接注入 Karpenter,让它成为唯一的算力造物主。

第一阶段:打通环境"路标" (Tagging)

Karpenter 不会自动乱买机器,我们需要给它指定"地盘"。根据你截图中的网络信息,我们需要给指定的子网(Subnet)和安全组(Security Group)打上特定的标签。

  1. 给子网打标签 :找到你截图里的 subnet-070c55a...subnet-09ca880... 等子网,给它们加上标签:

    • karpenter.sh/discovery: EKS-Dev-SGB-Demo-02
  2. 给安全组打标签 :找到你截图里的集群安全组 sg-0907dbb657ed29a5c,加上同样的标签:

    • karpenter.sh/discovery: EKS-Dev-SGB-Demo-02

原理:Karpenter 启动后,会自动扫描带这个标签的网络资源,以后买的新机器都会塞进这些子网里。

第二阶段:打破死锁,拉起 Karpenter 的"大脑"

既然没有 EC2,我们就用 AWS Fargate(Serverless 容器)来跑 Karpenter 控制器。

1. 创建 Fargate Profile

我们需要告诉 EKS:"只要是部署在 karpenter 命名空间里的 Pod,统统用 Fargate 跑,不要找我要物理机。"

通过命令行执行(使用 eksctl):

复制代码
eksctl create fargateprofile \
  --cluster EKS-Dev-SGB-Demo-02 \
  --name karpenter-profile \
  --namespace karpenter

2. 准备 IAM 权限 (IRSA)

Karpenter 需要买机器的权限。我们需要建立 OIDC 关联,并为它创建一个 IAM 角色(这里省略复杂的 JSON 策略,直接用 eksctl 一键搞定):

复制代码
eksctl create iamserviceaccount \
  --cluster EKS-Dev-SGB-Demo-02 --name karpenter --namespace karpenter \
  --role-name "KarpenterControllerRole-SGB-Demo" \
  --attach-policy-arn "arn:aws:iam::aws:policy/AmazonEKSWorkerNodeProvisionerPolicy" \
  --role-only \
  --approve

3. Helm 安装 Karpenter

现在环境就绪,直接使用 Helm 把 Karpenter 部署到我们刚刚划定的 Fargate 空间里:

复制代码
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
  --version 1.0.0 \
  --namespace karpenter --create-namespace \
  --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"="arn:aws:iam::YOUR_ACCOUNT_ID:role/KarpenterControllerRole-SGB-Demo" \
  --set settings.clusterName=EKS-Dev-SGB-Demo-02 \
  --wait

此时执行 kubectl get pods -n karpenter,你会看到 Karpenter 正在 Fargate 的加持下成功启动!死锁打破!

第三阶段:下发"造机法则" (NodePool & EC2NodeClass)

Karpenter 脑子虽然启动了,但还不知道你要买什么样的机器。在最新的 Karpenter API 中,我们需要下发两个核心配置。

创建一个 karpenter-rules.yaml 文件:

复制代码
---
# 1. 定义 AWS 相关的云资源参数 (EC2NodeClass)
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  amiFamily: AL2023 # 使用最新的 Amazon Linux 2023
  role: "KarpenterNodeRole-SGB-Demo" # 新机器用的 IAM 角色
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "EKS-Dev-SGB-Demo-02" # 认准我们刚才打标签的子网
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "EKS-Dev-SGB-Demo-02" # 认准我们刚才打标签的安全组

---
# 2. 定义机器规格和缩容逻辑 (NodePool)
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"] # 优先买 Spot 实例,省钱!
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"] # 支持按需买 x86 或 Graviton 芯片
  # 极其激进的缩容策略:机器空闲 30 秒立刻关机退款
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 30s

执行 kubectl apply -f karpenter-rules.yaml

第四阶段:见证奇迹的时刻

现在你的集群依然是 0 个 EC2 节点。让我们随便扔一个 Nginx 上去:

复制代码
kubectl create deployment nginx --image=nginx --replicas=5

发生了什么?

  1. EKS 发现有 5 个 Nginx Pod 需要运行,但没有机器,状态变为 Pending

  2. 跑在 Fargate 里的 Karpenter 瞬间捕捉到这个求救信号。

  3. 它计算出 5 个 Nginx 只需要极小的资源,于是直接调用 AWS API。

  4. 不到 45 秒钟 ,一台全新的、最便宜的 EC2(比如 t3.medium)被造了出来,加入集群,5 个 Nginx 瞬间变为 Running

  5. 当你执行 kubectl scale deployment nginx --replicas=0 时,Karpenter 发现机器空了,30 秒后自动触发 Terminate,物理机关机,停止计费。

至此,你完成了一个最高形态的 EKS 架构演进:无极弹性,0 资源闲置。


现在要求起一批gpu需求的pod,而且不要让其他pod调用到这批机器上。

核心逻辑:给 GPU 机器装上"专用锁"

我们要创建一个专门针对 GPU 的 NodePool。这个配置包含两个核心要点:

  1. Taints (污点/锁):给拉起来的 GPU 机器加一把锁,默认禁止任何人进入。

  2. Requirements (规格):限定 Karpenter 只能去买带显卡的机器(如 G5, P4 家族)。

1. 编写 GPU 专属 NodePool (karpenter-gpu-pool.yaml)
复制代码
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-pool
spec:
  template:
    spec:
      # 【关键:这就是那把锁】
      # 任何被这套规则创建出来的机器,都会自带这三个污点
      taints:
        - key: "nvidia.com/gpu"
          value: "true"
          effect: NoSchedule
        - key: "sku"
          value: "gpu-exclusive"
          effect: NoSchedule

      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default # 复用之前的网络配置

      requirements:
        # 限定只买 GPU 机型 (G系列或P系列)
        - key: "node.kubernetes.io/instance-type"
          operator: In
          values: ["g5.2xlarge", "g5.4xlarge", "p4d.24xlarge"]
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"] # 训练任务通常建议用按需实例

2. 编写 GPU Pod 配置 (带着钥匙进来)

现在,如果你提交一个普通的 Nginx,它绝对不会落在这批机器上,因为 Nginx 没有"钥匙"。

你的 GPU 任务必须在 YAML 中声明:

  1. Tolerations (容忍度/钥匙):能够忍受上面的污点。

  2. NodeSelector (定向投放):明确要求去有 GPU 的机器。

GPU 任务 YAML 示例:
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: gpu-training-task
spec:
  # 【钥匙 1】:必须配置容忍度,才能在带污点的机器上运行
  tolerations:
  - key: "nvidia.com/gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
  - key: "sku"
    operator: "Equal"
    value: "gpu-exclusive"
    effect: "NoSchedule"

  # 【钥匙 2】:明确要求使用显卡资源
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.0-base
    resources:
      limits:
        nvidia.com/gpu: 1 # 申请 1 块显卡

3. 为什么这样配置能实现你的要求?

我们可以从两个视角来看这个自动化的过程:

场景 A:普通的 Java/前端 Pod 进来
  1. EKS 发现这些 Pod 没有任何 Tolerations

  2. Karpenter 查看 gpu-pool,发现这批机器都有"锁"(Taint)。

  3. Karpenter 判定:gpu-pool 无法服务这些普通 Pod。

  4. Karpenter 会转而使用 default 队列去买普通的 t3.medium 这种便宜机器,绝对不会浪费昂贵的 GPU 资源给普通应用。

场景 B:带 GPU 需求的训练 Pod 进来
  1. EKS 发现 Pod 申请了 nvidia.com/gpu: 1

  2. Karpenter 扫描 NodePool,发现只有 gpu-pool 能满足 GPU 需求。

  3. 虽然 gpu-pool 有锁,但这个 Pod 刚好带着匹配的"钥匙"(Tolerations)。

  4. Karpenter 瞬间调用 AWS API,拉起一台 G5 实例。


相关推荐
北山有鸟1 小时前
常用的快捷键
linux·前端·chrome·单片机·学习
蜀道山老天师1 小时前
从零搭建 Prometheus 监控 MySQL:含二进制安装、授权、exporter 配置全流程
运维·数据库·mysql·adb·云原生·prometheus
岳来1 小时前
Linux Capabilities(能力机制)细分学习
linux·root
哈哈浩丶1 小时前
存储相关知识②—eMMC协议
linux·驱动开发·emmc
geshifei1 小时前
Sched_ext 回调深度解析(一):init_task —— 每个任务走进调度器的第一道门(6.18.26)
linux·ebpf
专注API从业者2 小时前
Open Claw 实战:用淘宝商品 API 实现自动化监控选品系统
大数据·运维·数据库·自动化
没文化的阿浩2 小时前
【Linux系统】Ext系列文件系统
linux·运维·电脑
珂玥c2 小时前
添加node节点到k8s集群+配置网络插件flannel
云原生·容器·kubernetes
红茶要加冰2 小时前
九、文本处理三剑客——sed
linux·运维·服务器·正则表达式·shell