如何从 Fargate 上的 Amazon ECS 任务访问其他 AWS 服务?

3 分钟阅读
0

我想从 AWS Fargate 上的 Amazon Elastic Container Service (Amazon ECS) 任务访问其他 AWS 服务。

简短描述

在调用 AWS API 时,容器化应用程序必须使用 AWS 凭证签署 AWS API 请求。对于 Amazon ECS 任务,应通过 AWS Identity and Access Management(IAM)任务角色,使用 AWS 凭证签署 API 请求。然后,将 IAM 角色与 Amazon ECS 任务定义或 RunTask API 操作相关联。完成此项操作后,您的容器可以使用 AWS SDK 或 AWS 命令行界面(AWS CLI)向授权的 AWS 服务发出 API 请求。

**注意:**如果在运行 AWS CLI 命令时收到错误,请确保使用最新版本的 AWS CLI
在本文中,示例解决方案适用于在 Fargate 上运行的必须访问 Amazon Simple Storage Service (Amazon S3) 的应用程序。

解决方案

先决条件

  • 确定您的 Fargate 任务必须访问的 AWS 服务。然后,创建一个 IAM 角色并指定具有在容器内调用 API 所需操作的策略。
  • 为应用程序容器创建任务定义,然后使用 taskRoleArn IAM 参数为任务指定 IAM 角色。

为任务创建 IAM 策略和角色

1.    创建一个 Amazon S3 存储桶来存储数据。存储桶名称必须是唯一的,必须遵守 Amazon S3 存储桶的名称要求。有关更多信息,请参阅 Bucket naming rules

2.    为任务创建 IAM 策略和角色。在此示例中,应用程序需要将对象放入 S3 存储桶,然后列出这些对象:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "S3PutGEList",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject", "s3:ListBucketMultipartUploads", "s3:ListBucketVersions", "s3:ListBucket", "s3:ListMultipartUploadParts"],
    "Resource": ["arn:aws:s3:::*/*", "arn:aws:s3:::kc-test-fargate-app-bucket"]
  }]
}

**注意:**将 fargate-app-bucket 替换为 S3 存储桶的名称。

为应用程序创建任务定义并为任务指定 IAM 角色

要在创建任务定义时分配角色,请使用 taskRoleArn 部分:

{
  "containerDefinitions": [{
    "name": "sample-s3-access",
    "image": "public.ecr.aws/aws-cli/aws-cli:latest",
    "memory": 1024,
    "cpu": 512,
    "command": ["s3api", "put-object", "--bucket", "fargate-app-bucket", "--key", "/usr/local/bin/aws"],
    "essential": true
  }],
  "memory": "1024",
  "cpu": "512",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX"
  },
  "family": "s3_access-WITH-ROLE",
  "taskRoleArn": "arn:aws:iam::aws_account_id:role/s3-access-role"
}

**注意:**由于基础镜像包含 aws-cli 安装(public.ecr.aws/aws-cli/aws-cli:latest),因此,此应用程序可以进行 API 调用。

将配置信息保存到文件中,然后使用 register-task-definition 命令注册任务定义:

aws ecs register-task-definition --cli-input-json file://task-def1.json --region eu-west-1

创建并运行独立任务

运行独立任务,请使用 Fargate 启动类型。在此示例中,容器根据命令运行然后退出。

容器运行命令后,如果 taskRoleArn 具有运行 API 调用所需的权限,任务将返回 ExitCode=0。如果 taskRoleArn 缺失或权限不足,任务将返回 none 0 exit code

创建服务

**注意:**为了使服务达到稳定状态,任务进程无法在进入时退出。在前面的示例中,容器在命令完成后退出。因此,该示例不适合作为服务的一部分运行。

1.    创建一个 bash 脚本,该脚本运行循环并将文件的创建日期和主机名打印到一个文件上。然后,将文件推送到 Amazon S3 桶。

在下面的示例中,bash 脚本被名为“run-s3-script.sh”。

#!/bin/bash

while true; do
TODAY=$(date)
echo "-----------------------------------------------------"
echo "Date: $TODAY Host:$HOST"
echo "File was added and active on these Dates: $TODAY" from Host:$HOSTNAME>> checkfile.txt
echo "--------------------Add to S3------------------------"
aws s3 cp checkfile.txt s3://kc-test-fargate-app-bucket
status_code=$?
echo "------------Get upload StatusCode=$status_code ([ $status_code -eq 0 ] means failed)---------------"
#echo "------------Get upload StatusCode=$status_code and exit if upload failed.---------------"
#[ $status_code -eq 0 ] || exit 1
echo "------------Also list the files in the S3 bucket---------------"
aws s3 ls s3://kc-test-fargate-app-bucket
status_code=$?
echo "------------Get the status_code=$status_code after listing objects in bucket---------------"
#[ $status_code -eq 0 ] || exit 1 #uncomment this is you want the task to stop upon failed attempt
echo "============================================================================="
sleep 5

#check the user or role that made the call
aws sts get-caller-identity
echo "*****End of loop, restarting"
sleep 10

done

2.    要构建添加脚本并运行该脚本的新镜像,请创建一个 Dockerfile:

FROM public.ecr.aws/amazonlinux/amazonlinux:latest
Run yum -y install unzip
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN /aws/install
RUN rm -rf aws*
COPY run-s3-test.sh /
CMD ./run-s3-test.sh

3.    要在本地构建镜像,请运行以下命令:

$ docker build -t test-awscli:amz-build-scripts

4.    将镜像推送到 Amazon Elastic Container Registry (Amazon ECR)。将镜像添加到用于创建服务的任务定义中。有关更多信息,请参阅 Pushing an image

{
  "containerDefinitions": [{
    "name": "add-files-to-s3",
    "image": "aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/test-s3-ecs:amzlin-build-scripts",
    "memory": 1024,
    "cpu": 512,
    "healthCheck": {
      "retries": 3,
      "command": ["CMD-SHELL", "aws s3 ls s3://kc-test-fargate-app-bucket || exit 1"],
      "timeout": 5,
      "interval": 10,
      "startPeriod": 5
    },
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/test-s3-script",
        "awslogs-region": "eu-central-1",
        "awslogs-create-group": "true",
        "awslogs-stream-prefix": "ecs"
      }
    },
    "essential": true
  }],
  "memory": "1024",
  "cpu": "512",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX"
  },
  "family": "test-s3-script",
  "taskRoleArn": "arn:aws:iam::aws_account_id:role/s3-access-role",
  "executionRoleArn": "arn:aws:iam::aws_account_id:role/ecsTaskExecutionRole"
}

**注意:**在容器中使用 IAM 任务角色时,可能会收到“访问被拒绝”错误。有关更多信息,请参阅 How can I configure IAM task roles in Amazon ECS to avoid "Access Denied" errors?

相关信息

使用控制台创建服务

AWS 官方
AWS 官方已更新 9 个月前