+++
title = " Scaling with Karpenter”
hidden=true
weight = 47 pre = “47. ”
+++
标题: 使用 Karpenter 进行扩展 权重: 65
:::alert[如果您直接来到这一部分,请确保您已完成上述描述的先决条件 ]
Karpenter 是一个动态的、高性能的、开源的 Kubernetes 集群自动扩展解决方案。Karpenter 的工作原理如下:
Karpenter 的任务是添加节点来处理无法调度的 pod、在这些节点上调度 pod,以及在不需要这些节点时删除它们。要配置 Karpenter,您需要创建供应商,它们定义 Karpenter 如何管理无法调度的 pod 和过期节点。下图说明了它的工作原理:
本工作坊会话将向您展示如何在为您在本工作坊中配置的 EKS 集群中设置 Karpenter。我们将使用 TPC-DS 数据,依次运行 3 个 Spark SQL 查询,每个查询使用 50 个执行器处理 177 亿条记录。我们将使用来自 emr-on-eks-benchmark 存储库的基准测试。
我们将使用 pod 模板 在按需实例上调度 Spark 驱动程序,在 EC2 Spot 实例上调度执行器。
还有另一个工具需要安装,但在上面提供的引导程序中没有包括:
请按照以下说明安装 Helm:
curl -L https://git.io/get_helm.sh | bash -s -- --version v3.8.2
:button[下载 zip 文件]{href=”/static/zip/karpenter_files.zip” action="download”}
karpenter_files.zip
并将以下文件上传到提供的 S3 存储桶的以下前缀:export ACCOUNTID="${ACCOUNTID:-$(aws sts get-caller-identity --query Account --output text)}"
export AWS_REGION="${AWS_REGION:-$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')}"
## 从 CloudFormation 输出选项卡获取 S3 存储桶名称
## 示例: emr-eks-workshop-123456789012
export S3BUCKET="emr-eks-workshop-123456789012"
unzip karpenter_files.zip
aws s3 cp karpenter-driver-pod-template.yaml s3://${S3BUCKET}/pod-template/
aws s3 cp karpenter-executor-pod-template.yaml s3://${S3BUCKET}/pod-template/
kubectl
并访问 EKS 集群。# 使用以下命令进行测试,您应该会看到节点列表
kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-113-17.ec2.internal Ready <none> 4m20s v1.22.17-eks-0a21954
ip-10-0-113-86.ec2.internal Ready <none> 2d1h v1.22.17-eks-0a21954
ip-10-0-128-138.ec2.internal Ready <none> 2d1h v1.22.17-eks-0a21954
ip-10-0-155-242.ec2.internal Ready <none> 7m49s v1.22.17-eks-0a21954
如果您没有看到上述节点列表,请通过以下方式更新您的 kubeconfig:
export EKSCLUSTER_NAME="${EKSCLUSTER_NAME:-emr-eks-workshop}"
aws eks update-kubeconfig --region ${AWS_REGION} --name ${EKSCLUSTER_NAME}
karpenter-setup.sh
脚本,它将安装所有必要的 Karpenter 组件。输入为您在本工作坊中创建的 S3 存储桶名称。如果方括号中显示的存储桶名称正确,只需按 Enter 继续。./karpenter-setup.sh
Please enter the bucket name [emr-eks-workshop-XXXXXXXXXXXX]:
# 验证 Karpenter pod 已安装在 karpenter 命名空间中
kubectl get pods -n karpenter
NAME READY STATUS RESTARTS AGE
karpenter-9746cb6b8-dc5lp 2/2 Running 0 22h
karpenter-9746cb6b8-dlnt4 2/2 Running 0 14h
查看为 Karpenter 部署的供应商:
# 获取安装的供应商列表
kubectl get provisioners
NAME AGE
default 3d21h
# 描述默认供应商
kubectl describe provisioners default
Name: default
Namespace:
Labels: <none>
Annotations: <none>
API Version: karpenter.sh/v1alpha5
Kind: Provisioner
Metadata:
Creation Timestamp: 2023-07-20T22:39:54Z
Generation: 1
Managed Fields:
API Version: karpenter.sh/v1alpha5
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:labels:
.:
f:app:
f:limits:
.:
f:resources:
.:
f:cpu:
f:provider:
.:
f:launchTemplate:
f:subnetSelector:
f:requirements:
f:ttlSecondsAfterEmpty:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2023-07-20T22:39:54Z
Resource Version: 748457
UID: d1381ee0-f5bb-45c0-ac1b-5de837c04560
Spec:
Labels:
App: kspark
Limits:
Resources:
Cpu: 2k
Provider:
Launch Template: emr-eks-workshop-karpenter-launchtemplate
Subnet Selector:
karpenter.sh/discovery: emr-eks-workshop
Requirements:
Key: karpenter.sh/capacity-type
Operator: In
Values:
on-demand
spot
Key: kubernetes.io/arch
Operator: In
Values:
amd64
Key: karpenter.k8s.aws/instance-family
Operator: In
Values:
c5
c5a
c5d
c5ad
m5
c6a
Key: karpenter.k8s.aws/instance-size
Operator: In
Values:
2xlarge
4xlarge
8xlarge
9xlarge
Key: topology.kubernetes.io/zone
Operator: In
Values:
us-east-1a
Ttl Seconds After Empty: 30
Status:
Events: <none>
从上面的供应商描述中,Karpenter 将部署具有以下特征的 EC2 节点:
emr-eks-workshop-karpenter-launchtemplate
emr6.5-tpcds-karpenter.sh
脚本提交一个 Spark 作业:# 此脚本将运行 EMR 基准脚本,每个执行器使用 4 个 vCPU 和 7 GB RAM
./emr6.5-tpcds-karpenter.sh 4 7
上面的脚本使用 pod 模板来自定义 Spark pod 被调度到哪些 EC2 节点。作业提交中指示 pod 模板的配置在这里描述:
"spark.kubernetes.node.selector.app": "kspark",
"spark.kubernetes.driver.podTemplateFile": "s3://'$S3BUCKET'/pod-template/karpenter-driver-pod-template.yaml",
"spark.kubernetes.executor.podTemplateFile": "s3://'$S3BUCKET'/pod-template/karpenter-executor-pod-template.yaml",
该作业将在标签为 app = kspark
的 EC2 节点上运行,Spark 驱动程序和 Spark 执行器将根据各自的 pod 模板被调度到 EC2 节点上。
Spark 驱动程序 pod 模板如下:
# // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# // SPDX-License-Identifier: MIT-0
apiVersion: v1
kind: Pod
spec:
nodeSelector:
karpenter.sh/capacity-type: on-demand
containers:
- name: spark-kubernetes-driver
volumeMounts:
- name: spark-local-dir-1
mountPath: /data1
initContainers:
- name: volume-permission
image: public.ecr.aws/y4g4v0z7/busybox
command: ['sh', '-c', 'mkdir /data1; chown -R 999:1000 /data*'] # grant volume access to hadoop user
volumeMounts:
- name: spark-local-dir-1
mountPath: /data1
volumes:
- name: spark-local-dir-1
hostPath:
path: /local1
Spark 执行器 pod 模板如下:
# // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# // SPDX-License-Identifier: MIT-0
apiVersion: v1
kind: Pod
spec:
nodeSelector:
karpenter.sh/capacity-type: spot
containers:
- name: spark-kubernetes-executor
volumeMounts:
- name: spark-local-dir-1
mountPath: /data1
initContainers:
- name: volume-permission
image: public.ecr.aws/y4g4v0z7/busybox
command: ['sh', '-c', 'mkdir /data1; chown -R 999:1000 /data*'] # grant volume access to hadoop user
volumeMounts:
- name: spark-local-dir-1
mountPath: /data1
volumes:
- name: spark-local-dir-1
hostPath:
path: /local1
两个 pod 模板是相似的,除了 nodeSelector
设置。Spark 驱动程序在 ON_DEMAND EC2 节点上运行,而 Spark 执行器在 SPOT EC2 节点上运行。
# 此命令将显示生成的 pod。第一个 pod 将是 job-runner,第二个将是 Spark 驱动程序 pod,然后大约 50 个执行器 pod 将被调度
watch -n1 "kubectl get pod -n emr-karpenter"
Every 1.0s: kubectl get po -n emr-karpenter Fri Jul 21 23:40:11 2023
NAME READY STATUS RESTARTS AGE
000000032bqpqgfmbe4-7zb87 3/3 Running 0 5m2s
karpenter-4vcpu-7gb-exec-1 2/2 Running 0 104s
karpenter-4vcpu-7gb-exec-10 2/2 Running 0 102s
karpenter-4vcpu-7gb-exec-11 2/2 Running 0 101s
karpenter-4vcpu-7gb-exec-12 2/2 Running 0 101s
karpenter-4vcpu-7gb-exec-13 2/2 Running 0 101s
karpenter-4vcpu-7gb-exec-14 2/2 Running 0 101s
karpenter-4vcpu-7gb-exec-15 2/2 Running 0 101s
karpenter-4vcpu-7gb-exec-16 2/2 Running 0 100s
karpenter-4vcpu-7gb-exec-17 2/2 Running 0 100s
karpenter-4vcpu-7gb-exec-18 2/2 Running 0 99s
karpenter-4vcpu-7gb-exec-19 2/2 Running 0 99s
karpenter-4vcpu-7gb-exec-2 2/2 Running 0 104s