使用Graviton机器

与同类x86基础的Amazon EC2实例相比,Graviton性价比最高可提升40%。Graviton处理器在相同性能下的能耗也比同类EC2实例低60%。

在本节中,我们将创建一个新的、自定义的通用节点池来创建AWS Graviton实例。在创建新节点池之前,让我们先查看现有的general-purpose节点池和集群中当前可用节点的状态。执行以下命令:

kubectl get nodepool general-purpose -o yaml

general-purpose节点池的配置应该如下所示:

image-20250228085204865

➤ 查看当前实例的处理器架构:

kubectl get nodes -L kubernetes.io/arch

对应的输出:

image-20250228085248167

上面的输出显示了现有的节点及其CPU架构。所有节点当前都使用amd64处理器架构的EC2实例,这些实例由general-purpose节点池提供。

创建Graviton节点池

让我们创建一个新的节点池,在kubernetes.io/arch要求中包含arm64(Graviton)。

Karpenter从而会检查每个新Pod的nodeAffinitynodeSelector,以查看是否有特定的CPU架构要求。如果Karpenter确定需要一个新的Graviton节点来适应待处理的pod,它将启动一个新的Graviton节点。

我们还将为Graviton节点池添加一个taint,以控制我们想要在这些节点上调度的应用程序。污点将定义键和效果为key:GravitonOnlyeffect:NoSchedule。这将确保只有具有匹配tolerant的pod才会被调度到这些节点上。

新的NodePool的定义:

cat << EOF >nodepool-graviton.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: graviton
  labels:
    app.kubernetes.io/managed-by: app-team
spec:
  disruption:
    budgets:
    - nodes: 10%
    consolidateAfter: 30s
    consolidationPolicy: WhenEmptyOrUnderutilized
  template:
    metadata: {}
    spec:
      expireAfter: 336h
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
      - key: karpenter.sh/capacity-type
        operator: In
        values:
        - on-demand
      - key: eks.amazonaws.com/instance-category
        operator: In
        values:
        - c
        - m
        - r
      - key: eks.amazonaws.com/instance-generation
        operator: Gt
        values:
        - "4"
      - key: kubernetes.io/arch
        operator: In
        values:
        - arm64
      taints:
      - effect: NoSchedule
        key: GravitonOnly
      terminationGracePeriod: 24h0m0s
  limits:
    cpu: "1000"
    memory: 1000Gi
EOF

kubectl apply -f nodepool-graviton.yaml

在Graviton上运行pod

创建了Graviton节点池,需要配置应用来使用graviton。

更新UI组件,将其pod绑定到Graviton节点池。

kubectl patch deployment ui --type=strategic --patch '
{
  "spec": {
    "template": {
      "spec": {
        "nodeSelector": {
          "karpenter.sh/nodepool": "graviton"
        },
        "tolerations": [
          {
            "key": "GravitonOnly",
            "operator": "Exists"
          }
        ]
      }
    }
  }
}'

在检查应该启动的新Graviton节点之前,运行以下命令以确保所有UI组件pod都已启动并运行:

image-20250228091955081

➤ 现在我们可以检查我们的EKS集群节点和UI组件pod的状态:

kubectl get nodes -L kubernetes.io/arch -L karpenter.sh/nodepool
kubectl get pods -l app.kubernetes.io/name=ui -o wide

预期输出类似于以下内容:

image-20250228092104031

总结

在本实验中,我们探索了在EKS Auto Mode中使用AWS Graviton实例以提高性能和成本效率。

我们首先创建了一个专用的Graviton节点池,该节点池专门请求arm64架构实例,并包含一个GravitonOnly污点,用于控制pod调度。然后,我们通过更新UI组件的配置来修改应用程序部署,包括必要的nodeSelectortolerations,使其能够在Graviton实例上运行。