在 Amazon EKS 私有集群上使用 Amazon Batch 的入门 - Amazon Batch
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

在 Amazon EKS 私有集群上使用 Amazon Batch 的入门

Amazon Batch 是一项托管服务,可编排 Amazon Elastic Kubernetes Service(Amazon EKS)集群中的批处理工作负载。该服务包括队列、依赖项跟踪、托管作业重试次数和优先级、容器组(pod)管理和节点扩展。此功能可将您现有的私有 Amazon EKS 集群与 Amazon Batch 连接起来,从而大规模运行您的作业。您可以使用 eksctl(Amazon EKS 的命令行界面)、Amazon 控制台或创建包含所有其他必要资源的私有 Amazon EKS 集群的 Amazon Command Line Interface

默认情况下,Amazon EKS 全私有集群没有入站/出站互联网访问权限,并且只能从 VPC 或已连接网络内访问 API 服务器。Amazon VPC 端点用于实现对其他 Amazon 服务的私有访问。eksctl 支持使用预先存在的 Amazon VPC 和子网创建完全私有的集群。eksctl 还会在提供的 Amazon VPC 中创建 Amazon VPC 端点,并修改所提供子网的路由表。

每个子网都应有一个与之关联的显式路由表,因为 eksctl 不会修改主路由表。您的集群必须从 Amazon VPC 中的容器注册表中拉取映像。同样,您可以在 Amazon VPC 中创建 Amazon Elastic Container Registry,并将容器映像复制到其中,以供节点拉取。有关更多信息,请参阅将容器映像从一个存储库复制到另一个存储库。要开始使用 Amazon ECR 私有存储库,请参阅 Amazon ECR 私有存储库

您可以选择使用 Amazon ECR 创建缓存提取规则。为外部公有注册表创建缓存提取规则后,就可以使用 Amazon ECR 私有注册表统一资源标识符(URI)从该外部公有注册表中提取映像。然后,Amazon ECR 会创建一个存储库并缓存映像。当使用 Amazon ECR 私有注册表 URI 提取缓存映像时,Amazon ECR 会检查远程注册表以查看是否有新版本的映像,并且会最多每 24 小时更新一次您的私有注册表。

概览

本教程展示了如何使用 Amazon CloudShell、kubectleksctl 设置将 Amazon Batch 用于一个私有 Amazon EKS。

目标受众

本教程面向负责设置、测试和部署 Amazon Batch 的系统管理员和开发人员而设计。

使用的功能

本教程介绍如何使用 Amazon CLI 来执行以下操作:

  • 使用 Amazon Elastic Container Registry(Amazon ECR)存储容器映像

  • 创建和配置 Amazon EKS 计算环境

  • 创建作业队列。

  • 创建任务定义

  • 创建并提交要运行的作业

  • 提交带覆盖的作业

所需时间

完成本教程大约需要 40–50 分钟。

区域限制

使用此解决方案没有任何国家或地区限制。

资源用量费用

创建 Amazon 账户并不会收费;但是,通过实施此解决方案,您可能会产生下表中列出的部分或全部费用。

描述 费用(美元)
您需要按集群小时数付费 因实例而异,详情请参阅 Amazon EKS 定价
Amazon EC2 实例 您需要为创建的每个 Amazon EC2 实例付费。有关定价的更多信息,请参阅 Amazon EC2 定价

先决条件

本教程使用的是 Amazon CloudShell,这是一个已经事先完成身份验证的浏览器式 Shell,您可以直接从 Amazon Web Services 管理控制台中启动。这样就可以在不再能够通过公共互联网访问集群时对其进行访问。Amazon CLI、kubectl、和 eksctl 可能已经作为 Amazon CloudShell 的一部分安装。有关 Amazon CloudShell 的更多信息,请参阅《Amazon CloudShell 用户指南https://docs.amazonaws.cn/cloudshell/latest/userguide/welcome.html。一种替代 Amazon CloudShell 的方法是连接到集群的 VPC 或集群的已连接网络

