我们将部署两个节点池,利用 Karpenter 能够根据所需比例在按需和竞价型实例之间分配工作负载的能力。
执行以下命令创建节点池:
cat << EOF >nodepool-ondemandspotsplit.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: ondemand
labels:
app.kubernetes.io/managed-by: app-team
spec:
disruption:
consolidateAfter: 30s
consolidationPolicy: WhenEmptyOrUnderutilized
template:
metadata:
labels:
EKSAutoNodePool: OnDemandSpotSplit
spec:
expireAfter: 336h
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: default
requirements:
- 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:
- amd64
- key: karpenter.sh/capacity-type
operator: In
values:
- on-demand
- key: capacity-spread
operator: In
values:
- "1"
taints:
- effect: NoSchedule
key: OnDemandSpotSplit
terminationGracePeriod: 24h0m0s
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: spot
labels:
app.kubernetes.io/managed-by: app-team
spec:
disruption:
consolidateAfter: 30s
consolidationPolicy: WhenEmptyOrUnderutilized
template:
metadata:
labels:
EKSAutoNodePool: OnDemandSpotSplit
spec:
expireAfter: 336h
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: default
requirements:
- 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:
- amd64
- key: karpenter.sh/capacity-type
operator: In
values:
- spot
- key: capacity-spread
operator: In
values:
- "2"
- "3"
- "4"
- "5"
taints:
- effect: NoSchedule
key: OnDemandSpotSplit
terminationGracePeriod: 24h0m0s
EOF
kubectl apply -f nodepool-ondemandspotsplit.yaml
输出应类似于:
nodepool.karpenter.sh/ondemand created
nodepool.karpenter.sh/spot created
利用 Karpenter 为节点分配标签的能力,并使用这些标签进行拓扑分布,按照所需比例在按需和竞价型实例之间分配工作负载。
为此,我们为竞价型和按需容量类型各创建了一个节点池,并为名为 capacity-spread
的新标签分配了不同的值。在上面的示例中,我们为竞价型节点池提供了四个唯一值,为按需节点池提供了一个值。当我们均匀分布在新标签上时,我们将得到 4:1 的竞价型与按需节点比例。
在本实验中,我们将使用 catalog
组件在竞价型实例上运行其副本。让我们配置我们的catalog应用程序部署为 5 个副本。使用 capacity-spread 标签,我们将在新标签上均匀分布,最终得到 4:1 的竞价型与按需节点比例。
配置并重新部署组件:
kubectl patch deployment catalog --type=strategic --patch '{
"spec": {
"replicas": 5,
"template": {
"spec": {
"topologySpreadConstraints": [
{
"maxSkew": 1,
"minDomains": 5,
"topologyKey": "capacity-spread",
"whenUnsatisfiable": "DoNotSchedule",
"labelSelector": {
"matchLabels": {
"app.kubernetes.io/name": "catalog"
}
}
}
],
"nodeSelector": {
"EKSAutoNodePool": "OnDemandSpotSplit"
},
"tolerations": [
{
"key": "OnDemandSpotSplit",
"operator": "Exists"
}
]
}
}
}
}'
最后,我们可以验证 catalog
组件的 Pod 是否在竞价型实例上运行。
运行以下命令检查节点和 Pod:
kubectl get node -L karpenter.sh/capacity-type
我们可以看到 catalog
应用程序的 Pod 分布在竞价型和按需容量类型之间
在本实验中,我们探索了如何在 EKS Auto Mode中同时利用按需和竞价型实例。我们通过创建两个节点池实现了分割比例策略 - 一个用于按需实例,另一个用于竞价型实例,使用 capacity-spread
标签。我们为竞价型节点池配置了四个唯一的分布值,为按需节点池配置了一个值,有效地创建了 4:1 的竞价型与按需实例比例。
为了演示这种配置,我们将catalog应用程序配置为 5 个副本,并使用拓扑分布约束根据我们所需的比例将 Pod 分布在节点上。
本实验成功展示了如何在 EKS 集群管理中实现可靠性和成本优化之间的平衡。