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

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Step Functions 调用 Amazon EKS

Step Functions 可以直接从 Amazon States Language (ASL) 控制某些 Amazon 服务。有关使用 Amazon Step Functions 及其集成的更多信息,请参阅以下内容:

优化的 Amazon EKS 集成与 Amazon EKS Amazon 开发工具包集成有何不同

有关在将 Step Functions 与其他 Amazon 服务一起使用时如何配置 IAM 权限的信息,请参阅集成服务的 IAM 策略

Step Functions 提供了两种服务集成 API,用于与 Amazon Elastic Kubernetes Service 集成。其中一种允许您使用 Amazon EKS API 来创建和管理 Amazon EKS 集群。另一种允许您使用 Kubernetes API 与集群进行交互,并作为应用程序工作流的一部分运行作业。您可以使用 Kubernetes API 与使用 Step Functions 创建的 Amazon EKS 集群、使用 eksctl 工具或 Amazon EKS 控制台创建的 Amazon EKS 集群或类似方法进行集成。有关更多信息,请参阅《Amazon EKS 用户指南》中的创建 Amazon EKS 集群

注意

Step Functions EKS 集成仅支持具有公共端点访问权限的 Kubernetes API。默认情况下,EKS 集群 API 服务器端点具有公共访问权限。有关更多信息,请参阅《Amazon EKS 用户指南》中的 Amazon EKS 集群端点访问控制

如果执行停止,Step Functions 不会自动终止 Amazon EKS 集群。如果您的状态机在 Amazon EKS 集群终止之前停止,则您的集群可能会无限期地继续运行,并且可能会产生额外费用。为避免这种情况,请确保您创建的任何 Amazon EKS 集群都已正确终止。有关更多信息,请参阅:

注意

在 Step Functions 中,任务的最大输入或结果数据大小有一个配额。在向另一个服务发送数据或从另一个服务接收数据时,数据大小不得超过 256 KB(UTF-8 编码字符串)。请参阅与状态机执行相关的配额

Kubernetes API 集成

Step Functions 支持以下 Kubernetes API:

RunJob

eks:runJob 服务集成允许您在 Amazon EKS 集群上运行作业。您可以是使用 eks:runJob.sync 变体等待任务完成,也可以选择检索日志。

您的 Kubernetes API 服务器必须向状态机使用的 IAM 角色授予权限。有关更多信息,请参阅权限

对于运行任务 (.sync) 模式,作业的状态由轮询确定。Step Functions 最初的轮询速度约为每分钟 1 次。这个速度最终会减慢到大约每 5 分钟进行一次。如果您需要更频繁地进行轮询,或者需要对轮询策略进行更多控制,则可以使用 eks:call 集成来查询作业的状态。

eks:runJob 集成特定于 batch/v1 Kubernetes 作业。有关更多信息,请参阅 Kubernetes 文档中的作业。如果您想管理其他 Kubernetes 资源,包括自定义资源,请使用 eks:call 服务集成。您可以使用 Step Functions 来构建轮询循环,如任务状态投票 (Lambda,) Amazon Batch示例项目所示。

