

# 了解如何使用 AWS CLI 为 Amazon ECS 托管实例创建任务
<a name="getting-started-managed-instances-cli"></a>

 以下步骤可帮助您使用 AWS CLI 在 Amazon ECS 和 Amazon ECS 托管实例中设置集群、创建容量提供程序、注册任务定义、运行 Linux 任务以及执行其他常见场景。使用最新版本的 AWS CLI。有关如何升级到最新版本的更多信息，请参阅[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

**注意**  
 您可以使用双堆栈服务端点通过 IPv4 和 IPv6 从 AWS AWS CLI、SDK 和 Amazon ECS API 与 Amazon ECS 进行交互。有关更多信息，请参阅 [使用 Amazon ECS 双堆栈端点](dual-stack-endpoint.md)。

**主题**
+ [先决条件](#managed-instances-cli-prereq)
+ [步骤 1：创建集群](#managed-instances-cli-create-cluster)
+ [步骤 2：创建 Amazon ECS 托管实例容量提供程序](#managed-instances-cli-create-capacity-provider)
+ [步骤 3：配置集群的默认容量提供程序策略](#managed-instances-cli-configure-cluster)
+ [步骤 4：注册 Linux 任务定义](#managed-instances-cli-register-task-definition)
+ [步骤 5：列出任务定义](#managed-instances-cli-list-task-definitions)
+ [步骤 6：创建服务](#managed-instances-cli-create-service)
+ [步骤 7：列出服务](#managed-instances-cli-list-services)
+ [步骤 8：描述正在运行的服务](#managed-instances-cli-describe-service)
+ [步骤 9：测试](#managed-instances-cli-test)
+ [步骤 10：清理](#managed-instances-cli-clean-up)

## 先决条件
<a name="managed-instances-cli-prereq"></a>

 开始教程前，请完成以下任务：
+ 您已完成[设置以使用 Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/get-set-up-for-amazon-ecs.html)中的步骤。
+ 安装并配置了最新版本的 AWS CLI。有关安装或升级 AWS CLI 的更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ [设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md) 中的步骤已完成。
+ 您拥有 Amazon ECS 托管实例所需的 IAM 角色。这包括：
  + 基础设施角色：允许 Amazon ECS 代表您调用 AWS 服务来管理 Amazon ECS 托管实例基础设施。

    有关更多信息，请参阅 [Amazon ECS 基础设施 IAM 角色](infrastructure_IAM_role.md)。
  + 实例配置文件：为在托管实例上运行的 Amazon ECS 容器代理和 Docker 进程守护程序提供权限。

    实例角色名称必须包含 `ecsInstanceRole` 作为前缀，以匹配基础设施角色中的 `iam:PassRole` 操作。

    有关更多信息，请参阅 [Amazon ECS 托管实例实例配置文件](managed-instances-instance-profile.md)。
+ 您已创建要使用的 VPC 和安全组。本教程使用的是托管在 Amazon ECR Public 上的容器映像，因此您的实例必须具有互联网访问权限。要让您的实例路由到互联网，请使用下列选项之一：
  + 将私有子网与具有弹性 IP 地址的 NAT 网关结合使用。
  + 使用公有子网并向实例分配公有 IP 地址。

  有关更多信息，请参阅 [创建虚拟私有云](get-set-up-for-amazon-ecs.md#create-a-vpc)。

  有关安全组的信息，请参阅《Amazon Virtual Private Cloud 用户指南》**中的[您的 VPC 的默认安全组](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#DefaultSecurityGroup)和[示例规则](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#security-group-rule-examples)。
+ （可选）AWS CloudShell 是一种为客户提供命令行的工具，而无需创建自己的 EC2 实例。有关更多信息，请参阅《AWS CloudShell 用户指南》**中的[什么是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 步骤 1：创建集群
<a name="managed-instances-cli-create-cluster"></a>

 默认情况下，您的账户会收到一个 `default` 集群。

**注意**  
 使用为您提供的 `default` 集群的好处是您不必在后续命令中指定 `--cluster cluster_name` 选项。如果您自行创建非默认集群，您必须为您打算用于该集群的每个命令指定 `--cluster cluster_name`。

 使用以下命令自行创建具有唯一名称的集群：

```
aws ecs create-cluster --cluster-name managed-instances-cluster
```

输出：

```
{
    "cluster": {
        "status": "ACTIVE", 
        "defaultCapacityProviderStrategy": [], 
        "statistics": [], 
        "capacityProviders": [], 
        "tags": [], 
        "clusterName": "managed-instances-cluster", 
        "settings": [
            {
                "name": "containerInsights", 
                "value": "disabled"
            }
        ], 
        "registeredContainerInstancesCount": 0, 
        "pendingTasksCount": 0, 
        "runningTasksCount": 0, 
        "activeServicesCount": 0, 
        "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/managed-instances-cluster"
    }
}
```

## 步骤 2：创建 Amazon ECS 托管实例容量提供程序
<a name="managed-instances-cli-create-capacity-provider"></a>

 在使用 Amazon ECS 托管实例运行任务之前，您必须创建一个定义基础设施配置的容量提供程序。该容量提供程序为您的托管实例指定 IAM 角色、网络配置和其他设置。

 创建一个包含容量提供程序配置的 JSON 文件。将占位符值替换为您的实际资源标识符：

```
{
    "name": "managed-instances-cp",
    "cluster": "managed-instances-cluster",
    "managedInstancesProvider": {
        "infrastructureRoleArn": "arn:aws:iam::aws_account_id:role/ecsInfrastructureRole",
        "instanceLaunchTemplate": {
            "ec2InstanceProfileArn": "arn:aws:iam::aws_account_id:instance-profile/ecsInstanceRole",
            "networkConfiguration": {
                "subnets": [
                    "subnet-abcdef01234567890",
                    "subnet-1234567890abcdef0"
                ],
                "securityGroups": [
                    "sg-0123456789abcdef0"
                ]
            },
            "storageConfiguration": {
                "storageSizeGiB": 100
            },
            "monitoring": "basic"
        }
    }
}
```

 将此配置另存为 `managed-instances-cp.json` 并创建容量提供程序：

```
aws ecs create-capacity-provider --cli-input-json file://managed-instances-cp.json
```

 该命令在容量提供程序创建完成后会返回其描述。

## 步骤 3：配置集群的默认容量提供程序策略
<a name="managed-instances-cli-configure-cluster"></a>

 更新集群，使其使用 Amazon ECS 托管实例容量提供程序作为默认容量提供程序策略。这样，任务和服务就可以自动使用 Amazon ECS 托管实例，而无需明确指定容量提供程序。

 创建一个包含集群容量提供程序配置的 JSON 文件：

```
{
    "cluster": "managed-instances-cluster",
    "capacityProviders": [
        "managed-instances-cp"
    ],
    "defaultCapacityProviderStrategy": [
        {
            "capacityProvider": "managed-instances-cp",
            "weight": 1
        }
    ]
}
```

 将此配置另存为 `cluster-cp-strategy.json` 并更新集群：

```
aws ecs put-cluster-capacity-providers --cli-input-json file://cluster-cp-strategy.json
```

## 步骤 4：注册 Linux 任务定义
<a name="managed-instances-cli-register-task-definition"></a>

 您必须先注册任务定义，然后才能在集群上运行任务。任务定义是分组在一起的一系列容器。以下示例是一个简单的任务定义，它使用托管在 Docker Hub 上的 httpd 容器映像创建 PHP Web 应用程序。有关可用任务定义参数的更多信息，请参阅 [Fargate 的 Amazon ECS 任务定义参数](task_definition_parameters.md)。

```
{
    "family": "sample-managed-instances",
    "networkMode": "awsvpc",
    "containerDefinitions": [
        {
            "name": "managed-instances-app",
            "image": "public.ecr.aws/docker/library/httpd:latest",
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "entryPoint": [
                "sh",
                "-c"
            ],
            "command": [
                "/bin/sh -c \"echo '<html><head><title>Amazon ECS Sample App</title><style>body {margin-top: 40px; background-color: #333;} </style></head><body><div style=color:white;text-align:center><h1>Amazon ECS Sample App</h1><h2>Congratulations!</h2><p>Your application is now running on a container in Amazon ECS using Amazon ECS Managed Instances.</p></div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
            ]
        }
    ],
    "requiresCompatibilities": [
        "MANAGED_INSTANCES"
    ],
    "cpu": "256",
    "memory": "512"
}
```

 将任务定义 JSON 保存为文件并使用 `--cli-input-json file://path_to_file.json` 选项传递它。

 将 JSON 文件用于容器定义：

```
aws ecs register-task-definition --cli-input-json file://$HOME/tasks/managed-instances-task.json
```

 **register-task-definition** 命令在完成其注册后会返回任务定义的描述。

## 步骤 5：列出任务定义
<a name="managed-instances-cli-list-task-definitions"></a>

 您可以随时使用 **list-task-definitions** 命令列出您的账户的任务定义。此命令的输出将显示 `family` 和 `revision` 值，您可以在调用 **run-task** 或 **start-task** 时将这些值一起使用。

```
aws ecs list-task-definitions
```

输出：

```
{
    "taskDefinitionArns": [
        "arn:aws:ecs:region:aws_account_id:task-definition/sample-managed-instances:1"
    ]
}
```

## 步骤 6：创建服务
<a name="managed-instances-cli-create-service"></a>

 为账户注册任务后，您可以为集群中已注册的任务创建服务。在此示例中，您将使用集群中运行的一个 `sample-managed-instances:1` 任务定义实例来创建服务。此任务需要连接到互联网，您可以通过两种方法实现这一点。一种方法是将使用 NAT 网关配置的私有子网与公有子网中的弹性 IP 地址结合使用。另一种方法是使用公有子网并向任务分配公有 IP 地址。下面提供了这两种方法的示例。

 使用私有子网的示例：

```
aws ecs create-service --cluster managed-instances-cluster --service-name managed-instances-service --task-definition sample-managed-instances:1 --desired-count 1 --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234]}"
```

 使用公有子网的示例：

```
aws ecs create-service --cluster managed-instances-cluster --service-name managed-instances-service --task-definition sample-managed-instances:1 --desired-count 1 --network-configuration "awsvpcConfiguration={subnets=[subnet-abcd1234],securityGroups=[sg-abcd1234],assignPublicIp=ENABLED}"
```

 **create-service** 命令在服务创建完成后会返回其描述。

## 步骤 7：列出服务
<a name="managed-instances-cli-list-services"></a>

 列出您的集群的服务。您应看到您在上一部分中创建的服务。您可以选取从此命令返回的服务名称或完整 ARN 并在稍后将其用于描述服务。

```
aws ecs list-services --cluster managed-instances-cluster
```

输出：

```
{
    "serviceArns": [
        "arn:aws:ecs:region:aws_account_id:service/managed-instances-cluster/managed-instances-service"
    ]
}
```

## 步骤 8：描述正在运行的服务
<a name="managed-instances-cli-describe-service"></a>

 使用之前检索到的服务名称描述服务，以获取有关任务的更多信息。

```
aws ecs describe-services --cluster managed-instances-cluster --services managed-instances-service
```

 如果成功，这将返回服务失败和服务的描述。例如，在 `services` 部分中，您将找到有关部署的信息，例如任务的正在运行或待处理状态。也可以找到有关任务定义、网络配置和带时间戳的事件的信息。在失败部分中，您将找到与调用关联的失败的信息（如果有）。

 输出将显示该服务正在使用 Amazon ECS 托管实例容量提供程序：

```
{
    "services": [
        {
            "capacityProviderStrategy": [
                {
                    "capacityProvider": "managed-instances-cp",
                    "weight": 1,
                    "base": 0
                }
            ],
            "networkConfiguration": {
                "awsvpcConfiguration": {
                    "subnets": [
                        "subnet-abcd1234"
                    ], 
                    "securityGroups": [
                        "sg-abcd1234"
                    ], 
                    "assignPublicIp": "ENABLED"
                }
            }, 
            "enableECSManagedTags": false, 
            "loadBalancers": [], 
            "deploymentController": {
                "type": "ECS"
            }, 
            "desiredCount": 1, 
            "clusterArn": "arn:aws:ecs:region:aws_account_id:cluster/managed-instances-cluster", 
            "serviceArn": "arn:aws:ecs:region:aws_account_id:service/managed-instances-service", 
            "serviceName": "managed-instances-service",
            "taskDefinition": "arn:aws:ecs:region:aws_account_id:task-definition/sample-managed-instances:1"
        }
    ], 
    "failures": []
}
```

## 步骤 9：测试
<a name="managed-instances-cli-test"></a>

 要测试您的部署，您需要找到运行您的任务的托管实例的公有 IP 地址。

### 使用公有子网部署的测试任务
<a name="managed-instances-cli-test-public-subnet"></a>

 首先，从您的服务中获取任务 ARN：

```
aws ecs list-tasks --cluster managed-instances-cluster --service managed-instances-service
```

 输出包含任务 ARN：

```
{
    "taskArns": [
        "arn:aws:ecs:region:aws_account_id:task/managed-instances-cluster/EXAMPLE"
    ]
}
```

 描述任务以获取容器实例 ARN。将任务 ARN 用于 `tasks` 参数：

```
aws ecs describe-tasks --cluster managed-instances-cluster --tasks arn:aws:ecs:region:aws_account_id:task/managed-instances-cluster/EXAMPLE
```

 输出显示任务正在 Amazon ECS 托管实例上运行，并且包括容器实例 ARN：

```
{
    "tasks": [
        {
            "launchType": "MANAGED_INSTANCES",
            "capacityProviderName": "managed-instances-cp",
            "containerInstanceArn": "arn:aws:ecs:region:aws_account_id:container-instance/managed-instances-cluster/CONTAINER_INSTANCE_ID",
            "taskArn": "arn:aws:ecs:region:aws_account_id:task/managed-instances-cluster/EXAMPLE",
            "taskDefinitionArn": "arn:aws:ecs:region:aws_account_id:task-definition/sample-managed-instances:1"
        }
    ]
}
```

 描述容器实例以获取 EC2 实例 ID：

```
aws ecs describe-container-instances --cluster managed-instances-cluster --container-instances CONTAINER_INSTANCE_ID
```

 输出包括 EC2 实例 ID：

```
{
    "containerInstances": [
        {
            "ec2InstanceId": "i-1234567890abcdef0",
            "capacityProviderName": "managed-instances-cp",
            "containerInstanceArn": "arn:aws:ecs:region:aws_account_id:container-instance/managed-instances-cluster/CONTAINER_INSTANCE_ID"
        }
    ]
}
```

 描述 EC2 实例以获取公有 IP 地址：

```
aws ec2 describe-instances --instance-ids i-1234567890abcdef0
```

 输出中包含公有 IP 地址：

```
{
    "Reservations": [
        {
            "Instances": [
                {
                    "PublicIpAddress": "198.51.100.2",
                    "InstanceId": "i-1234567890abcdef0"
                }
            ]
        }
    ]
}
```

 在 Web 浏览器中输入公有 IP 地址，您应该会看到一个网页，其显示在 Amazon ECS 托管实例上运行的 **Amazon ECS** 示例应用程序。

### 使用私有子网部署的测试任务
<a name="managed-instances-cli-test-private-subnet"></a>

 对于部署在私有子网中的任务，您可以使用 Amazon ECS Exec 连接到容器，并从实例内部测试部署。请按照与上述相同的步骤获取任务 ARN，然后使用 ECS Exec：

```
aws ecs execute-command --cluster managed-instances-cluster \
    --task arn:aws:ecs:region:aws_account_id:task/managed-instances-cluster/EXAMPLE \
    --container managed-instances-app \
    --interactive \
    --command "/bin/sh"
```

 交互式 shell 运行后，即可测试 Web 服务器：

```
curl localhost
```

 您应该会看到与 **Amazon ECS** 示例应用程序网页等效的 HTML。

## 步骤 10：清理
<a name="managed-instances-cli-clean-up"></a>

 完成本教程后，您应清除相关资源，以避免产生与未使用的资源相关的费用。

 删除服务：

```
aws ecs delete-service --cluster managed-instances-cluster --service managed-instances-service --force
```

 等待服务删除完毕且所有任务停止后，再删除容量提供程序：

```
aws ecs delete-capacity-provider --capacity-provider managed-instances-cp
```

 删除 集群：

```
aws ecs delete-cluster --cluster managed-instances-cluster
```

**注意**  
 删除容量提供程序后，托管实例将自动终止。您不需要手动终止 EC2 实例。