关于网络:Karpenter-新一代-Kubernetes-auto-scaling-工具

51次阅读

共计 19035 个字符,预计需要花费 48 分钟才能阅读完成。

在亚马逊云科技 2021 re:Invent 大会期间,亚马逊云科技发表为 Kubernetes 构建的开源主动扩缩容我的项目 Karpenter 降级至 0.5 版本并 GA,可在生产环境应用。在 Kubernetes 上的 auto scaling 始终被人关注,以后的 kubernetes 提供 Cluster Autocaler 用于制订调度和扩缩决策。那么,既然有了 Kubernetes Cluster Autoscaler,为何还要反复造轮子,去开发新的 auto scaling 工具呢? 本文将介绍 Karpenter 作用和原理,同时对比一下大家相熟的 Cluster Autoscaler,并演示 Karpenter 的基本操作。

Karpenter 是什么?

Karpenter 是一个为 Kubernetes 构建的开源主动扩缩容我的项目。它进步了 Kubernetes 应用程序的可用性,而无需手动或适度配置计算资源。Karpenter 旨在通过观察不可调度的 Pod 的聚合资源申请并做出启动和终止节点的决策,以最大限度地缩小调度提早,从而在几秒钟内(而不是几分钟)提供适合的计算资源来满足您的应用程序的需要。

Karpenter 与 Cluster Autocaler

在 Kubernetes 上能够实现集群主动缩放的工具,有 Cluster Autoscaler、Escalator 和 Cerebral 等。惋惜有些工具曾经疏于保护或终止开发。现在 Cluster Autoscaler 是集群主动缩放组件的首选,常见的长处包含:能够使集群依据需要的增长而主动扩容;通过无效整合利用资源和终止不必要的节点而较少基础架构带来的老本;其开发者是中立的,反对所有支流的私有云厂商;利用宽泛,通过了实战的考验;反对大概 1000 个节点的集群。

上面咱们理解一下 Cluster Autoscaler 是如何工作的,如下图所示:当有 Pod 因为资源有余状态为 pending 时,就会触发 Cluster Autoscaler 的扩大机制,Cluster Autoscaler 会减少托管节点组底层的 Auto Scaling Group 中的 desired 实例数量,从而通过 Auto Scaling Group 部署新的 Amazon EC2 实例退出节点组,作为预置新节点,pending 状态的 pod 会被调度到新的节点进行部署。

Cluster Autoscaler 在应用中有一些问题和注意事项。Cluster Autoscaler 对节点组进行的主动扩缩容,是依赖于 launch template 和 Auto Scaling group 进行的,所以 Auto Scaling group 的最大值和最小值也会限度节点组的最大和最小节点数量。有时 Cluster Autoscaler 为了进行一些指定的扩缩容操作,咱们须要为每种实例类型或可用区独自区创立一个节点组。在节点组中如果创立节点失败,并不会立即进行解决,因为 Cluster Autoscaler 处理错误的机制是基于超时。Cluster Autocaler 官网的性能测试报告,测试中应用了 1000 个节点,每个节点 30 个 pod,超过这样的规模目前还没有官网的测试反馈。Cluster Autocaler 的操作也是比较复杂的,足有 78 个命令行参数。并且用户不能自定义调度器。基于以上的问题,Zalando 公司基于 Cluster Autocaler 做了批改,并且在 github 里 fork 出了一个分支,他们改良了节点解决代码,反对多实例类型的 Auto Scaling Group,应用了更加牢靠的 backoff 逻辑。但这些改良可能还不够,咱们是否能够领有一个更简略、扩大更疾速、反对更大集群的扩缩容工具?这就是 Karpenter 了。