要运行 kubectl 命令,您需要对 Amazon EKS 集群的私有访问权限。这意味着,传输到集群 API 服务器的所有流量都必须来自您的集群的 VPC 或连接的网络中。

  • Amazon CLI – 与 Amazon 服务一起使用的命令行工具,包括 Amazon EKS。本指南要求您使用 2.8.6 版或更高版本,或者 1.26.0 版或更高版本。有关更多信息,请参阅《Amazon Command Line Interface 用户指南》中的安装、更新和卸载 Amazon CLI。在安装 Amazon CLI 后,建议您还要对其进行配置。有关更多信息,请参阅《Amazon Command Line Interface 用户指南》中的使用 aws configure 进行快速配置

  • kubectl – 用于与 Kubernetes 集群一起使用的命令行工具。本指南要求您使用 1.23 版或更高版本。有关更多信息,请参阅《Amazon EKS 用户指南》中的安装或更新 kubectl

  • eksctl – 用于处理 Amazon EKS 集群的命令行工具,该工具可自动执行许多单独任务。本指南要求您使用 0.115.0 版或更高版本。有关更多信息,请参阅《Amazon EKS 用户指南》中的安装或更新 eksctl

  • 权限:调用 CreateComputeEnvironment API 操作来创建要使用 Amazon EKS 资源的计算环境时,用户需要具有 eks:DescribeClustereks:ListClusters API 操作的权限。您可以按照《IAM 用户指南》中添加和删除 IAM 身份权限的说明,将 AWSBatchFullAccess 托管式策略附加到您的用户账户

  • 实例角色:您需要为您的 Amazon EKS 节点创建一个具有 AmazonEKSWorkerNodePolicyAmazonEC2ContainerRegistryPullOnly 策略的 InstanceRole。有关如何创建 InstanceRole 的说明,请参阅创建 Amazon EKS 节点 IAM 角色。您将需要 InstanceRole 的 ARN。

  • Amazon Web Services 账户 ID:您需要知道您的 Amazon Web Services 账户 ID。按照查看您的 Amazon Web Services 账户 ID 中的说明进行操作。

  • (可选)CloudWatch :要检查(可选)提交带覆盖的作业的详细信息,必须配置日志记录。有关更多信息,请参阅 使用 CloudWatch Logs 监控 Amazon EKS 作业的 Amazon Batch

第 1 步:为 Amazon Batch 创建 EKS 集群

重要

本教程包含的步骤均使用默认设置,以助您尽可能简单快速地入门。在出于生产用途而开始创建之前,我们建议您熟悉所有设置,并使用符合您要求的设置进行部署。

我们建议您使用 eksctl 和以下配置文件来创建集群。要手动设置集群,请按照《Amazon EKS 用户指南》中部署具有有限互联网访问权限的私有集群部分的说明进操作

  1. 打开 Amazon CloudShell 控制台并将区域设置为 us-east-1。在本教程的其余部分中,请确保您使用的是 us-east-1

  2. 使用示例 eksctl 配置文件,在 us-east-1 区域中创建一个私有 EKS 集群。将该 yaml 文件保存到您的 Amazon CloudShell 环境中并将其命名为 clusterConfig.yaml。您可以将 my-test-cluster 更改为要使用的集群名称。

    kind: ClusterConfig apiVersion: eksctl.io/v1alpha5 metadata: name: my-test-cluster region: us-east-1 availabilityZones: - us-east-1a - us-east-1b - us-east-1c managedNodeGroups: - name: ng-1 privateNetworking: true privateCluster: enabled: true skipEndpointCreation: false
  3. 使用以下命令创建资源:eksctl create cluster -f clusterConfig.yaml。集群创建可能需要 10–15 分钟时间。

  4. 集群创建完成后,您必须将您的 Amazon CloudShell IP 地址添加到允许列表中。要查找您的 Amazon CloudShell IP 地址,请运行以下命令:

    curl http://checkip.amazonaws.com

    获得公有 IP 地址后,您必须创建一条允许列表规则:

    aws eks update-cluster-config \ --name my-test-cluster \ --region us-east-1 \ --resources-vpc-config endpointPublicAccess=true,endpointPrivateAccess=true,publicAccessCidrs=["<Public IP>/32"]

    然后将更新应用到该 kubectl 配置文件:

    aws eks update-kubeconfig --name my-test-cluster --region us-east-1
  5. 要测试您是否有权访问节点,请运行以下命令:

    kubectl get nodes

    命令的输出为:

    NAME STATUS ROLES AGE VERSION ip-192-168-107-235.ec2.internal Ready none 1h v1.32.3-eks-473151a ip-192-168-165-40.ec2.internal Ready none 1h v1.32.3-eks-473151a ip-192-168-98-54.ec2.internal Ready none 1h v1.32.1-eks-5d632ec

