
各位读者大家好,今天我们要讨论的是Karpenter:一个kubernetes集群的autoscaler ,但是在了解Karpenter之前,最好先讨论一下什么是autoscaler 以及它在kubernetes集群中的重要性。
什么是AutoScaler?
今天,许多组织使用kubernetes进行微服务协调,因为kubernetes具有许多重要的功能,如服务发现、负载平衡、自我管理等。
这使得它成为容器管理和协调的流行工具。但是,使用Kubernetes的一个承诺是,它有能力根据用户需求动态地扩展基础设施。它提供了多层次的自动扩展功能。基于Pod的扩展有Horizontal Pod AutoScaler和Vertical Pod AutoScaler,以及基于节点的Cluster AutoScaler。
Kubernetes集群是一组机器,由运行Pod的节点和请求CPU、内存和GPU等资源的Pod容器组成。Cluster Autoscaler根据Pod的资源请求,在集群中添加或删除节点。当有Pod因资源短缺而无法安排时,集群Autoscaler 会增加集群的规模。它可以被配置为不增加或减少超过一定数量的机器。今天,大多数云供应商都有自己的集群自动扩展方式。

但是,集群Autoscaler 也有一些限制,比如。
- 它不考虑实际的CPU/GPU/内存使用情况,只是考虑资源请求和限制。
- 扩容不是立马的,这导致服务出现停机或延迟等情况。
- 向下扩展没有保证。
为了克服这个问题,AWS实验室开发了一个名为Karpenter的节点生命周期管理解决方案工具,它是一个开源的解决方案和供应商中立的集群自动缩放工具。
什么是Karpenter?

Karpenter是一个开源、灵活、高性能的Kubernetes集群AutoScaler。它通过快速启动合适大小的计算资源以应对不断变化的应用负载,帮助提高应用的可用性和集群效率。Karpenter还提供及时的计算资源,以满足应用程序的需求,并将很快自动优化集群的计算资源占用,以降低成本和提高性能。
在Karpenter之前,Kubernetes用户需要动态调整其集群的计算能力,以支持使用亚马逊EC2自动扩展组和Kubernetes集群AutoScaler的应用。AWS上近一半的Kubernetes客户表示,使用Kubernetes集群AutoScaler配置集群自动缩放具有挑战性和限制性。
Karpenter如何工作?
- 检查:检查未满足的pod的资源请求。
- 评估。直接提供节点的适时容量。(无群组节点自动缩放)。
- 供给。满足pod的要求的节点。
- 调度。在新节点上运行的pods。
- 移除。移除未使用的节点。

是什么使Karpenter的效率高?
Karpenter有两个控制循环,最大限度地提高集群的可用性和效率。
- Allocator - Allocator确保在节点上快速调度待定的pod。它充当了快动作的控制器。
- Reallocator - 当多余的节点容量被重新分配为pod被驱逐时,Reallocator 就会出现。Reallocator是一个对成本敏感的慢动作控制器。
AutoScaler(AS)和Karpenter之间的区别?
在Cluster Autoscaler的情况下,用户不能直接控制实例,我们通过Auto Scaling Group控制它们。它只是要求ASG增加或减少节点的数量。但在这里karpenter与Cluster AutoScaler不同,Karpenter直接管理节点,这使得它在容量不可用时,可以在几毫秒内重试,而不是几分钟。它还允许Karpenter利用不同的实例类型、可用性区域和购买选项,而无需创建数百个节点组。
实践
安装Karpenter
前置条件
- AWS CLI
- kubectl – the Kubernetes CLI
- eksctl – the CLI for AWS EKS
- EKS Cluster – Setup eks cluster
- helm – the package manager for Kubernetes
-
在设置好工具后,设置以下环境变量来存储常用的值。
export CLUSTER_NAME=<cluster-name> export AWS_DEFAULT_REGION=<region-code> AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) -
现在,通过以下命令连接到创建的EKS集群。
-
连接aws账户
aws configure
-