Karpenter 勾销了节点组的概念,这是它与 Cluster Autoscaler 的基本区别,节点组通常是效率较低的起因之一。Karpenter 间接提供计算资源,动静的计算 pod 须要何种大小的 Amazon EC2 实例类型作为节点。从 Cluster Autocaler 的动态模版到 Karpenter 的动静生成模版,不用去创立节点组来确定实例的各种属性,从而升高了配置的复杂性。Cloud Provider 的 API 负载也会大大减少,在 Cluster Autocaler 中,Auto Scaling group 总会一直申请 Cloud Provider 来确认状态,在集群宏大当前,很可能碰到 API 调用限度,造成整个零碎进行响应。而 Karpenter 只在创立和删除容量时调用 API,这种设计能够反对更高的 API 吞吐量。没有了节点组,调度的复杂程度也被升高,因为 Cluster Autoscaler 不同节点组有不同属性,须要思考 pod 被调度到哪个节点组。

上面咱们理解一下 Karpenter 的工作过程,如下图所示:当有一个 pending 状态的 pod 时,如果还有存在的容量,则由 kube scheduler 进行调度。如果没有容量造成 pod 不能被调度,则由 Karpenter 绕过 kube scheduler 将 pod 绑定到新建的预置节点。

启动 Amazon EC2 实例的形式很多,Cluster Autoscaler 应用 Auto Scaling group,Karpenter 应用 Amazon EC2 Fleets,这两种形式都能够启动 Amaozn EC2 实例。之所以抉择 Amaozn EC2 Fleets,是因为它更弱小更灵便,举例来说,当决定为一组 pod 创立节点时,能够不受限于可用区、实例类型,咱们能够在 Cloud Providers 指定实例类型、可用区等属性,对 Karpenter 进行束缚,Karpenter 能够在指定的属性中寻找最适宜的实例类型来部署 pod。Amazon EC2 fleet 也会抉择指定实例中最便宜的实例类型。另外,应用 Auto Scaling group 来启动节点,大概须要 30 秒的工夫,如果改用 Amazon EC2 Fleets 将远远少于 30 秒。

调度也十分重要,Karpenter 也优化了调度,一旦容量扩容的决定被做出,收回创立实例的申请,会立刻取得实例 ID,不等实例创立实现就创立节点对象,将须要调度的 pod 绑定到节点。这是在 kube scheduler 之外强制执行了一个调度决策。这样做的益处有两个,第一,为 pod 部署升高了 5 秒左右的提早,第二,不用匹配 Karpenter 与 kube scheduler 之间的版本。

通过 nodeSelector,咱们能够应用 kubernetes Well-Known Label:https://kubernetes.io/docs/re… 来指定属性启动实例,能够指定的属性包含可用区,实例类型,容量类型,CPU 架构,操作系统等。

如何为 pod 抉择适合的 Amazon EC2 实例,即 Bin Packing 打包问题。Karpenter 采纳了 First Fit Descending 算法,咱们将 pod 依照从大到小排序,先将最大的 pod 去适配实例,如果不行就再换小一些的 pod,这个过程尝试的实例越来越小,直到将最小的 pod 找到适合的实例。这样做的益处是,大的 pod 常常会在实例上留下一些间隙,能够让前面小 pod 填入,能够更无效的利用资源。对于 pod 排序的优先级,能够依照 CPU、内存或 euclidean。

Karpenter 不止减少节点,也负责终止节点。有一个控制器专门负责终止节点,默认一个节点 5 分钟内没有 pod,Karpenter 就会终止它。另外,当 Amazon EC2 实例因为某种原因处于 unhealthy 状态或 spot 实例行将被回收,它都会发送一个事件,Karpenter 会响应这些事件,新创建节点来重部署下面的 pod。另外 Karpenter 也能够为节点设置一个 TTL 值,比方配置节点生命周期是 90 天,这个性能在降级时十分有用,能够确保节点始终滚动降级。

Karpenter 也对节点的启动过程做了优化,之前节点启动都有一大堆步骤,个别云中的节点启动大概须要 2 分钟,理论这是因为适度配置造成的,当初这个提早被 Karpenter 缩小到了 15 到 50 秒。

Karpenter 上手指南