支持的参数包括:

  • ClusterName:要调用的 Amazon EKS 集群的名称。

    • Type: String

    • 必需:是

  • CertificateAuthority:检索与集群通信所需的 Base64 编码证书数据。您可以从 Amazon EKS 控制台或使用 Amazon EKS DescribeCluster API 获取此值。

    • Type: String

    • 必需:是

  • Endpoint:Kubernetes API 服务器的端点 URL。您可以从 Amazon EKS 控制台或使用 Amazon EKS DescribeCluster API 获取此值。

    • Type: String

    • 必需:是

  • Namespace:运行作业的命名空间。如果未提供,则使用 default 命名空间。

    • Type: String

    • 必需:否

  • Job: Kubernetes 作业的定义。请参阅 Kubernetes 文档中的作业

    • TypeJSONString

    • 必需:是

  • LogOptions:一组用于控制日志可选检索的选项。仅当使用运行作业 (.sync) 服务集成模式来等待作业完成时才适用。

    • Type: JSON

    • 必需:否

    • 日志包含在密钥 logs 下的响应中。任务中可能有多个容器组,每个容器组都有多个容器。

      { ... "logs": { "pods": { "pod1": { "containers": { "container1": { "log": <log> }, ... } }, ... } }
    • 将尽最大努力执行日志检索。如果检索日志时出错,则将使用 errorcause 字段代替 log 字段。

  • LogOptions.RetrieveLogs:在任务完成后启用日志检索。默认情况下,不会检索日志。

    • Type: Boolean

    • 必需:否

  • LogOptions.RawLogs: 如果 RawLogs 设置为 true,则日志将作为原始字符串返回,而无需尝试将其解析为 JSON。默认情况下,如果可能,日志会反序列化为 JSON。在某些情况下,此类解析可能会带来不必要的更改,例如限制包含多位数的数字精确度。

    • Type: Boolean

    • 必需:否

  • LogOptions.LogParameters:Kubernetes API 的读取日志 API 支持查询参数来控制日志检索。例如,您可以使用 tailLineslimitBytes 来限制检索到的日志的大小,并保持在 Step Functions 的数据大小配额之内。有关更多信息,请参阅 Kubernetes API 参考中的读取日志部分。

    • Type: StringList of Strings 的映射

    • 必需:否

    • 示例:

      "LogParameters": { "tailLines": [ "6" ] }

以下示例包括运行作业、等待任务完成然后检索作业日志的 Task 状态:

{ "StartAt": "Run a job on EKS", "States": { "Run a job on EKS": { "Type": "Task", "Resource": "arn:aws:states:::eks:runJob.sync", "Parameters": { "ClusterName": "MyCluster", "CertificateAuthority": "ANPAJ2UCCR6DPCEXAMPLE", "Endpoint": "https://AKIAIOSFODNN7EXAMPLE.yl4.us-east-1.eks.amazonaws.com", "LogOptions": { "RetrieveLogs": true }, "Job": { "apiVersion": "batch/v1", "kind": "Job", "metadata": { "name": "example-job" }, "spec": { "backoffLimit": 0, "template": { "metadata": { "name": "example-job" }, "spec": { "containers": [ { "name": "pi-2000", "image": "perl", "command": [ "perl" ], "args": [ "-Mbignum=bpi", "-wle", "print bpi(2000)" ] } ], "restartPolicy": "Never" } } } } }, "End": true } } }

Call

eks:call 服务集成允许您使用 Kubernetes API 通过 Kubernetes API 端点读取和写入 Kubernetes 资源对象。

您的 Kubernetes API 服务器必须向状态机使用的 IAM 角色授予权限。有关更多信息,请参阅权限

有关使用可用操作的更多信息,请参阅 Kubernetes API 参考

Call 支持的参数包括:

  • ClusterName:要调用的 Amazon EKS 集群的名称。

    • Type:字符串

    • 必需:是

  • CertificateAuthority:检索与集群通信所需的 Base64 编码证书数据。您可以从 Amazon EKS 控制台或使用 Amazon EKS DescribeCluster API 获取此值。

    • Type: String

    • 必需:是

  • Endpoint:Kubernetes API 服务器的端点 URL。您可以在 Amazon EKS 控制台上或使用 Amazon EKS 的 DescribeCluster API 找到这个值。

    • Type: String

    • 必需:是

  • Method:请求的 HTTP 方法。以下值之一:GETPOSTPUTDELETEHEADPATCH

    • Type: String

    • 必需:是

  • Path: Kubernetes REST API 操作的 HTTP 路径。

    • Type: String

    • 必需:是

  • QueryParameters: Kubernetes REST API 操作的 HTTP 查询参数。

    • Type: StringList of Strings 的映射

    • 必需:否

    • 示例:

      "QueryParameters": { "labelSelector": [ "job-name=example-job" ] }
  • RequestBody: Kubernetes REST API 操作的 HTTP 消息正文。

    • TypeJSONString

    • 必需:否

下面包含一个 Task 状态,它使用 eks:call 列出属于作业 example-job 的容器组。

{ "StartAt": "Call EKS", "States": { "Call EKS": { "Type": "Task", "Resource": "arn:aws:states:::eks:call", "Parameters": { "ClusterName": "MyCluster", "CertificateAuthority": "ANPAJ2UCCR6DPCEXAMPLE", "Endpoint": "https://444455556666.yl4.us-east-1.eks.amazonaws.com", "Method": "GET", "Path": "/api/v1/namespaces/default/pods", "QueryParameters": { "labelSelector": [ "job-name=example-job" ] } }, "End": true } } }

下面包含一个 Task 状态,它使用 eks:call 删除作业 example-job,并设置 propagationPolicy 以确保作业的容器组也被删除。

{ "StartAt": "Call EKS", "States": { "Call EKS": { "Type": "Task", "Resource": "arn:aws:states:::eks:call", "Parameters": { "ClusterName": "MyCluster", "CertificateAuthority": "ANPAJ2UCCR6DPCEXAMPLE", "Endpoint": "https://444455556666.yl4.us-east-1.eks.amazonaws.com", "Method": "DELETE", "Path": "/apis/batch/v1/namespaces/default/jobs/example-job", "QueryParameters": { "propagationPolicy": [ "Foreground" ] } }, "End": true } } }

支持的 Amazon EKS API

支持的 Amazon EKS API 和语法包括:

  • CreateCluster

    • 请求语法

    • 响应语法

      使用 eks:createCluster 服务集成创建 Amazon EKS 集群时,IAM 角色会作为管理员添加到 Kubernetes RBAC 授权表中,并拥有 system:masters 权限。最初,仅该 IAM 实体可以调用 Kubernetes API 服务器。有关更多信息,请参阅:

      Amazon EKS 使用服务相关角色,其中包含 Amazon EKS 代表您调用其他服务所需的权限。如果您的账户中还不存在这些服务相关角色,您必须将 iam:CreateServiceLinkedRole 权限添加到 Step Functions 使用的 IAM 角色中。有关更多信息,请参阅《Amazon EKS 用户指南》中的使用服务相关角色

      Step Functions 使用的 IAM 角色必须具有 iam:PassRole 旋前,才能将集群 IAM 角色传递给 Amazon EKS。有关更多信息,请参阅《Amazon EKS 用户指南》中的 Amazon EKS 集群 IAM 角色

  • DeleteCluster

  • CreateFargateProfile

    • 请求语法

    • 响应语法

      Amazon EKS 使用服务相关角色,其中包含 Amazon EKS 代表您调用其他服务所需的权限。如果您的账户中还不存在这些服务相关角色,您必须将 iam:CreateServiceLinkedRole 权限添加到 Step Functions 使用的 IAM 角色中。有关更多信息,请参阅《Amazon EKS 用户指南》中的使用服务相关角色

      Fargate 上的 Amazon EKS 可能并未在所有区域提供。有关区域可用性的信息,请参阅《Amazon EKS 用户指南》中的 Fargate 部分。

      Step Functions 使用的 IAM 角色必须具有 iam:PassRole 旋前,才能将容器组执行 IAM 角色传递给 Amazon EKS。有关更多信息,请参阅《Amazon EKS 用户指南》中的容器组执行角色

  • DeleteFargateProfile

  • CreateNodegroup

    • 请求语法

    • 响应语法

      Amazon EKS 使用服务相关角色,其中包含 Amazon EKS 代表您调用其他服务所需的权限。如果您的账户中还不存在这些服务相关角色,您必须将 iam:CreateServiceLinkedRole 权限添加到 Step Functions 使用的 IAM 角色中。有关更多信息,请参阅《Amazon EKS 用户指南》中的使用服务相关角色

      Step Functions 使用的 IAM 角色必须具有 iam:PassRole 旋前,才能将节点 IAM 角色传递给 Amazon EKS。有关更多信息,请参阅《Amazon EKS 用户指南》中的使用服务相关角色

  • DeleteNodegroup

以下内容包含一个创建 Amazon EKS 集群的 Task 状态。

{ "StartAt": "CreateCluster.sync", "States": { "CreateCluster.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:createCluster.sync", "Parameters": { "Name": "MyCluster", "ResourcesVpcConfig": { "SubnetIds": [ "subnet-053e7c47012341234", "subnet-027cfea4b12341234" ] }, "RoleArn": "arn:aws:iam::123456789012:role/MyEKSClusterRole" }, "End": true } } }

