作者:Rajdeep Saha,AWS 首席解决方案架构师;Praseeda Sathaye,AWS 容器与开源首席解决方案架构师
引言
Karpenter[1] 是一个开源项目,旨在提供节点生命周期管理,以优化在 Kubernetes 集群上运行工作负载的效率和成本。AWS 于 2021 年创建并开源了 Karpenter,帮助用户自动选择、配置和扩展集群中的基础设施,为 Kubernetes 用户提供更大的灵活性,以充分利用不同云服务提供商的独特基础设施。2023 年,该项目进入 beta 阶段,AWS 将项目的供应商中立核心贡献[2]给云原生计算基金会(CNCF),通过 Kubernetes 自动伸缩特别兴趣小组(SIG)。2024 年,AWS 发布了 Karpenter 版本 1.0.0[3],标志着该项目成熟的最终里程碑。此次发布后,所有 Karpenter API 将在未来的 1.0 次要版本中保持可用,且不会做出造成破坏性变更的修改。Karpenter 作为开源软件(OSS)[4]在 Apache 2.0 许可下提供。它将 Kubernetes 应用感知和工作负载整合的通用逻辑与为特定云服务提供商启动或终止计算资源的 API 请求的创建和运行分开。通过开发与各自计算 API 交互的云服务提供商特定集成,Karpenter 使 AWS、Azure、GCP 等独立云服务提供商能够在各自环境中利用其能力。2023 年,微软发布了 Karpenter Provider[5],以便在 Azure Kubernetes Service (AKS) 上运行 Karpenter。
如今,Karpenter 在 Kubernetes 社区中已获得广泛认可,各种组织和企业利用其功能来提高应用可用性、降低运营开销,并提高成本效率。
Karpenter 的工作原理
Karpenter 在 Kubernetes 集群中的任务,是做出应用和 Kubernetes 感知的计算容量决策。它作为 Kubernetes Operator 构建,运行在 Kubernetes 集群中,管理集群计算基础设施。Karpenter 做出两种类型的决策:配置新计算和在不再需要时撤销这些计算。Karpenter 通过监控 Kubernetes 调度器标记为不可调度的 Pod,评估 Pod 请求的调度约束(资源请求、节点选择器、亲和性、容忍度及拓扑扩散约束),配置满足 Pod 要求的节点,并在不再需要时撤销节点。Karpenter 的工作负载整合功能主动识别并将未充分利用的工作负载重新调度到更具成本效益的实例上,既可以重用集群内现有实例,也可以启动新的优化实例,从而最大化资源使用并最小化运营成本。
图 1:Karpenter 根据待处理的不可调度 Pod 配置节点
Karpenter 的扩展通过 Kubernetes 原生 YAML 控制,特别是通过使用 NodePool[6] 和 NodeClass[7] 自定义 Kubernetes 资源。
NodePools 对 Karpenter 在 Kubernetes 集群中配置的节点设定约束。每个 NodePool 定义实例类型、可用区、架构(例如 AMD64 或 ARM64)、容量类型(竞价或按需)和适用于 NodePool 中所有节点的其他节点设置等要求。它还允许对 NodePool 可消耗的 CPU、内存和 GPU 等总资源设置限制。以下是 NodePool 配置的示例。
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c","m","r","t"]
- key: "karpenter.k8s.aws/instance-family"
operator: In
values: ["m5","m5d","c5","c5d","c4","r4"]
- key: karpenter.k8s.aws/instance-size
operator: NotIn
values: ["nano","micro","small","medium"]
- key: topology.kubernetes.io/zone
operator: In
values: ["us-west-2a","us-west-2b"]
- key: kubernetes.io/arch
operator: In
values: ["amd64","arm64"]
limits:
cpu: 100
请参考 Karpenter 文档[8]以获取 NodePool 要求的完整字段列表。
以下是带有污点、用户定义标签和注释的 NodePool 示例,这些都会添加到 Karpenter 配置的所有节点上。
apiVersion: karpenter.sh/v1beta1
kind: NodePool
spec:
template:
metadata:
annotations:
application/name: "app-a"
labels:
team: team-a
spec:
taints:
- key: example.com/special-taint
value: "true"
effect: NoSchedule
apiVersion: apps/v1
kind: Deployment
metadata:
name:
spec: myapp
nodeSelector:
team: team-a
Karpenter 支持所有标准 Kubernetes 调度约束,如节点选择器、节点亲和性、污点/容忍度和拓扑扩散约束。这允许应用在调度 Pod 时使用这些约束。
Karpenter 中的 NodeClasses 允许你为 Kubernetes 集群中的节点配置云服务提供商特定的设置。每个 NodePool 引用一个 NodeClass,以确定 Karpenter 配置节点的具体配置。例如,你可以指定 Amazon 机器镜像(AMI)系列、子网和安全组选择器、AWS 身份和访问管理(IAM)角色/实例配置文件、节点标签和 AWS EC2NodeClass 中的各种 Kubelet 配置,Azure AKSNodeClass 也类似。
超越扩展
Karpenter 不仅是 Kubernetes 的高效集群自动伸缩器。它优化计算成本,帮助升级和修补数据平面工作节点,并通过与其他 CNCF 工具配对,提供强大而探索性的用例。
成本优化
在前面的部分中,我们看到 Karpenter 如何根据 Pod 的资源请求配置适当的工作虚拟机(VM)。随着 Kubernetes 集群中工作负载的变化和扩展,可能需要启动新实例,以确保它们拥有所需的计算资源。随着时间的推移,这些实例可能会因为某些工作负载缩减或从集群中移除而变得未充分利用。Karpenter 的工作负载整合功能会自动寻找机会,将这些工作负载重新调度到更具成本效益的实例上,无论这些实例是否已经在集群中,还是需要新启动。
图 2:使用情况不同的工作节点
在上面的图中,第一个节点的使用率很高,而其他节点的使用率则不如预期。使用 Karpenter,你可以在 NodePool YAML 文件中启用整合功能:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
Karpenter 始终在评估并努力降低集群成本。Karpenter 将工作负载整合到最少的、成本最低的实例上,同时仍然尊重 Pod 的资源和调度约束。在前述场景中,Karpenter 将 Pod 从最后两个节点移动到第二个节点,并终止空节点:
图 3:Karpenter 将 Pod 整合到现有节点中
Karpenter 根据已调度 Pod 的数量优先考虑整合节点。对于经历需求激增或中断作业的工作负载,频繁的 Pod 创建和删除(Pod 变动)可能是一个关注点。Karpenter 提供了 consolidateAfter
设置,以控制在响应 Pod 添加或移除时,尝试整合节点的速度。用户可以通过指定小时、分钟或秒的值,决定 Karpenter 开始整合操作的延迟时间。
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: default
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1h
通过整合,Karpenter 还会调整工作节点的大小。例如,在以下情况下,如果 Karpenter 将 Pod 从第三个节点整合到第二个节点(m5.xlarge),则仍然会出现未充分利用的情况。Karpenter 会配置一个较小的节点(m5.large)并整合 Pod,从而实现更低的成本。
图 4:Karpenter 通过整合调整节点大小
有关整合的更多信息,请参考官方文档[9]。
工作节点的生命周期管理
Karpenter 确保你的工作节点始终使用最新的节点映像/Amazon 机器镜像(AMI)。在 NodeClass YAML 中,你可以指定 AMI 系列和版本,如下所示:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiSelectorTerms:
- alias: bottlerocket@latest
amiSelectorTerms
是 NodeClass 的必要字段,自版本 1.0 起引入了一个新术语 alias
,它由 AMI 系列和版本(family@version)组成。如果 NodeClass 中存在别名,则 Karpenter 会选择云服务提供商为该系列提供的 AMI。通过这个新功能,用户还可以固定到特定版本的 AMI。对于 AWS,可以配置以下 Amazon Elastic Kubernetes Service(Amazon EKS)优化的 AMI 系列:al2、al2023、bottlerocket、windows2019 和 windows2022。
所有通过此 NodeClass 配置的节点都将使用最新的 bottlerocket AMI。由于该别名使用 @latest 版本,当云服务提供商为 Kubernetes 版本集群发布新的优化 AMI 时,Karpenter 会自动更新工作节点 AMI,同时尊重 Kubernetes 调度约束。工作节点将以滚动部署的方式升级。如果集群升级到新版本,Karpenter 会自动使用该新版本的最新 AMI 升级工作节点,无需人工干预。这减少了管理开销,使你始终可以使用最新和最安全的 AMI。这在预生产环境中非常有效,适合自动升级到最新版本进行测试,但在生产环境中建议对 AMI 版本进行更多控制。
另外,你也可以将工作节点固定到特定版本的 AMI,如下所示:
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiSelectorTerms:
- alias: bottlerocket@v1.20.3
在这种情况下,如果云服务提供商发布新的 bottlerocket AMI,Karpenter 将不会使工作节点漂移。
Karpenter 还支持自定义 AMI。你可以在 amiSelectorTerms
中使用现有标签、名称或 ID 字段选择 AMI。在以下情况下,将选择 ID 为 ami-123 的 AMI 来配置节点。amiFamily
Bottlerocket 将预生成的用户数据注入到配置的节点中。
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
...
amiFamily: Bottlerocket
amiSelectorTerms:
- id: ami-123
要升级工作节点,只需更改 amiSelectorTerms
来选择不同的 AMI,节点将漂移并升级到指定的 AMI。
Karpenter 与其他 CNCF 项目协作
Karpenter 可以与其他 CNCF 项目结合使用,以提供强大的解决方案,满足常见用例。其中一个显著的例子是与 Kubernetes 事件驱动自动伸缩(KEDA)结合使用 Karpenter 实现事件驱动工作负载。使用 KEDA,你可以根据需要处理的事件数量驱动 Kubernetes 中任何容器的扩展。一个流行的实现是扩展工作节点,以容纳处理来自队列的消息的 Pod:
图 5:Karpenter 根据队列中的消息与 KEDA 配置节点
用户通常希望在非高峰时段减少工作节点的数量。KEDA 和 Karpenter 可以支持这种用例:
图 6:Karpenter 根据 KEDA 的 Cron 计划配置节点
Karpenter 可以与其他 CNCF 项目结合使用,如 Prometheus、Argo Workflows 和 Grafana,以实现多样的用例。请查看在 Kubecon EU 2024 上的演讲[10],了解 Argo Workflows 如何与 Karpenter 结合,从而完成从集群自动伸缩器的迁移。
采用 Karpenter
要开始使用 Karpenter,你可以按照官方的《Karpenter 快速入门[11]》指南,提供使用 eksctl[12] 逐步创建 EKS 集群并将 Karpenter 添加到其中的流程。或者,如果你更喜欢使用 Terraform,可以使用 Amazon EKS Blueprints[13] for Terraform,其中包含 Karpenter 模块,从而简化 Karpenter 与 EKS 集群的设置过程。此外,还有指南可帮助你将 Karpenter 与其他 Kubernetes 发行版(如 AWS 上的 kOps[14])结合使用。如果你希望将 Kubernetes 集群自动伸缩器迁移到 Karpenter,以在现有 EKS 集群上实现自动节点配置,请参考这指南[15]以获取详细步骤。
接下来是什么
Karpenter 已经远远超越了自动伸缩工具的角色,展示了其多样性和在云原生生态系统中的更深层次集成。Karpenter 不仅扩展工作节点,还推动成本效率,轻松管理如生成式 AI 等多样化工作负载,精确支持数据平面升级等。
展望未来,Karpenter 的可能性是无穷的,尤其是在组织探索突破性用例的过程中。我们才刚刚开始挖掘 Karpenter 与其他 CNCF 项目结合所能实现的潜力。Karpenter 对下一代基础设施的贡献潜力巨大,我们迫不及待想要看到用户创造出的创新和强大的用例,使其云操作更加高效、可扩展和智能。
为了塑造 Karpenter 的未来,欢迎你在此[16]投票和评论我们应当重点开发的功能。
如果你将参加 KubeCon NA 2024,欢迎在 AWS 展位 F1 与我们会面,或参加我们的 Karpenter 研讨会[17]《Kubernetes 智能扩展:Karpenter 快速入门》,以了解更多信息。
关于作者
Rajdeep Saha,AWS 首席解决方案架构师
Raj 是 AWS 容器和无服务器技术的首席专家解决方案架构师。他设计了多款高流量的 AWS 应用,服务数百万用户。他在 Kubernetes、无服务器、DevOps 和系统设计方面是出版的讲师,并在 AWS Re:Invent、Kubecon 和 AWS 峰会等重要活动上发表过广受欢迎的演讲。
Praseeda Sathaye,容器与开源首席解决方案架构师
Praseeda Sathaye 是亚马逊网络服务(AWS)应用现代化和容器的首席专家,驻扎在加利福尼亚州湾区。她专注于帮助客户通过微服务策略、容器化、平台工程、GitOps、Kubernetes 和服务网格,加速其云原生采用之旅。Praseeda 热衷于利用生成式 AI(GenAI)在 Amazon Elastic Kubernetes Service(EKS)上释放前沿技术的全部潜力,推动 AI 驱动应用的发展。
Karpenter: https://karpenter.sh/
[2]贡献: https://github.com/kubernetes/org/issues/4258
[3]1.0.0: https://aws.amazon.com/blogs/containers/announcing-karpenter-1-0/
[4]开源软件(OSS): https://github.com/kubernetes-sigs/karpenter
[5]Karpenter Provider: https://github.com/Azure/karpenter-provider-azure
[6]NodePool: https://karpenter.sh/docs/concepts/nodepools/
[7]NodeClass: https://karpenter.sh/docs/concepts/nodeclasses/
[8]文档: https://karpenter.sh/docs/concepts/nodepools/
[9]官方文档: https://karpenter.sh/docs/concepts/disruption/
[10]演讲: https://www.youtube.com/watch?v=rq57liGu0H4
[11]Karpenter 快速入门: https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/
[12]eksctl: https://eksctl.io/
[13]Blueprints: https://aws-ia.github.io/terraform-aws-eks-blueprints/getting-started/
[14]kOps: https://kops.sigs.k8s.io/operations/karpenter/
[15]指南: https://karpenter.sh/docs/getting-started/migrating-from-cas/
[16]此: https://github.com/aws/karpenter-provider-aws
[17]研讨会: https://sched.co/1i7n3
点击【阅读原文】阅读网站原文。
CNCF概况(幻灯片)
扫描二维码联系我们!
CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux Foundation,是非营利性组织。
CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。请关注CNCF微信公众号。