Karpenter 主动配置新节点以响应不可调度的 pod。Karpenter 通过监控 Kubernetes 集群内的事件,而后向底层 cloud providers 发送命令来做到这一点。在此示例中,集群在亚马逊云科技的 Elastic Kubernetes Service (EKS) 上运行。Karpenter 旨在与云提供商无关,但目前仅反对亚马逊云科技 cloud providers。欢送退出 https://github.com/awslabs/ka… 以开发其余版本 cloud providers。实现本指南所需的工夫不到 1 小时,老本低于 0.25 美元。记得依照文末形式对资源进行清理删除。

Karpenter 上手之环境筹备

本次试验咱们会用到四个工具:

1. 亚马逊云科技 CLI,能够参考以下链接进行装置:https://docs.aws.amazon.com/c…,装置实现进行 AKSK 配置,region 输出 us-west-2。

2.Kubectl,参考以下链接装置:
https://kubernetes.io/docs/ta…

3.Eksctl,参考以下链接装置:
https://docs.aws.amazon.com/e…

4.Helm,参考以下链接装置:
https://helm.sh/docs/intro/in…

装置完必要工具后,运行 shell 设置以下环境变量:

export CLUSTER_NAME=$USER-karpenter-demo
export AWS_DEFAULT_REGION=us-west-2
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

* 左滑查看更多

应用 eksctl 创立集群。此示例配置文件指定了一个具备一个初始节点的根本集群,并为该集群设置了一个 IAM OIDC provider,以用于后续步骤设置 IAM Roles for Service Accounts(IRSA):

cat <<EOF > cluster.yaml
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: ${CLUSTER_NAME}
  region: ${AWS_DEFAULT_REGION}
  version: "1.20"
managedNodeGroups:
  - instanceType: m5.large
    amiFamily: AmazonLinux2
    name: ${CLUSTER_NAME}-ng
    desiredCapacity: 1
    minSize: 1
    maxSize: 10
iam:
  withOIDC: true
EOF
eksctl create cluster -f cluster.yaml

* 左滑查看更多

试验中咱们应用的是 Amazon EKS 里的 managed Node Groups 的节点来部署 Karpenter。Karpenter 也能够运行在自建节点,fargate。

Karpenter 发现子网须要有指定 tag:kubernetes.io/cluster/$CLUSTER_NAME。将此 tag 增加到为您的集群配置的关联子网。

SUBNET_IDS=$(aws cloudformation describe-stacks \
    --stack-name eksctl-${CLUSTER_NAME}-cluster \
    --query 'Stacks[].Outputs[?OutputKey==`SubnetsPrivate`].OutputValue' \
    --output text)
aws ec2 create-tags \
    --resources $(echo $SUBNET_IDS | tr ',' '\n') \
    --tags Key="kubernetes.io/cluster/${CLUSTER_NAME}",Value=

* 左滑查看更多

Karpenter 启动的 Amazon EC2 实例必须应用 InstanceProfile 运行,该配置文件授予运行容器和配置网络所需的权限。Karpenter 应用名称 KarpenterNodeRole-${ClusterName} 发现 InstanceProfile。

首先,应用 Amazon CloudFormation 创立 IAM 资源。

TEMPOUT=$(mktemp)
curl -fsSL https://karpenter.sh/docs/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}

* 左滑查看更多

其次,应用配置文件授予 Amazon EC2 实例连贯到集群的拜访权限。此命令将 Karpenter 节点角色增加到您的 aws-auth 配置映射,容许具备此角色的节点连贯到集群。

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

* 左滑查看更多

Karpenter 自身还须要启动 Amazon EC2 实例的权限,与 Cluster Autoscaler 一样,咱们通过 IAM Roles for Service Accounts(IRSA) 实现,用上面命令配置:

eksctl create iamserviceaccount \
  --cluster $CLUSTER_NAME --name karpenter --namespace karpenter \
  --attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/KarpenterControllerPolicy-$CLUSTER_NAME \
  --approve

