Karpenter 可以将 pod 从一个 Spot 节点合并到另一个 Spot 节点,终止未使用的 Spot 实例,从而进一步优化成本。
首先,让我们在开始新的deploy之前清理现有的 NodePool 和deployment,否则结果可能会有所不同:
kubectl delete deployment inflate
kubectl delete nodepool.karpenter.sh default
kubectl delete ec2nodeclass.karpenter.k8s.aws default
让我们部署 Spot 实例的 Nodepool:
mkdir -p ~/environment/karpenter
cd ~/environment/karpenter
cat <<EoF> spottospot.yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: Never
limits:
cpu: 10
template:
metadata:
labels:
eks-immersion-team: my-team
spec:
nodeClassRef:
name: default
requirements:
- key: karpenter.k8s.aws/instance-category
operator: In
values:
- c
- m
- r
- key: kubernetes.io/arch
operator: In
values:
- amd64
- key: karpenter.sh/capacity-type
operator: In
values:
- spot
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: "KarpenterNodeRole-${CLUSTER_NAME}"
securityGroupSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
subnetSelectorTerms:
- tags:
alpha.eksctl.io/cluster-name: $CLUSTER_NAME
tags:
intent: apps
managed-by: karpenter
eks-immersion-team: my-team
EoF
kubectl apply -f spottospot.yaml
让我们部署应用:
cd ~/environment/karpenter
cat <<EoF> spot-consolidation.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 8
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
memory: 1Gi
cpu: 1
nodeSelector:
eks-immersion-team: my-team
EoF
kubectl apply -f spot-consolidation.yaml
我们看到 Karpenter 在两个节点上调度了 8 个应用程pod,这两个节点,一个是2xlarge,一个是large:
现在,让我们将deploy缩到 4 个副本。
kubectl scale deployment inflate --replicas 4
deployment.apps/inflate scaled
eks先将2xlarge节点上的4个pod下掉,分布成3:1
karpenter检查到可以将large节点上的1个pod移动到2xlarge上,再把large节点下掉。最终如下:
检查 Karpenter 的日志:
kubectl -n karpenter logs -l app.kubernetes.io/name=karpenter
我们应该在日志中看到 disrupting via consolidation delete
和 terminating 1 nodes
的消息
假如我们再将replica缩小到3个:
kubectl scale deployment inflate --replicas 3
Karpenter也不会再将2xlarge consolidation成xlarge,这是因为它是spot节点。对于spot节点,只有删除机制,Karpenter不会使用节点替换。
删除示例应用、NodePool 和 EC2NodeClass 资源。
cd ~/environment/karpenter
kubectl delete -f spottospot.yaml
kubectl delete -f spot-consolidation.yaml