第 2 步:为 Amazon Batch 准备好 EKS 集群

必须完成所有步骤,并且必须在 Amazon CloudShell 中完成。

  1. 为 Amazon 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
  2. 通过基于角色的访问控制(RBAC)启用访问权限

    kubectl 为集群创建 Kubernetes 角色以允许 Amazon Batch 监视节点和容器组(pod),并用于绑定该角色。您必须为每个 Amazon EKS 集群执行一次此操作。

    $ 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: ["events"] verbs: ["list"] - 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

    为 Amazon 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 权限映射到 Amazon Batch 服务相关角色。

    $ eksctl create iamidentitymapping \ --cluster my-test-cluster \ --arn "arn:aws:iam::<your-account-ID>:role/AWSServiceRoleForBatch" \ --username aws-batch

    输出:

    2022-10-25 20:19:57 [ℹ] adding identity "arn:aws:iam::<your-account-ID>:role/AWSServiceRoleForBatch" to auth ConfigMap
    注意

    已从服务相关角色的 ARN 中删除路径aws-service-role/batch.amazonaws.com/。这是因为 aws-auth 配置映射存在问题。有关更多信息,请参阅 aws-authconfigmap 中带路径的角色在其 ARN 中包含路径时不起作用

第 3 步:创建 Amazon EKS 计算环境

Amazon Batch 计算环境定义计算资源参数以满足您的批处理工作负载需求。在托管计算环境中,Amazon Batch 用以管理您的 Amazon EKS 集群中计算资源(Kubernetes 节点)的容量和实例类型。这是基于您在创建计算环境时定义的计算资源规范。您可以使用 EC2 按需型实例或 EC2 竞价型实例。

由于 AWSServiceRoleForBatch 服务相关角色可以访问您的 Amazon EKS 集群,您可以创建 Amazon Batch 资源。首先,创建一个指向 Amazon EKS 集群的计算环境。

  • 对于 subnets,请运行 eksctl get cluster my-test-cluster 来获取集群使用的子网。

  • 对于 securityGroupIds 参数,您可以使用与 Amazon EKS 集群相同的安全组。此命令检索集群的安全组 ID。

    $ aws eks describe-cluster \ --name my-test-cluster \ --query cluster.resourcesVpcConfig.clusterSecurityGroupId
  • 使用您在先决条件步骤中创建的 instanceRole ARN。

