Karpenter API 遵循 alpha → beta → stable
的成熟度进程。
从 v0.33.0 版本开始,Karpenter 将仅支持其 v1beta1 API。
从 Alpha 版升级到 Beta 版对 API 进行了重大更改。但从beta版升级到stable版不需要这么大的更改。
从 alpha 版到 beta 版,最重要的是一些API的命名发生改变,例如provisioner
在此版本中,Karpenter 弃用了 Provisioner、AWSNodeTemplate
、 Machine
,同时引入了 NodePool、EC2NodeClass
和 NodeClaim
。
v1beta1 版本引入了以下新 API,同时弃用了现有 API:
karpenter.sh/Provisioner
变为 karpenter.sh/NodePool
karpenter.sh/Machine
变为 karpenter.sh/NodeClaim
karpenter.k8s.aws/AWSNodeTemplate
变为 karpenter.k8s.aws/EC2NodeClass
让我们看看每项更改以及新的 API 定义是什么样
一个Pool是不同实例类型和大小的混合,可参考 https://karpenter.sh/docs/concepts/nodepools/
NodePool 的示例如下所示:
apiVersion: karpenter.sh/v1beta1
kind: NodePool
...
spec:
template:
metadata:
annotations:
custom-annotation: custom-value
labels:
team: team-a
custom-label: custom-value
spec:
nodeClassRef:
name: default
requirements:
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
...
kubelet:
systemReserved:
cpu: 100m
memory: 100Mi
ephemeral-storage: 1Gi
maxPods: 20
disruption:
expireAfter: 360h
consolidationPolicy: WhenUnderutilized
我们注意到一个名为disruption
的新定义,它其实将alpha版本的ttlSecondsAfterEmpty
, ttlSecondsUntilExipred
, consolidation.enabled
进行了归类,一起放到这个字段了
如果yaml里没有设置这个字段,Karpenter会使用以下默认值:
字段 | 默认值 |
---|---|
spec.disruption.consolidationPolicy | WhenUnderutilized |
spec.disruption.expireAfter | 720h |
Karpenterspec.instanceProfile
字段已从 EC2NodeClass
中删除,取而代之的是该spec.role
字段。Karpenter 现在会根据指定的角色在您的 EC2NodeClass 中自动生成实例配置文件。
EC2NodeClass
示例如下:
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: Bottlerocket
role: KarpenterNodeRole-karpenter-demo
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: karpenter-demo
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: karpenter-demo
tags:
test-tag: test-value
Karpenter v1beta1
对标签karpenter.sh/do-not-evict
、karpenter.sh/do-not-consolidate
进行了替换,这两个标签已被弃用并统一在单一标签——karpenter.sh/do-not-disrupt
。它应用于 Pod 和节点,防止 Karpenter 执行node disruption和 Pod 驱逐。
现在AMI selector、subnetGroup、securityGroup Selector
使用OR(以前是AND)逻辑进行选择,例如:
amiSelectorTerms:
- name: my-name1
owner: 123456789
- name: my-name2
owner: 123456789
- name: my-name1
owner: amazon
- name: my-name2
owner: amazon
securityGroupSelectorTerms:
- id: abc-123
name: default-security-group # Not the same as the name tag
tags:
key: value
# Selector Terms are ORed
- id: abc-123
name: custom-security-group # Not the same as the name tag
tags:
key: value
从下一个版本(v0.33.0)开始,Drift功能将默认启用。如果您不指定 Drift featureGate
,则假定该功能已启用。
从上面的介绍可以看到,beta版本对Karpenter的一些API进行了更改,所以一些IAM Policy也需要进行更新,新的policy可见: https://github.com/aws/karpenter/blob/main/website/content/en/v0.32/getting-started/getting-started-with-karpenter/cloudformation.yaml (例如将karpenter.sh/nodepool
Tag更新为karpenter.sh/provisioner-name
)
要从 alpha 过渡到新的 v1beta1 API,应该首先安装新的 v1beta1 CRD。随后,需要为 Provisioners 和 AWSNodeTemplates 生成每个 alpha API 的 beta 版本。
可以借助工具karpenter-convert ,它是一个命令行实用程序,旨在简化 NodePool 和 EC2NodeClass 对象的创建。
go install github.com/aws/karpenter/tools/karpenter-convert/cmd/karpenter-convert@latest
karpenter-convert -f provisioner.yaml > nodepool.yaml
karpenter-convert -f nodetemplate.yaml > nodeclass.yaml
对于每个 Provisioner 资源,您需要决定是一次滚动一个节点还是一次性滚动所有 Provisioner 节点。以下部分提供了详细的分步指南:
启用漂移后,对于集群中的每个 Provisioner,执行以下操作:
karpenter.sh/legacy=true:NoSchedule
目前,Karpenter 仅支持一次滚动一个节点,这意味着 Karpenter 可能需要一些时间才能完全滚动单个 Provisioner 下的所有节点
对于集群中的每个 Provisioner,执行以下操作:
在集群中创建 NodePool/EC2NodeClass
,该 NodePool/EC2NodeClass
相当于 v1alpha5中的 Provisioner/AWSNodeTemplate
删除旧的 Provisioner
kubectl delete provisioner <provisioner-name> --cascade=foreground
Karpenter 删除 Provisioner 拥有的每个节点,同时drain所有节点,并在节点进入Drain状态后为pending pod启动新的节点
对于集群中的每个 Provisioner,执行以下操作:
NodePool/EC2NodeClass
karpenter.sh/legacy=true:NoSchedule
kubectl delete node <node-name>