找回密码
 立即注册
首页 业界区 安全 新手攻略!手把手教你安装配置 Karpenter

新手攻略!手把手教你安装配置 Karpenter

宿遘稠 6 天前
起初,Karpenter 是专为 AWS 环境设计的 Kubernetes 集群节点扩展工具。随着开源社区的繁荣发展,Karpenter 对阿里云和 Azure 提供了支持。
针对阿里云的支持,由 CloudPilot AI 和阿里云容器服务和弹性计算团队联合开发贡献,详情请参阅:
CloudPilot AI携手阿里云发布Karpenter阿里云 Provider,优化ACK集群自动扩展
多年来,Kubernetes 节点的扩展解决方案一直是 Cluster Autoscaler(支持多个云厂商)。而在 AWS 上,这意味着通过调整 Auto Scaling Group 的实例数量来实现扩缩容,极大限制了扩缩容的速度。
这种方法存在一些问题:
1.Autoscale Group 的更改需要一定时间,因为 ASG 需要评估条件并调用 API 来启动或终止实例,所以当一个新的 Pod 因容量问题无法调度时,它必须等待 ASG 生效并启动一个新实例。
通常,从请求更新到实际启动 EC2 实例之间会有 30 到 60 秒的延迟。
2.默认情况下,在节点的资源使用率低于 50% 且持续时间超过 10 分钟时,Cluster Autoscaler 才将该节点评估为“低利用率”。这可能导致实例长时间处于利用率不足或闲置状态,从而增加开支。
3.Cluster Autoscaler 通常会为每个 Pod 请求一个节点,因此,如果有几个 Pod 请求容量,它就会启动几个节点来满足要求,这同样会造成利用率不足和支出问题。
4.在创建 ASG 时,会通过设置最大值来限制其规模,如果达到最大值,Cluster Autoscaler 就无法进一步增加规模,从而导致集群出现容量问题。
5.Cluster Autoscaler只能根据节点的规格来评估调度情况,因此 Autoscale Group 中的所有实例的 CPU 和内存必须相同,否则会干扰计算并影响 Cluster Autoscaler 的功能——这会导致我们的集群只能使用1 种节点类型(例如,4 核 CPU 和 32GB 内存),因为没有足够多符合该规格的的实例可供选择。
6.区域感知——Cluster Autoscaler 无法均匀地在多个可用区 (AZ) 启动实例,这通常会导致选择单个区域来部署 Spot 实例,并可能导致容量问题,我们通过为每个 AZ 创建 ASG 来解决这个问题。
Karpenter

Karpenter 是一款开源产品,可根据模板驱动实例创建(就像 ASG 根据模板驱动实例创建一样),但跳过了 ASG,从而实现了超快速的实例启动。节点几乎可以立即加入集群,但需要注意的是,节点准备就绪通常需要 60 秒左右。
01/Karpenter 如何工作?

Karpenter 会评估处于待调度状态的 Pod 数量,并立即将可以调度的 Pod 其调度到可用的容量。对于其余的 Pod,Karpenter 会根据用户提供的约束条件计算最佳的机器类型,并启动一台或几台能满足工作负载的机器。由于每台机器只需拉取一次镜像,因此 Pod 的启动速度会更快。
当 Karpenter 发现某个节点上没有运行任何 Pod 时,它就会缩小该 EC2 实例的规模。
02/Karpenter的优点

Karpenter 可以灵活组合不同规格 EC2 实例以适配工作负载,使 Spot 实例的利用效率和容错性大大提高。
Karpenter 的"consolidate"功能可主动检查节点利用率,并将工作负载整合到现有或新的节点中。
与 Cluster Autoscaler 相比,Karpenter 可以在一个节点上安装更多 Pod,从而节省成本。Karpenter 强制要求我们确保集群节点具备容错能力并能够恢复,这有助于提高集群的稳定性。
Karpenter 可以设置节点自动回收和更新最新 AMI 补丁的到期时间(TTL),从而减少故障影响范围。
Karpenter 对节点进行管理的方式是,当节点被删除时,它会首先将该节点标记为不可调度(Cordon),并停止向其调度更多的节点,然后将节点排空(Drain),将 Pod 迁移到其他节点上。
这种方式使得升级过程更加可控,并且如果操作得当(不是所有节点同时删除,并且设置了 Pod 中断预算),可以实现零停机时间。
节约成本

在 Karpenter 中节省的成本取决于您当前的工作负载和您在 Cluster Autoscaler 上使用的 EC2 实例类型。
下面是一个从R5.Large实例切换到一系列实例类型时每月成本节约的示例:
1.png

如何设置 Karpenter