$ cat <<EOF > ./batch-eks-compute-environment.json { "computeEnvironmentName": "My-Eks-CE1", "type": "MANAGED", "state": "ENABLED", "eksConfiguration": { "eksClusterArn": "arn:aws:eks:us-east-1:<your-account-ID>:cluster/my-test-cluster", "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
备注

第 4 步:创建作业队列并连接计算环境

重要

在继续操作之前,请务必确认计算环境是否正常。DescribeComputeEnvironments API 操作可以用来做到这一点。

$ aws batch describe-compute-environments --compute-environments My-Eks-CE1

确认 status 参数不是 INVALID。如果是,请查看 statusReason 参数查找原因。有关更多信息,请参阅 故障排除 Amazon Batch

提交到这个新作业队列的作业在加入与您的计算环境关联的 Amazon EKS 集群的 Amazon 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

第 5 步:创建具有缓存提取规则的 Amazon ECR

由于集群没有公共互联网问访权限,因此您必须为容器映像创建一个 Amazon ECR。以下说明会创建一个具有缓存提取规则的 Amazon ECR 来存储映像。

  1. 以下命令会创建缓存提取规则。您可以使用其他前缀来替换 tutorial-prefix

    aws ecr create-pull-through-cache-rule \ --ecr-repository-prefix "my-prefix" \ --upstream-registry-url "public.ecr.aws" \ --region us-east-1
  2. 完成公有 ECR 的身份验证。

    aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <your-account-ID>.dkr.ecr.us-east-1.amazonaws.com

    现在就可以提取映像。

    docker pull <your-account-ID>.dkr.ecr.us-east-1.amazonaws.com/my-prefix/amazonlinux/amazonlinux:2
  3. 您可以通过运行以下命令验证存储库和映像:

    aws ecr describe-repositories
    aws ecr describe-images --repository-name my-prefix/amazonlinux/amazonlinux
  4. 用于提取容器的映像字符串格式如下:

    <your-account-ID>.dkr.ecr.us-east-1.amazonaws.com/my-prefix/amazonlinux/amazonlinux:2

第 6 步:注册作业定义

以下作业定义会指示该容器组睡眠 60 秒。

在作业定义的映像字段中,与其提供指向公共 ECR 存储库中映像的链接,不如提供指向我们的私有 ECR 存储库中存储的映像的链接。请参阅以下示例作业定义:

$ cat <<EOF > ./batch-eks-job-definition.json { "jobDefinitionName": "MyJobOnEks_Sleep", "type": "container", "eksProperties": { "podProperties": { "hostNetwork": true, "containers": [ { "image": "<your-account-ID>.dkr.ecr.us-east-1.amazonaws.com/my-prefix/amazonlinux/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

备注

第 7 步:提交要运行的作业

在 Amazon CloudShell 中运行以下 Amazon CLI 命令,以提交一个新作业并返回唯一的 JobID。

$ aws batch submit-job --job-queue My-Eks-JQ1 \ --job-definition MyJobOnEks_Sleep - -job-name My-Eks-Job1
备注
  • 有关在 Amazon EKS 资源上运行作业的更多信息,请参阅 Amazon EKS 作业

第 8 步:查看作业输出

检查作业状态:

$ aws batch describe-jobs --job <JobID-from-submit-response>

startedAtstoppedAt 应会间隔一分钟。

第 9 步:(可选)提交带覆盖的作业

此作业会覆盖传递给容器的命令。

$ 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
备注

第 10 步:清理教程资源

启用 Amazon EC2 实例后,您需要为该实例付费。您可以删除实例以停止产生费用。

要删除您创建的资源,请执行以下操作:

  1. 打开Amazon Batch控制台,地址:https://console.aws.amazon.com/batch/

  2. 在导航窗格中,选择作业队列

  3. 作业队列表中,选择您为本教程创建的作业队列。

  4. 对于操作,请选择禁用。当作业队列的状态变为“已禁用”后,您可以选择删除

  5. 删除该作业队列后,在导航窗格中选择计算环境

  6. 选择您为本教程创建的计算环境,然后在操作中选择禁用。计算环境的禁用可能需要 1-2 分钟才能完成。

  7. 计算环境的状态变为“已禁用”后,选择删除。计算环境的删除可能需要 1-2 分钟才能完成。

其他资源

完成本教程后,您可以探索以下主题:

故障排除

如果由 Amazon Batch 启动的节点无权访问存储您的映像的 Amazon ECR 存储库(或任何其他存储库),则您的作业可能会保持“启动”状态。这是因为容器组(pod)将无法下载映像并运行您的 Amazon Batch 作业。如果您点击 Amazon 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

有关其他常见的故障排除方案,请参阅排查 Amazon Batch 问题。有关基于容器组状态的问题排查,请参阅我如何排查 Amazon EKS 中的容器组(pod)状态问题?