使用 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-nameMyCluster
输出:
{
"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-nameecs-tutorial-sg--description "ECS tutorial security group"输出:
{ "GroupId": "sg-abcd1234" } -
通过运行以下命令,将一条入站规则添加到该安全组。
aws ec2 authorize-security-group-ingress --group-idsg-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-nameecs-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-idami-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。该实例使用ecsInstanceRoleIAM 角色,从而为该代理提供所需的权限。
列出容器实例
在启动您的容器实例后的几分钟内,Amazon ECS 代理将向您的 MyCluster 集群注册该实例。您可以通过运行以下命令列出集群中的容器实例:
aws ecs list-container-instances --clusterMyCluster
输出:
{
"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 --clusterMyCluster--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-jsonfile://$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 任务定义的单个实例放置在 MyCluster 集群中。
aws ecs create-service --clusterMyCluster--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 --clusterMyCluster
输出:
{
"taskArns": [
"arn:aws:ecs:us-east-1:aws_account_id:task/task_ID"
]
}
描述服务
使用以下命令描述服务,以获取有关该服务的更多信息。
aws ecs describe-services --clusterMyCluster--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 --clusterMyCluster--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-idsi-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 --clusterMyCluster--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 --clusterMyCluster--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-idsi-abcd1234{ "TerminatingInstances": [ { "InstanceId": "i-abcd1234", "CurrentState": { "Code": 32, "Name": "shutting-down" }, "PreviousState": { "Code": 16, "Name": "running" } } ] } -
清理您创建的安全组和密钥对。
aws ec2 delete-security-group --group-idsg-abcd1234aws ec2 delete-key-pair --key-nameecs-tutorial-keyrmecs-tutorial-key.pem -
删除 Amazon ECS 集群。
aws ecs delete-cluster --clusterMyCluster{ "cluster": { "clusterArn": "arn:aws:ecs:us-east-1:123456789012:cluster/MyCluster", "clusterName": "MyCluster", "status": "INACTIVE" } }