本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
教程:开始使用 Amazon EKS 私有集群上的 AWS Batch
AWS Batch 是一项托管服务,可编排 Amazon Elastic Kubernetes Service(Amazon EKS)集群中的批处理工作负载。该服务包括队列、依赖项跟踪、托管作业重试次数和优先级、容器组(pod)管理和节点扩展。此功能可将您现有的私有 Amazon EKS 集群与 AWS Batch 连接起来,从而大规模运行您的作业。您可以使用 eksctl
Amazon EKS 仅限私有集群没有入站/出站互联网访问权限,且只有私有子网。Amazon VPC 端点用于允许私有访问其他 AWS 服务。eksctl
支持使用预先存在的 Amazon VPC 和子网创建完全私有的集群。
还会在提供的 Amazon VPC 中创建 Amazon VPC 端点,并修改所提供子网的路由表。eksctl
每个子网都应有一个与之关联的显式路由表,因为
不会修改主路由表。您的集群eksctl
您可以选择使用 Amazon ECR 创建缓存提取规则。为外部公有注册表创建缓存提取规则后,您就可以使用 Amazon ECR 私有注册表统一资源标识符(URI)从该外部公有注册表中提取映像。然后,Amazon ECR 会创建一个存储库并缓存映像。当使用 Amazon ECR 私有注册表 URI 提取缓存映像时,Amazon ECR 会检查远程注册表以查看是否有新版本的映像,并且会最多每 24 小时更新一次您的私有注册表。
先决条件
在开始使用本教程之前,您必须安装并配置创建和管理 AWS Batch 和 Amazon EKS 资源所需的以下工具和资源。您还需要创建所有必要的资源,包括 VPC、子网、路由表、VPC 端点和 Amazon EKS 集群。您需要使用 AWS CLI。
-
AWS CLI – 与 AWS 服务一起使用的命令行工具,包括 Amazon EKS。本指南要求您使用 2.8.6 版或更高版本,或者 1.26.0 版或更高版本。有关更多信息,请参阅《AWS Command Line Interface 用户指南》中的安装、更新和卸载 AWS CLI。
在安装 AWS CLI 后,建议您对其进行配置。有关更多信息,请参阅《AWS Command Line Interface 用户指南》中的使用
aws configure
进行快速配置。 -
kubectl
– 与 Kubernetes 集群一起使用的命令行工具。本指南要求您使用1.23
版或更高版本。有关更多信息,请参阅《Amazon EKS 用户指南》中的安装或更新kubectl
。 -
– 与 Amazon EKS 集群一起使用的命令行工具,该工具可自动执行许多单独任务。本指南要求您使用eksctl
0.115.0
版或更高版本。有关更多信息,请参阅《Amazon EKS 用户指南》中的安装或更新
。eksctl
-
所需的 AWS Identity and Access Management(IAM)权限 – 您正在使用的 IAM 安全主体必须具有使用 Amazon EKS IAM 角色和服务相关角色 AWS CloudFormation 的权限,以及 VPC 和相关资源。有关更多信息,请参阅《IAM 用户指南》中的用于 Amazon Elastic Kubernetes Service 的操作、资源和条件密钥和使用服务相关角色。您必须以同一用户身份完成本指南中的所有步骤。
-
创建 Amazon EKS 集群 — 有关更多信息,请参阅《Amazon EKS 用户指南》中的 Amazon EKS –
eksctl
入门。注意
AWS Batch 不为 CoreDNS 或其他部署容器组(pod)提供托管节点编排。如果您需要 CoreDNS,请参阅 Amazon EKS 用户指南中的添加 CoreDNS Amazon EKS 插件。或者,使用
eksctl create cluster create
创建集群,默认情况下它包含 CoreDNS。 -
权限 – 调用 CreateComputeEnvironment API 操作来创建使用 Amazon EKS 资源的计算环境的用户需要
eks:DescribeCluster
API 操作权限。使用 AWS Management Console 来创建使用 Amazon EKS 资源的计算资源需要eks:DescribeCluster
和eks:ListClusters
的权限。 -
使用示例
配置文件,在 us-east-1 区域中创建私有 EKS 集群。eksctl
kind: ClusterConfig apiVersion: eksctl.io/v1alpha5 availabilityZones: - us-east-1a - us-east-1b - us-east-1d managedNodeGroups: privateNetworking: true privateCluster: enabled: true skipEndpointCreation: false
使用以下命令创建您的资源:
eksctl create cluster -f clusterConfig.yaml
-
批量管理的节点都必须部署到具有您需要的 VPC 接口端点的子网中。有关更多信息,请参阅私有集群要求。
为 AWS Batch 准备您的 EKS 集群
必须完成所有步骤。
-
为 AWS Batch 作业创建专用的命名空间
用
kubectl
以创建新的命名空间。$
namespace=
my-aws-batch-namespace
$
cat - <<EOF | kubectl create -f - { "apiVersion": "v1", "kind": "Namespace", "metadata": { "name": "${namespace}", "labels": { "name": "${namespace}" } } } EOF
输出:
namespace/my-aws-batch-namespace created
-
通过基于角色的访问控制(RBAC)启用访问权限
用
kubectl
为集群创建 Kubernetes 角色以允许 AWS Batch 监视节点和容器组(pod),并用于绑定该角色。您必须为每个 Amazon EKS 集群执行一次此操作。注意
有关使用 RBAC 授权的更多信息,请参阅 Kubernetes 文档中的使用 RBAC 授权
。 $
cat - <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name:
aws-batch-cluster-role
rules: - apiGroups: [""] resources: ["namespaces"] verbs: ["get"] - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["daemonsets", "deployments", "statefulsets", "replicasets"] verbs: ["get", "list", "watch"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterroles", "clusterrolebindings"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name:aws-batch-cluster-role-binding
subjects: - kind: User name:aws-batch
apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name:aws-batch-cluster-role
apiGroup: rbac.authorization.k8s.io EOF输出:
clusterrole.rbac.authorization.k8s.io/aws-batch-cluster-role created clusterrolebinding.rbac.authorization.k8s.io/aws-batch-cluster-role-binding created
为 AWS Batch 创建名称空间范围的 Kubernetes 角色,用于管理和绑定生命周期容器组(pod)。必须为每个唯一的命名空间执行一次此操作。
$
namespace=
my-aws-batch-namespace
$
cat - <<EOF | kubectl apply -f - --namespace "${namespace}" apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name:
aws-batch-compute-environment-role
namespace: ${namespace} rules: - apiGroups: [""] resources: ["pods"] verbs: ["create", "get", "list", "watch", "delete", "patch"] - apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get", "list"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["roles", "rolebindings"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name:aws-batch-compute-environment-role-binding
namespace: ${namespace} subjects: - kind: User name:aws-batch
apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name:aws-batch-compute-environment-role
apiGroup: rbac.authorization.k8s.io EOF输出:
role.rbac.authorization.k8s.io/aws-batch-compute-environment-role created rolebinding.rbac.authorization.k8s.io/aws-batch-compute-environment-role-binding created
更新 Kubernetes
aws-auth
配置映射以将前面的 RBAC 权限映射到 AWS Batch 服务相关角色。$
eksctl create iamidentitymapping \ --cluster
my-cluster-name
\ --arn "arn:aws:iam::<your-account>
:role/AWSServiceRoleForBatch" \ --usernameaws-batch
输出:
2022-10-25 20:19:57 [ℹ] adding identity "arn:aws:iam::
<your-account>
:role/AWSServiceRoleForBatch" to auth ConfigMap注意
已从服务相关角色的 ARN 中删除路径
aws-service-role/batch.amazonaws.com/
。这是因为aws-auth
配置映射存在问题。有关更多信息,请参阅 aws-authconfigmap 中带路径的角色在其 ARN 中包含路径时不起作用。
创建 Amazon EKS 计算环境
AWS Batch 计算环境定义计算资源参数以满足您的批处理工作负载需求。在托管计算环境中,AWS Batch 用以管理您的 Amazon EKS 集群中计算资源(Kubernetes 节点)的容量和实例类型。这是基于您在创建计算环境时定义的计算资源规范。您可以使用 EC2 按需型实例或 EC2 竞价型实例。
由于 AWSServiceRoleForBatch 服务相关角色可以访问您的 Amazon EKS 集群,您可以创建 AWS Batch 资源。首先,创建一个指向 Amazon EKS 集群的计算环境。
$
cat <<EOF > ./batch-eks-compute-environment.json { "computeEnvironmentName": "
My-Eks-CE1
", "type": "MANAGED", "state": "ENABLED", "eksConfiguration": { "eksClusterArn": "arn:aws:eks:<region>
:123456789012
:cluster/<cluster-name>
", "kubernetesNamespace": "my-aws-batch-namespace
" }, "computeResources": { "type": "EC2", "allocationStrategy": "BEST_FIT_PROGRESSIVE", "minvCpus": 0, "maxvCpus": 128, "instanceTypes": [ "m5" ], "subnets": [ "<eks-cluster-subnets-with-access-to-the-image-for-image-pull>
" ], "securityGroupIds": [ "<eks-cluster-sg>
" ], "instanceRole": "<eks-instance-profile>
" } } EOF$
aws batch create-compute-environment --cli-input-json file://./batch-eks-compute-environment.json
注意
-
不应指定
serviceRole
参数,然后将使用 AWS Batch 服务相关角色。Amazon EKS 的 AWS Batch 仅支持 AWS Batch 服务相关角色。 -
Amazon EKS 计算环境仅支持
BEST_FIT_PROGRESSIVE
、SPOT_CAPACITY_OPTIMIZED
和SPOT_PRICE_CAPACITY_OPTIMIZED
分配策略。注意
建议在大多数情况下使用
SPOT_PRICE_CAPACITY_OPTIMIZED
而不是SPOT_CAPACITY_OPTIMIZED
n。 -
有关
instanceRole
,请参阅 Amazon EKS 用户指南中的创建 Amazon EKS 节点 IAM 角色和启用 IAM 主体访问您的集群。如果您使用的是容器组(pod)联网,请参阅 Amazon EKS 用户指南中的为 Kubernetes 配置 Amazon VPC CNI 插件以使用服务账户的 IAM 角色。 -
获取
subnets
参数的工作子网的一种方法是使用eksctl
创建 Amazon EKS 集群时创建的 Amazon EKS 托管节点组公共子网。否则,请使用具有支持拉取映像的网络路径的子网。 -
securityGroupIds
参数可以使用与 Amazon EKS 集群相同的安全组。此命令检索集群的安全组 ID。$
eks describe-cluster \ --name
<cluster-name>
\ --query cluster.resourcesVpcConfig.clusterSecurityGroupId -
对 Amazon EKS 计算环境的维护是一项共同责任。有关更多信息,请参阅 Amazon EKS 中的安全性。
重要
在继续操作之前,请务必确认计算环境是否正常。DescribeComputeEnvironments API 操作可以用来做到这一点。
$
aws batch describe-compute-environments --compute-environments
My-Eks-CE1
确认 status
参数不是 INVALID
。如果是,请查看 statusReason
参数查找原因。有关更多信息,请参阅 故障排除 AWS Batch。
创建作业队列并连接计算环境
$
aws batch describe-compute-environments --compute-environments
My-Eks-CE1
提交到这个新作业队列的作业在加入与您的计算环境关联的 Amazon EKS 集群的 AWS Batch 托管节点上以容器组(pod)的形式运行。
$
cat <<EOF > ./batch-eks-job-queue.json { "jobQueueName": "
My-Eks-JQ1
", "priority": 10, "computeEnvironmentOrder": [ { "order": 1, "computeEnvironment": "My-Eks-CE1
" } ] } EOF$
aws batch create-job-queue --cli-input-json file://./batch-eks-job-queue.json
创建任务定义
在作业定义的映像字段中,与其提供指向公共 ECR 存储库中映像的链接,不如提供指向我们的私有 ECR 存储库中存储的映像的链接。请参阅以下示例作业定义:
$
cat <<EOF > ./batch-eks-job-definition.json { "jobDefinitionName": "
MyJobOnEks_Sleep
", "type": "container", "eksProperties": { "podProperties": { "hostNetwork": true, "containers": [ { "image": "account-id
.dkr.ecr.region
.amazonaws.com/amazonlinux:2", "command": [ "sleep", "60" ], "resources": { "limits": { "cpu": "1", "memory": "1024Mi" } } } ], "metadata": { "labels": { "environment": "test
" } } } } } EOF$
aws batch register-job-definition --cli-input-json file://./batch-eks-job-definition.json
要运行 kubectl 命令,您需要对 Amazon EKS 集群的私有访问权限。这意味着,传输到集群 API 服务器的所有流量都必须来自您的集群的 VPC 或连接的网络中。
提交作业
$
aws batch submit-job - -job-queue
My-Eks-JQ1
\ - -job-definitionMyJobOnEks_Sleep
- -job-nameMy-Eks-Job1
$
aws batch describe-jobs - -job
<jobId-from-submit-response>
注意
-
仅支持单个容器作业。
-
请确保您熟悉
cpu
和memory
参数的所有相关注意事项。有关更多信息,请参阅 Amazon EKS 上 AWS Batch 的内存和 vCPU 注意事项。 -
有关在 Amazon EKS 资源上运行作业的更多信息,请参阅 亚马逊EKS职位。
(可选)提交带有优先级的作业
此作业会覆盖传递给容器的命令。
$
cat <<EOF > ./submit-job-override.json { "jobName": "
EksWithOverrides
", "jobQueue": "My-Eks-JQ1
", "jobDefinition": "MyJobOnEks_Sleep
", "eksPropertiesOverride": { "podProperties": { "containers": [ { "command": [ "/bin/sh" ], "args": [ "-c", "echo hello world" ] } ] } } } EOF$
aws batch submit-job - -cli-input-json file://./submit-job-override.json
注意
-
AWS Batch 在作业完成后积极清理容器组(pod)以将负载减少到 Kubernetes。要检查作业的详细信息,必须配置日志记录。有关更多信息,请参阅 使用 CloudWatch Logs 监控 Amazon EKS 作业的 AWS Batch。
-
要提高对操作细节的可见性,请启用 Amazon EKS 控制面板日志记录。有关更多信息,请参阅《Amazon EKS 用户指南》中的 Amazon EKS 控制面板日志。
-
Daemonsets 和 kubelets 开销会影响可用的 vCPU 和内存资源,特别是扩展和作业布局。有关更多信息,请参阅 Amazon EKS 上 AWS Batch 的内存和 vCPU 注意事项。
故障排除
如果由 AWS Batch 启动的节点无权访问存储您的映像的 Amazon ECR 存储库(或任何其他存储库),则您的作业可能会保持“启动”状态。这是因为容器组(pod)将无法下载映像并运行您的 AWS Batch 作业。如果您点击 AWS Batch 启动的容器组(pod)名称,您应该能够看到错误消息并确认问题。错误消息应该类似于以下内容:
Failed to pull image "public.ecr.aws/amazonlinux/amazonlinux:2": rpc error: code = Unknown desc = failed to pull and unpack image "public.ecr.aws/amazonlinux/amazonlinux:2": failed to resolve reference "public.ecr.aws/amazonlinux/amazonlinux:2": failed to do request: Head "https://public.ecr.aws/v2/amazonlinux/amazonlinux/manifests/2": dial tcp: i/o timeout
有关其他常见的故障排除方案,请参阅排查 AWS Batch 问题。有关基于容器组(pod)状态的故障排除,请参阅如何对 Amazon EKS 中的容器组(pod)状态进行故障排除?