以下内容包括一个删除 Amazon EKS 集群的 Task 状态。

{ "StartAt": "DeleteCluster.sync", "States": { "DeleteCluster.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:deleteCluster.sync", "Parameters": { "Name": "MyCluster" }, "End": true } } }

以下内容包含一个创建 Fargate 配置文件的 Task 状态。

{ "StartAt": "CreateFargateProfile.sync", "States": { "CreateFargateProfile.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:createFargateProfile.sync", "Parameters": { "ClusterName": "MyCluster", "FargateProfileName": "MyFargateProfile", "PodExecutionRoleArn": "arn:aws:iam::123456789012:role/MyFargatePodExecutionRole", "Selectors": [{ "Namespace": "my-namespace", "Labels": { "my-label": "my-value" } }] }, "End": true } } }

以下内容包含一个删除 Fargate 配置文件的 Task 状态。

{ "StartAt": "DeleteFargateProfile.sync", "States": { "DeleteFargateProfile.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:deleteFargateProfile.sync", "Parameters": { "ClusterName": "MyCluster", "FargateProfileName": "MyFargateProfile" }, "End": true } } }

以下内容包含一个创建节点组的 Task 状态。

{ "StartAt": "CreateNodegroup.sync", "States": { "CreateNodegroup.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:createNodegroup.sync", "Parameters": { "ClusterName": "MyCluster", "NodegroupName": "MyNodegroup", "NodeRole": "arn:aws:iam::123456789012:role/MyNodeInstanceRole", "Subnets": ["subnet-09fb51df01234", "subnet-027cfea4b1234"] }, "End": true } } }