* 左滑查看更多

如果您之前没有运行过 Amazon EC2 spot 实例,请运行上面命令,如果之前运行过 spot 实例,上面命令会报错,请疏忽。

aws iam create-service-linked-role --aws-service-name spot.amazonaws.com

* 左滑查看更多

Karpenter 是用 Helm 打包的,咱们须要应用 Helm 来装置:

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 0.4.1 \
  --wait # for the defaulting webhook to install before creating a Provisioner

* 左滑查看更多

关上 debug 日志:

kubectl patch configmap config-logging -n karpenter --patch '{"data":{"loglevel.controller":"debug"}}'

* 左滑查看更多

Karpenter 上手之 Provisioner 配置

Karpenter Provisioners 是一种 Kubernetes 自定义资源 (CustomResourceDefinitions),使客户可能在其集群中配置 Karpenter 的束缚,比方实例类型,可用区等。Karpenter Provisioner 带有一组全局默认值,如果您本人定义了 Provisioner,默认值会被笼罩。一个集群中,也能够存在多个 Karpenter Provisioners,默认状况下,pod 将应用名为 default 的 Provisioner 定义的规定。如果您创立了第二个 Provisioner,请应用节点选择器指定 karpenter.sh/provisioner-name:alternative-provisioner。与此同时,应用默认 Provisioner 也须要应用节点选择器明确指定 karpenter.sh/provisioner-name。

上面是一个 Provisioner 的示例:

cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
    - key: node.k8s.aws/capacity-type
      operator: In
      values: ["spot"]
  provider:
    instanceProfile: KarpenterNodeInstanceProfile-${CLUSTER_NAME}
    cluster:
      name: ${CLUSTER_NAME}
      endpoint: $(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output json)
  ttlSecondsAfterEmpty: 30
EOF

* 左滑查看更多

能够看到,示例中仅对 capacity-type 做了 spot 的限度,并且指定了 ttlSecondsAfterEmpty 为 30。应用这个 Provisioner 只会创立 spot 类型实例,并且在实例为空后 30 秒后敞开。更多 Provisioner 配置项能够参考:https://karpenter.sh/docs/pro…

Karpenter 上手之主动扩缩容

咱们应用 pause image 创立一个 replicas 为 0 的 deployment。

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:
      containers:
        - name: inflate
          image: public.ecr.aws/eks-distro/kubernetes/pause:3.2
          resources:
            requests:
              cpu: 1
EOF

* 左滑查看更多

而后将 replicas 设置为 5,察看 karpenter 日志:

kubectl scale deployment inflate --replicas 5
kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l karpenter=controller -o name)

* 左滑查看更多

依据上面输入的 karpenter 日志咱们能够看出,16:13:32 时,karpenter 发现 5 个 pod 被创立。咱们看到在 16:13:37 时,实现了节点启动以及 pod 与节点绑定的操作,整个过程仅用了 5 秒。咱们看到,这次 pod 调度须要 5 个 vcpu,karpenter 主动抉择了 c5.2xlagre 的示例,这体现了 karpenter 缩小复杂度,谋求速度的设计理念,会把多个 pod 调度合并在一个节点上。