-
通过eksctl创建集群。
cat <<EOF > demo-cluster.yaml --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ${CLUSTER_NAME} region: ${AWS_DEFAULT_REGION} version: "1.21" tags: karpenter.sh/discovery: ${CLUSTER_NAME} managedNodeGroups: - instanceType: t3.micro amiFamily: AmazonLinux2 name: ${CLUSTER_NAME} desiredCapacity: 1 minSize: 1 maxSize: 3 iam: withOIDC: true EOFeksctl create cluster -f demo-cluster.yaml
-
为Karpenter和Karpenter控制器创建IAM角色。
- IAM资源创建。
TEMPOUT=$(mktemp) curl -fsSL https://karpenter.sh/v0.6.1/getting-started/cloudformation.yaml > $TEMPOUT \ && aws cloudformation deploy \ --stack-name Karpenter-${CLUSTER_NAME} \ --template-file ${TEMPOUT} \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides ClusterName=${CLUSTER_NAME}- 授予使用配置文件的实例连接到集群的权限。
eksctl create iamidentitymapping \ --username system:node:{{EC2PrivateDNSName}} \ --cluster ${CLUSTER_NAME} \ --arn arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME} \ --group system:bootstrappers \ --group system:nodes-
KarpenterController IAM角色。
eksctl create iamserviceaccount \ --cluster $CLUSTER_NAME --name karpenter --namespace karpenter \ --attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/KarpenterControllerPolicy-$CLUSTER_NAME \ --approve
-
安装Karpenter Helm Chart
helm repo add karpenter https://charts.karpenter.sh
helm repo update
helm upgrade --install karpenter karpenter/karpenter --namespace karpenter \
--create-namespace --set serviceAccount.create=false --version v0.6.1 \
--set controller.clusterName=${CLUSTER_NAME} \
--set controller.clusterEndpoint=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output json) \
--set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME}

-
部署Provisioner
基于karpenter的pod属性(如标签和亲和力)的调度和供应决策由单个karpenter供应者处理。供应者使用安全gropu选择器和子网选择器来发现启动节点的资源。如果你记得我们使用了一个标签(tags:
karpenter.sh/discovery: ${CLUSTER_NAME})在之前的eksctl命令中使用过。cat <<EOF | kubectl apply -f - apiVersion: karpenter.sh/v1alpha5 kind: Provisioner metadata: name: default spec: requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot"] limits: resources: cpu: 1000 provider: subnetSelector: karpenter.sh/discovery: ${CLUSTER_NAME} securityGroupSelector: karpenter.sh/discovery: ${CLUSTER_NAME} ttlSecondsAfterEmpty: 30 EOF

现在karpenter已经为provisioning节点做好了准备,现在我们将部署一些pod,看看karpenter如何工作。
-
自动节点 Provisioning
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: inflate spec: replicas: 0 selector: matchLabels: app: inflate template: metadata: labels: app: inflate spec: terminationGracePeriodSeconds: 0 containers: - name: inflate image: busybox resources: requests: cpu: 1 EOFkubectl scale deployment inflate --replicas 5 kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l karpenter=controller -o name)

现在,删除该部署。30秒后(ttlSecondsAfterEmpty),Karpenter应该终止现在的空节点。
kubectl delete deployment inflate
kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l karpenter=controller -o name)
总结
因此,在这篇博客中,我们已经看到了kubernetes集群autoscaler 的重要性和使用,以及Karpenter如何作为kubernetes集群自动调节器的主要工具。通过它,我们可以实现kubernetes集群或部署在集群中的应用程序的高可用性。这篇文章就写到这里了。如果你有任何反馈或疑问,请在评论中告诉我。另外,如果你喜欢这篇文章,请鼓励我,我将在未来继续为你写这样的博客。继续阅读,继续编码。
原文标题:Karpenter : A Kubernetes Cluster AutoScaler
原文作者:abhishek
原文地址:https://blog.knoldus.com/karpenter-a-kubernetes-cluster-autoscaler/