您可以从官方 Helm Chart 中安装 Karpenter,但请注意,第一次安装可能会失败,因为 webhook 没有及时启动(这可能会在未来的版本中得到修复),在旧 Helm 的基础上重新安装一次即可正常工作。
如果在 Karpenter 安装上有困难,欢迎尝试 Karpenter 的托管云服务 CloudPilot AI(www.cloudpilot.ai),仅需5分钟即可完成安装。
接下来,为运行 Karpenter 创建专用节点。
Karpenter 自带用于指定 Provisioners 的自定义资源,这些 Provisioners 控制着要启动的实例类型和约束条件。
Provisioner 资源的示例:
  1. apiVersion: karpenter.sh/v1alpha5
  2. kind: Provisioner
  3. metadata:
  4.   name: default
  5. spec:
  6.   # Enables consolidation which attempts to reduce cluster cost by both removing un-needed nodes and down-sizing those
  7.   # that can't be removed.  Mutually exclusive with the ttlSecondsAfterEmpty parameter.
  8.   consolidation:
  9.     enabled: true
  10.   # If omitted, the feature is disabled and nodes will never expire.  If set to less time than it requires for a node
  11.   # to become ready, the node may expire before any pods successfully start.
  12.   ttlSecondsUntilExpired: 2592000 # 30 Days = 60 * 60 * 24 * 30 Seconds;
  13.   # If omitted, the feature is disabled, nodes will never scale down due to low utilization
  14.   ttlSecondsAfterEmpty: 30
  15.   # Priority given to the provisioner when the scheduler considers which provisioner
  16.   # to select. Higher weights indicate higher priority when comparing provisioners.
  17.   # Specifying no weight is equivalent to specifying a weight of 0.
  18.   weight: 10
  19.   # Provisioned nodes will have these taints
  20.   # Taints may prevent pods from scheduling if they are not tolerated by the pod.
  21.   taints:
  22.     - key: example.com/special-taint
  23.       effect: NoSchedule
  24.   # Provisioned nodes will have these taints, but pods do not need to tolerate these taints to be provisioned by this
  25.   # provisioner. These taints are expected to be temporary and some other entity (e.g. a DaemonSet) is responsible for
  26.   # removing the taint after it has finished initializing the node.
  27.   startupTaints:
  28.     - key: example.com/another-taint
  29.       effect: NoSchedule
  30.   # Labels are arbitrary key-values that are applied to all nodes
  31.   labels:
  32.     billing-team: my-team
  33.   # Requirements that constrain the parameters of provisioned nodes.
  34.   # These requirements are combined with pod.spec.affinity.nodeAffinity rules.
  35.   # Operators { In, NotIn } are supported to enable including or excluding values
  36.   requirements:
  37.     - key: "karpenter.k8s.aws/instance-category"
  38.       operator: In
  39.       values: ["c", "m", "r"]
  40.     - key: "karpenter.k8s.aws/instance-cpu"
  41.       operator: In
  42.       values: ["4", "8", "16", "32"]
  43.     - key: karpenter.k8s.aws/instance-hypervisor
  44.       operator: In
  45.       values: ["nitro"]
  46.     - key: "topology.kubernetes.io/zone"
  47.       operator: In
  48.       values: ["us-west-2a", "us-west-2b"]
  49.     - key: "kubernetes.io/arch"
  50.       operator: In
  51.       values: ["arm64", "amd64"]
  52.     - key: "karpenter.sh/capacity-type" # If not included, the webhook for the AWS cloud provider will default to on-demand
  53.       operator: In
  54.       values: ["spot", "on-demand"]
  55.   # Karpenter provides the ability to specify a few additional Kubelet args.
  56.   # These are all optional and provide support for additional customization and use cases.
  57.   kubeletConfiguration:
  58.     clusterDNS: ["10.0.1.100"]
  59.     containerRuntime: containerd
  60.     systemReserved:
  61.       cpu: 100m
  62.       memory: 100Mi
  63.       ephemeral-storage: 1Gi
  64.     kubeReserved:
  65.       cpu: 200m
  66.       memory: 100Mi
  67.       ephemeral-storage: 3Gi
  68.     evictionHard:
  69.       memory.available: 5%
  70.       nodefs.available: 10%
  71.       nodefs.inodesFree: 10%
  72.     evictionSoft:
  73.       memory.available: 500Mi
  74.       nodefs.available: 15%
  75.       nodefs.inodesFree: 15%
  76.     evictionSoftGracePeriod:
  77.       memory.available: 1m
  78.       nodefs.available: 1m30s
  79.       nodefs.inodesFree: 2m
  80.     evictionMaxPodGracePeriod: 3m
  81.     podsPerCore: 2
  82.     maxPods: 20
  83.   # Resource limits constrain the total size of the cluster.
  84.   # Limits prevent Karpenter from creating new instances once the limit is exceeded.
  85.   limits:
  86.     resources:
  87.       cpu: "1000"
  88.       memory: 1000Gi
  89.   # References cloud provider-specific custom resource, see your cloud provider specific documentation
  90.   providerRef:
  91.     name: default
复制代码
如你所见,你甚至可以调整 Kubelet 的配置。
避免使用 Karpenter 的自定义启动模板

Karpenter 强烈建议不要使用自定义启动模板(Launch Templates)。使用自定义启动模板会导致以下问题:
◻无法支持多架构。
◻无法自动升级节点。
◻无法发现安全组(SecurityGroup)
此外,使用启动模板可能会引起困惑,因为在 Karpenter 的 Provisioners 中,有些字段被重复定义,而有些字段则会被 Karpenter 忽略,例如子网和实例类型。
您通常可以通过使用自定义用户数据或直接在 AWS 节点模板中指定自定义 AMI 来避免使用启动模板。
自定义 UserData:

Karpenter 提供了一个名为 AWSNodeTemplate 的资源,允许您在节点启动时注入用户数据(UserData):
[code]apiVersion: karpenter.k8s.aws/v1alpha1kind: AWSNodeTemplatemetadata: name: al2-examplespec: amiFamily: AL2 instanceProfile: MyInstanceProfile subnetSelector:   karpenter.sh/discovery: my-cluster securityGroupSelector:   karpenter.sh/discovery: my-clusteruserData: |MIME-Version: 1.0Content-Type: multipart/mixed; boundary="BOUNDARY"--BOUNDARYContent-Type: text/x-shellscript; charset="us-ascii"#!/bin/bashmkdir -p ~ec2-user/.ssh/touch ~ec2-user/.ssh/authorized_keyscat >> ~ec2-user/.ssh/authorized_keys
您需要登录后才可以回帖 登录 | 立即注册