2021-10-31T16:13:30.536Z        INFO    controller.allocation.provisioner/default       Starting provisioning loop      {"commit": "c902206"}
2021-10-31T16:13:30.536Z        INFO    controller.allocation.provisioner/default       Waiting to batch additional pods        {"commit": "c902206"}
2021-10-31T16:13:32.050Z        INFO    controller.allocation.provisioner/default       Found 5 provisionable pods      {"commit": "c902206"}
2021-10-31T16:13:32.932Z        DEBUG   controller.allocation.provisioner/default       Discovered 318 EC2 instance types       {"commit": "c902206"}
2021-10-31T16:13:32.933Z        DEBUG   controller.allocation.provisioner/default       Excluding instance type t4g.nano because there are not enough resources for kubelet and system overhead     {"commit": "c902206"}
2021-10-31T16:13:32.935Z        DEBUG   controller.allocation.provisioner/default       Excluding instance type t3.nano because there are not enough resources for kubelet and system overhead      {"commit": "c902206"}
2021-10-31T16:13:32.939Z        DEBUG   controller.allocation.provisioner/default       Excluding instance type t3a.nano because there are not enough resources for kubelet and system overhead     {"commit": "c902206"}
2021-10-31T16:13:32.968Z        INFO    controller.allocation.provisioner/default       Computed packing for 5 pod(s) with instance type option(s) [c1.xlarge c3.2xlarge c4.2xlarge c6i.2xlarge c5a.2xlarge c5d.2xlarge c6g.2xlarge c5ad.2xlarge c6gd.2xlarge a1.2xlarge c6gn.2xlarge c5.2xlarge c5n.2xlarge m3.2xlarge m6g.2xlarge m4.2xlarge m5zn.2xlarge m5dn.2xlarge m5n.2xlarge m5d.2xlarge]       {"commit": "c902206"}
2021-10-31T16:13:33.146Z        DEBUG   controller.allocation.provisioner/default       Discovered subnets: [subnet-0a538ed8c05288206 subnet-07a9d3f4dbc92164c subnet-0b14f140baa9a38cb]    {"commit": "c902206"}
2021-10-31T16:13:33.262Z        DEBUG   controller.allocation.provisioner/default       Discovered security groups: [sg-0afb56113d9feb2e8]      {"commit": "c902206"}
2021-10-31T16:13:33.265Z        DEBUG   controller.allocation.provisioner/default       Discovered kubernetes version 1.20      {"commit": "c902206"}
2021-10-31T16:13:33.317Z        DEBUG   controller.allocation.provisioner/default       Discovered ami ami-0a69abe3cea2499b7 for query /aws/service/eks/optimized-ami/1.20/amazon-linux-2-arm64/recommended/image_id        {"commit": "c902206"}
2021-10-31T16:13:33.365Z        DEBUG   controller.allocation.provisioner/default       Discovered ami ami-088105bab8bfa2db6 for query /aws/service/eks/optimized-ami/1.20/amazon-linux-2/recommended/image_id      {"commit": "c902206"}
2021-10-31T16:13:33.365Z        DEBUG   controller.allocation.provisioner/default       Discovered caBundle, length 1066        {"commit": "c902206"}
2021-10-31T16:13:33.506Z        DEBUG   controller.allocation.provisioner/default       Created launch template, Karpenter-karpenter-demo-16982985708254790476      {"commit": "c902206"}
2021-10-31T16:13:33.507Z        DEBUG   controller.allocation.provisioner/default       Discovered caBundle, length 1066        {"commit": "c902206"}
2021-10-31T16:13:33.640Z        DEBUG   controller.allocation.provisioner/default       Created launch template, Karpenter-karpenter-demo-11290710479729449633      {"commit": "c902206"}
2021-10-31T16:13:36.898Z        INFO    controller.allocation.provisioner/default       Launched instance: i-0f38cb0ade09a537c, hostname: ip-192-168-132-54.us-west-2.compute.internal, type: c5.2xlarge, zone: us-west-2a, capacityType: spot      {"commit": "c902206"}
2021-10-31T16:13:37.050Z        INFO    controller.allocation.provisioner/default       Bound 5 pod(s) to node ip-192-168-132-54.us-west-2.compute.internal{"commit": "c902206"}
2021-10-31T16:13:37.050Z        INFO    controller.allocation.provisioner/default       Starting provisioning loop      {"commit": "c902206"}
2021-10-31T16:13:37.050Z        INFO    controller.allocation.provisioner/default       Waiting to batch additional pods        {"commit": "c902206"}
2021-10-31T16:13:38.050Z        INFO    controller.allocation.provisioner/default       Found 0 provisionable pods      {"commit": "c902206"}

