使用 AWS CLI 创建 EC2 启动类型的 Amazon ECS 任务
以下步骤帮助您在 Amazon ECS 中使用 AWS CLI 设置集群、注册任务定义、运行任务和执行其他常见方案。使用最新版本的 AWS CLI。有关如何升级到最新版本的更多信息,请参阅 Installing or updating to the latest version of the AWS CLI。
注意
您可以使用双堆栈服务端点通过 IPv4 和 IPv6 从 AWS CLI、SDK 和 Amazon ECS API 与 Amazon ECS 进行交互。有关更多信息,请参阅 使用 Amazon ECS 双堆栈端点。
先决条件
本教程假设以下先决条件已完成:
-
安装并配置了最新版本的 AWS CLI。有关安装或升级 AWS CLI 的更多信息,请参阅 Installing or updating to the latest version of the AWS CLI。
-
设置以使用 Amazon ECS 中的步骤已完成。
-
您的 IAM 用户具有 AmazonECS_FullAccess IAM 策略示例中指定的必需权限。
-
您已创建了一个可供使用的容器实例 IAM 角色。有关更多信息,请参阅Amazon ECS 容器实例 IAM 角色。
-
您已创建了一个可供使用的 VPC。有关更多信息,请参阅 创建 Virtual Private Cloud。
-
(可选)AWS CloudShell 是一种为客户提供命令行的工具,而无需创建自己的 EC2 实例。有关更多信息,请参阅《AWS CloudShell 用户指南》中的什么是 AWS CloudShell?。
创建集群
默认情况下,当您启动第一个容器实例时,您的账户将收到一个 default
集群。
注意
使用为您提供的 default
群集的好处是您不必在后续命令中指定 --cluster
选项。如果您自行创建非默认集群,您必须为您打算用于该集群的每个命令指定 cluster_name
--cluster
。cluster_name
使用以下命令自行创建具有唯一名称的集群:
aws ecs create-cluster --cluster-name
MyCluster
输出:
{
"cluster": {
"clusterName": "MyCluster",
"status": "ACTIVE",
"clusterArn": "arn:aws:ecs:region
:aws_account_id
:cluster/MyCluster"
}
}
使用 Amazon ECS AMI 启动容器实例
容器实例是已注册到集群并且将会运行 Amazon ECS 容器代理的 EC2 实例。在这一部分中,您将使用 ECS 优化版 AMI 启动一个 EC2 实例。
使用 AWS CLI 启动容器实例
-
使用以下命令检索您所在 AWS 区域的最新 ECS 优化版 Amazon Linux 2 AMI ID。此命令使用 AWS Systems Manager Parameter Store 来获取最新 ECS 优化版 AMI ID。该 AMI 包括预装的 Amazon ECS 容器代理和 Docker 运行时。
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/recommended --query 'Parameters[0].Value' --output text | jq -r '.image_id'
输出:
ami-abcd1234
-
创建一个允许 SSH 访问(用来管理容器实例)和 HTTP 访问(用于 Web 服务器)的安全组。
aws ec2 create-security-group --group-name
ecs-tutorial-sg
--description "ECS tutorial security group"输出:
{ "GroupId": "sg-abcd1234" }
-
通过运行以下命令,将一条入站规则添加到该安全组。
aws ec2 authorize-security-group-ingress --group-id
sg-abcd1234
--protocol tcp --port 80 --cidr 0.0.0.0/0输出:
{ "Return": true, "SecurityGroupRules": [ { "SecurityGroupRuleId": "sgr-efgh5678", "GroupId": "sg-abcd1234", "GroupOwnerId": "123456789012", "IsEgress": false, "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIpv4": "0.0.0.0/0" } ] }
现在,该安全组将允许从指定 IP 范围进行 SSH 访问以及从任何位置进行 HTTP 访问。在生产环境中,您应仅允许从您的特定 IP 地址进行 SSH 访问,并在需要时考虑限制 HTTP 访问。
-
创建一个 EC2 密钥对,用于对容器实例的 SSH 访问。
aws ec2 create-key-pair --key-name
ecs-tutorial-key
--query 'KeyMaterial' --output text > ecs-tutorial-key.pem chmod 400 ecs-tutorial-key.pem该私有密钥将保存到具有恰当 SSH 访问权限的本地计算机中。
-
使用 ECS 优化版 AMI 启动一个 EC2 实例,并进行配置以加入您的集群。
aws ec2 run-instances --image-id
ami-abcd1234
--instance-typet3.micro
--key-nameecs-tutorial-key
--security-group-idssg-abcd1234
--iam-instance-profile Name=ecsInstanceRole --user-data '#!/bin/bash echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.config' { "Instances": [ { "InstanceId": "i-abcd1234", "ImageId": "ami-abcd1234", "State": { "Code": 0, "Name": "pending" }, "PrivateDnsName": "", "PublicDnsName": "", "StateReason": { "Code": "pending", "Message": "pending" }, "InstanceType": "t3.micro", "KeyName": "ecs-tutorial-key", "LaunchTime": "2025-01-13T10:30:00.000Z" } ] }此用户数据脚本会配置 Amazon ECS 代理,以将该实例注册到您的
MyCluster
。该实例使用ecsInstanceRole
IAM 角色,从而为该代理提供所需的权限。
列出容器实例
在启动您的容器实例后的几分钟内,Amazon ECS 代理将向您的默认集群注册该实例。您可以通过运行以下命令列出集群中的容器实例:
aws ecs list-container-instances --cluster
default
输出:
{
"containerInstanceArns": [
"arn:aws:ecs:us-east-1:aws_account_id
:container-instance/container_instance_ID
"
]
}
描述容器实例
在拥有某个容器实例的 ARN 或 ID 后,您就可以使用 describe-container-instances 命令获取有关该实例的有价值的信息,例如剩余的和已注册的 CPU 和内存资源。
aws ecs describe-container-instances --cluster
MyCluster
--container-instancescontainer_instance_ID
输出:
{
"failures": [],
"containerInstances": [
{
"status": "ACTIVE",
"registeredResources": [
{
"integerValue": 1024,
"longValue": 0,
"type": "INTEGER",
"name": "CPU",
"doubleValue": 0.0
},
{
"integerValue": 995,
"longValue": 0,
"type": "INTEGER",
"name": "MEMORY",
"doubleValue": 0.0
},
{
"name": "PORTS",
"longValue": 0,
"doubleValue": 0.0,
"stringSetValue": [
"22",
"2376",
"2375",
"51678"
],
"type": "STRINGSET",
"integerValue": 0
},
{
"name": "PORTS_UDP",
"longValue": 0,
"doubleValue": 0.0,
"stringSetValue": [],
"type": "STRINGSET",
"integerValue": 0
}
],
"ec2InstanceId": "instance_id
",
"agentConnected": true,
"containerInstanceArn": "arn:aws:ecs:us-west-2:aws_account_id
:container-instance/container_instance_ID
",
"pendingTasksCount": 0,
"remainingResources": [
{
"integerValue": 1024,
"longValue": 0,
"type": "INTEGER",
"name": "CPU",
"doubleValue": 0.0
},
{
"integerValue": 995,
"longValue": 0,
"type": "INTEGER",
"name": "MEMORY",
"doubleValue": 0.0
},
{
"name": "PORTS",
"longValue": 0,
"doubleValue": 0.0,
"stringSetValue": [
"22",
"2376",
"2375",
"51678"
],
"type": "STRINGSET",
"integerValue": 0
},
{
"name": "PORTS_UDP",
"longValue": 0,
"doubleValue": 0.0,
"stringSetValue": [],
"type": "STRINGSET",
"integerValue": 0
}
],
"runningTasksCount": 0,
"attributes": [
{
"name": "com.amazonaws.ecs.capability.privileged-container"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"name": "com.amazonaws.ecs.capability.logging-driver.json-file"
},
{
"name": "com.amazonaws.ecs.capability.logging-driver.syslog"
}
],
"versionInfo": {
"agentVersion": "1.5.0",
"agentHash": "b197edd",
"dockerVersion": "DockerVersion: 1.7.1"
}
}
]
}
您也可以在 Amazon EC2 控制台中或使用 aws ec2 describe-instances --instance-id
instance_id
命令查找可用于监控实例的 Amazon EC2 实例 ID。
注册任务定义
您必须首先注册一个任务定义,然后才能在 Amazon ECS 集群上运行任务。任务定义是分组在一起的一系列容器。以下示例是一个使用 nginx
映像的简单任务定义。有关可用任务定义参数的更多信息,请参阅 Amazon ECS 任务定义。
{ "family": "nginx-task", "containerDefinitions": [ { "name": "nginx", "image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", "cpu": 256, "memory": 512, "essential": true, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ] } ], "requiresCompatibilities": ["EC2"], "networkMode": "bridge" }
上述示例 JSON 可通过两种方式传递到 AWS CLI:您可以将任务定义 JSON 保存为文件并使用
选项传递它。您也可以对 JSON 中的引号进行转义并在命令行上传递 JSON 容器定义。如果您选择在命令行上传递容器定义,您的命令还需要一个 --cli-input-json
file://path_to_file.json
--family
参数,该参数用于使任务定义的多个版本保持互相关联。
将 JSON 文件用于容器定义:
aws ecs register-task-definition --cli-input-json
file://$HOME/tasks/nginx.json
register-task-definition 将在其完成注册后返回任务定义的说明。
{
"taskDefinition": {
"taskDefinitionArn": "arn:aws:ecs:us-east-1:123456789012:task-definition/nginx-task:1",
"family": "nginx-task",
"revision": 1,
"status": "ACTIVE",
"containerDefinitions": [
{
"name": "nginx",
"image": "public.ecr.aws/docker/library/nginx:latest",
"cpu": 256,
"memory": 512,
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"environment": [],
"mountPoints": [],
"volumesFrom": []
}
],
"volumes": [],
"networkMode": "bridge",
"compatibilities": [
"EC2"
],
"requiresCompatibilities": [
"EC2"
]
}
}
列出任务定义
您可以随时使用 list-task-definitions 命令列出您的账户的任务定义。此命令的输出将显示 family
和 revision
值,您可以在调用 create-service 时将这些值一起使用。
aws ecs list-task-definitions
输出:
{
"taskDefinitionArns": [
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/sleep360:1",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/sleep360:2",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/nginx-task:1",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/wordpress:3",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/wordpress:4",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/wordpress:5",
"arn:aws:ec2:us-east-1:aws_account_id
:task-definition/wordpress:6"
]
}
创建服务
在为账户注册任务并启动注册到集群的容器实例后,您可以创建一个 Amazon ECS 服务,从而使用所注册的任务定义同时运行和维持所需数量的任务。在本实例中,您将 nginx:1
任务定义的单个实例放置在默认集群中。
aws ecs create-service --cluster
default
--service-namenginx-service
--task-definitionnginx-task:1
--desired-count1
输出:
{
"service": {
"serviceArn": "arn:aws:ecs:us-east-1:aws_account_id
:service/MyCluster/nginx-service",
"serviceName": "nginx-service",
"clusterArn": "arn:aws:ecs:us-east-1:aws_account_id
:cluster/MyCluster",
"taskDefinition": "arn:aws:ecs:us-east-1:aws_account_id
:task-definition/nginx-task:1",
"desiredCount": 1,
"runningCount": 0,
"pendingCount": 0,
"launchType": "EC2",
"status": "ACTIVE",
"createdAt": "2025-01-13T10:45:00.000Z"
}
}
列出服务
列出您的集群的服务。您应看到您在上一部分中创建的服务。您可以记下此命令返回的服务 ID 或完整 ARN,并在稍后将其用于描述服务。
aws ecs list-services --cluster
MyCluster
输出:
{
"taskArns": [
"arn:aws:ecs:us-east-1:aws_account_id
:task/task_ID
"
]
}
描述服务
使用以下命令描述服务,以获取有关该服务的更多信息。
aws ecs describe-services --cluster
MyCluster
--servicesnginx-service
输出:
{
"services": [
{
"serviceArn": "arn:aws:ecs:us-east-1:aws_account_id
:service/MyCluster/nginx-service",
"serviceName": "nginx-service",
"clusterArn": "arn:aws:ecs:us-east-1:aws_account_id
:cluster/MyCluster",
"taskDefinition": "arn:aws:ecs:us-east-1:aws_account_id
:task-definition/nginx-task:1",
"desiredCount": 1,
"runningCount": 1,
"pendingCount": 0,
"launchType": "EC2",
"status": "ACTIVE",
"createdAt": "2025-01-13T10:45:00.000Z",
"events": [
{
"id": "abcd1234-5678-90ab-cdef-1234567890ab",
"createdAt": "2025-01-13T10:45:30.000Z",
"message": "(service nginx-service) has started 1 tasks: (task abcd1234-5678-90ab-cdef-1234567890ab)."
}
]
}
]
}
描述正在运行的任务
在描述服务后,运行以下命令可获取有关该服务中正在运行的任务的更多信息。
aws ecs list-tasks --cluster
MyCluster
--service-namenginx-service
输出:
{
"tasks": [
{
"taskArn": "arn:aws:ecs:us-east-1:aws_account_id
:task/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
"clusterArn": "arn:aws:ecs:us-east-1:aws_account_id
:cluster/MyCluster",
"taskDefinitionArn": "arn:aws:ecs:us-east-1:aws_account_id
:task-definition/nginx-task:1",
"containerInstanceArn": "arn:aws:ecs:us-east-1:aws_account_id
:container-instance/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
"lastStatus": "RUNNING",
"desiredStatus": "RUNNING",
"containers": [
{
"containerArn": "arn:aws:ecs:us-east-1:aws_account_id
:container/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab/abcd1234-5678-90ab-cdef-1234567890ab",
"taskArn": "arn:aws:ecs:us-east-1:aws_account_id
:task/MyCluster/abcd1234-5678-90ab-cdef-1234567890ab",
"name": "nginx",
"lastStatus": "RUNNING",
"networkBindings": [
{
"bindIP": "0.0.0.0",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
]
}
],
"createdAt": "2025-01-13T10:45:00.000Z",
"startedAt": "2025-01-13T10:45:30.000Z"
}
]
}
测试 Web 服务器
测试 Web 服务器
-
通过运行以下命令,检索容器实例的公有 IP 地址。
aws ec2 describe-instances --instance-ids
i-abcd1234
--query 'Reservations[0].Instances[0].PublicIpAddress' --output text输出:
203.0.113.25
-
检索到 IP 地址后,使用该 IP 地址运行以下
curl
命令。curl http://203.0.113.25
输出:
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... </head> <body> <h1>Welcome to nginx!</h1> <p>If you can see this page, the nginx web server is successfully installed and working.</p> ... </body> </html>
nginx 欢迎页面会确认您的服务已成功运行并且可以从互联网访问。
清理资源
要避免产生费用,请清理您在本教程中创建的资源。
清理资源
-
更新服务,使需要的任务数降为零,然后删除服务。
aws ecs update-service --cluster
MyCluster
--servicenginx-service
--desired-count 0 { "service": { "serviceArn": "arn:aws:ecs:us-east-1:123456789012:service/MyCluster/nginx-service", "serviceName": "nginx-service", "desiredCount": 0, "runningCount": 1, "pendingCount": 0, "status": "ACTIVE" } } -
等待正在运行的任务停止,然后再删除服务。
aws ecs delete-service --cluster
MyCluster
--servicenginx-service
{ "service": { "serviceArn": "arn:aws:ecs:us-east-1:123456789012:service/MyCluster/nginx-service", "serviceName": "nginx-service", "status": "DRAINING" } } -
终止您创建的容器实例。
aws ec2 terminate-instances --instance-ids
i-abcd1234
{ "TerminatingInstances": [ { "InstanceId": "i-abcd1234", "CurrentState": { "Code": 32, "Name": "shutting-down" }, "PreviousState": { "Code": 16, "Name": "running" } } ] } -
清理您创建的安全组和密钥对。
aws ec2 delete-security-group --group-id
sg-abcd1234
aws ec2 delete-key-pair --key-nameecs-tutorial-key
rmecs-tutorial-key.pem
-
删除 Amazon ECS 集群。
aws ecs delete-cluster --cluster
MyCluster
{ "cluster": { "clusterArn": "arn:aws:ecs:us-east-1:123456789012:cluster/MyCluster", "clusterName": "MyCluster", "status": "INACTIVE" } }