以下内容包含一个删除节点组的 Task 状态。

{ "StartAt": "DeleteNodegroup.sync", "States": { "DeleteNodegroup.sync": { "Type": "Task", "Resource": "arn:aws:states:::eks:deleteNodegroup.sync", "Parameters": { "ClusterName": "MyCluster", "NodegroupName": "MyNodegroup" }, "End": true } } }

权限

使用 eks:createCluster 服务集成创建 Amazon EKS 集群时,IAM 角色会作为管理员添加到 Kubernetes RBAC 授权表中,并拥有 system:masters 权限。最初,仅该 IAM 实体可以调用 Kubernetes API 服务器。例如,您将无法使用 kubectl 与您的 Kubernetes API 服务器交互,除非您承担与 Step Functions 状态机相同的角色,或者您配置 Kubernetes 向其他 IAM 实体授予权限。有关更多信息,请参阅《Amazon EKS 用户指南》中的管理集群的用户或 IAM 角色

您可以将其他 IAM 实体(如用户或角色)添加到 kube-system 名称空间中的 aws-auth ConfigMap,从而为它们添加权限。如果您通过 Step Functions 创建集群,请使用 eks:call 服务集成。

下面包含一个 Task 状态,该状态创建了 aws-auth ConfigMap ,并向用户 arn:aws:iam::123456789012:user/my-user 和 IAM 角色 arn:aws:iam::123456789012:role/my-role 授予 system:masters 权限。

{ "StartAt": "Add authorized user", "States": { "Add authorized user": { "Type": "Task", "Resource": "arn:aws:states:::eks:call", "Parameters": { "ClusterName": "MyCluster", "CertificateAuthority": "LS0tLS1CRUd...UtLS0tLQo=", "Endpoint": "https://444455556666.yl4.us-east-1.eks.amazonaws.com", "Method": "POST", "Path": "/api/v1/namespaces/kube-system/configmaps", "RequestBody": { "apiVersion": "v1", "kind": "ConfigMap", "metadata": { "name": "aws-auth", "namespace": "kube-system" }, "data": { "mapUsers": "[{ \"userarn\": \"arn:aws:iam::123456789012:user/my-user\", \"username\": \"my-user\", \"groups\": [ \"system:masters\" ] } ]", "mapRoles": "[{ \"rolearn\": \"arn:aws:iam::123456789012:role/my-role\", \"username\": \"my-role\", \"groups\": [ \"system:masters\" ] } ]" } } }, "End": true } }
注意

您可能会看到 IAM 角色的 ARN 以包含 /service-role/ 路径的格式显示,例如 arn:aws:iam::123456789012:role/service-role/my-role。在 aws-auth 中列出角色时,不应包含此服务角色路径令牌。

首次创建集群时,aws-auth ConfigMap 并不存在,但如果创建了 Fargate 配置文件,则会自动添加。您可以检索 aws-auth 的当前值、添加其他权限和 PUT 一个新版本。通常,在 Fargate 配置文件之前创建 aws-auth 会更容易。

如果您的集群是在 Step Functions 之外创建的,则可以配置 kubectl 与 Kubernetes API 服务器通信。然后,使用 kubectl apply -f aws-auth.yaml 创建新的 aws-auth ConfigMap 或使用 kubectl edit -n kube-system configmap/aws-auth 编辑已存在的 aws-auth ConfigMap。有关更多信息,请参阅:

如果您的 IAM 角色在 Kubernetes 中没有足够的权限,eks:calleks:runJob 服务集成将失败,并出现以下错误:

Error: EKS.401 Cause: { "ResponseBody": { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }, "StatusCode": 401, "StatusText": "Unauthorized" }