* 左滑查看更多

咱们抉择一个 pod 来查看它的创立耗时:

kubectl get pod <pod_name> -oyaml

* 左滑查看更多

从上面日志能够看出,16:13:36 时,pod 被调度,16:14:45 时 pod ready。整个过程为 1 分 9 秒。思考到是 5 个 pod,并且这段时间是创立 ec2 启动模版,ec2 实例启动并退出集群节点和 pod 向节点部署的工夫,整个过程还是很快的。如果想减速这段过程,能够思考应用 placeholder pod 做 Over-Provisioning 的形式。

……
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2021-10-31T16:14:17Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2021-10-31T16:14:45Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2021-10-31T16:14:45Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2021-10-31T16:13:36Z"
    status: "True"
type: PodScheduled
……

* 左滑查看更多

咱们关上 Amazon EC2 Dashboard,查看 spot requests,能够看到 karpenter 是应用的 spot fleet,以后咱们应用的是 spot 实例,如果应用 karpenter 启动 on demand 实例,能够应用 aws cli 命令 aws ec2 describe-fleets 去查看。

上面咱们删除方才创立的 Deployment,并察看 karpenter 日志:

kubectl delete deployment inflate
kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l karpenter=controller -o name)

* 左滑查看更多

从日志中咱们能够看到,16:40:16 时发现了空实例,ttlSecondsAfterEmpty 在 Provisioner 中设置为 30,则 30 秒后,才将实例终止。

2021-10-31T16:13:39.549Z        INFO    controller.allocation.provisioner/default       Watching for pod events {"commit": "c902206"}
2021-10-31T16:40:16.040Z        INFO    controller.Node Added TTL to empty node ip-192-168-132-54.us-west-2.compute.internal    {"commit": "c902206"}
2021-10-31T16:40:46.059Z        INFO    controller.Node Triggering termination after 30s for empty node ip-192-168-132-54.us-west-2.compute.internal    {"commit": "c902206"}
2021-10-31T16:40:46.103Z        INFO    controller.Termination  Cordoned node ip-192-168-132-54.us-west-2.compute.internal      {"commit": "c902206"}
2021-10-31T16:40:46.290Z        INFO    controller.Termination  Deleted node ip-192-168-132-54.us-west-2.compute.internal       {"commit": "c902206"}

* 左滑查看更多

除了利用 provisioner 去主动抉择扩大节点类型,咱们也能够在 pod 中应用 nodeSelector 来指定 Well-Known Labes 启动节点,上面是一段 Deployment 示例:

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:
      containers:
        - name: inflate
          image: public.ecr.aws/eks-distro/kubernetes/pause:3.2
          resources:
            requests:
              cpu: 1
      nodeSelector:
        node.kubernetes.io/instance-type: c5.xlarge
EOF

* 左滑查看更多

察看 karpenter 日志,本次曾经有了第一次扩大创立的 launch template,所以从发现 pod provisionable,到创立实例绑定 pod,仅用了 4 秒。但与第一次不同,咱们这次在 Deployment 时利用 nodeSelector 指定了应用 c5.xlarge 实例,所以 karpenter 创立了 2 台 c5.xlarge 实例来部署 pod,而不是第一次的一台 c5.2xlarge。

kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l karpenter=controller -o name)
……
2021-10-31T17:13:28.459Z        INFO    controller.allocation.provisioner/default       Waiting to batch additional pods        {"commit": "c902206"}
2021-10-31T17:13:29.549Z        INFO    controller.allocation.provisioner/default       Found 5 provisionable pods      {"commit": "c902206"}
2021-10-31T17:13:30.648Z        DEBUG   controller.allocation.provisioner/default       Discovered 318 EC2 instance types       {"commit": "c902206"}
2021-10-31T17:13:30.661Z        INFO    controller.allocation.provisioner/default       Computed packing for 3 pod(s) with instance type option(s) [c5.xlarge]      {"commit": "c902206"}
2021-10-31T17:13:30.675Z        INFO    controller.allocation.provisioner/default       Incremented node count to 2 on packing for 2 pod(s) with instance type option(s) [c5.xlarge]        {"commit": "c902206"}
2021-10-31T17:13:30.860Z        DEBUG   controller.allocation.provisioner/default       Discovered subnets: [subnet-0a538ed8c05288206 subnet-07a9d3f4dbc92164c subnet-0b14f140baa9a38cb]    {"commit": "c902206"}
2021-10-31T17:13:30.951Z        DEBUG   controller.allocation.provisioner/default       Discovered security groups: [sg-0afb56113d9feb2e8]      {"commit": "c902206"}
2021-10-31T17:13:30.955Z        DEBUG   controller.allocation.provisioner/default       Discovered kubernetes version 1.20      {"commit": "c902206"}
2021-10-31T17:13:31.016Z        DEBUG   controller.allocation.provisioner/default       Discovered ami ami-088105bab8bfa2db6 for query /aws/service/eks/optimized-ami/1.20/amazon-linux-2/recommended/image_id      {"commit": "c902206"}
2021-10-31T17:13:31.016Z        DEBUG   controller.allocation.provisioner/default       Discovered caBundle, length 1066        {"commit": "c902206"}
2021-10-31T17:13:31.052Z        DEBUG   controller.allocation.provisioner/default       Discovered launch template Karpenter-karpenter-demo-11290710479729449633    {"commit": "c902206"}
2021-10-31T17:13:33.150Z        INFO    controller.allocation.provisioner/default       Launched instance: i-04604513375c3dc3a, hostname: ip-192-168-156-86.us-west-2.compute.internal, type: c5.xlarge, zone: us-west-2a, capacityType: spot       {"commit": "c902206"}
2021-10-31T17:13:33.150Z        INFO    controller.allocation.provisioner/default       Launched instance: i-0e058845370c428ec, hostname: ip-192-168-154-221.us-west-2.compute.internal, type: c5.xlarge, zone: us-west-2a, capacityType: spot      {"commit": "c902206"}
2021-10-31T17:13:33.207Z        INFO    controller.allocation.provisioner/default       Bound 3 pod(s) to node ip-192-168-156-86.us-west-2.compute.internal{"commit": "c902206"}
2021-10-31T17:13:33.233Z        INFO    controller.allocation.provisioner/default       Bound 2 pod(s) to node ip-192-168-154-221.us-west-2.compute.internal{"commit": "c902206"}
……

* 左滑查看更多

关上 Amazon EC2 Dashboard,查看 spot request,能够看到 2 个 spot fleet,能够看到即便同型号实例,karpenter 为了能够疾速调度,也会别离创立 fleet。

删除试验环境

执行上面命令,删除试验环境,防止产生额定费用。

helm uninstall karpenter --namespace karpenter
eksctl delete iamserviceaccount --cluster ${CLUSTER_NAME} --name karpenter --namespace karpenter
aws cloudformation delete-stack --stack-name Karpenter-${CLUSTER_NAME}
aws ec2 describe-launch-templates \
    | jq -r ".LaunchTemplates[].LaunchTemplateName" \
    | grep -i Karpenter-${CLUSTER_NAME} \
    | xargs -I{} aws ec2 delete-launch-template --launch-template-name {}
eksctl delete cluster --name ${CLUSTER_NAME}

* 左滑查看更多

总结

Karpenter 作为一款新的 Kubernetes auto scaling 工具,它有着更疾速更灵便的劣势。对于大规模的 Kubernetes 集群有着更好的反对。在具备这些长处的同时,它还大大降低的运维工作量,使 auto scaling 更加主动。

本篇作者

夏焱

亚马逊云科技解决方案架构师

目前专一于容器化解决方案。在退出亚马逊云科技之前,曾就任于惠普、IBM 等科技公司,从事数据中心基础架构相干工作,领有十余年技术服务教训。

正文完
 0