

# 通过 AWS CLI 将 Amazon ECS Windows 容器与无域 gMSA 结合使用
<a name="tutorial-gmsa-windows"></a>

以下教程演示如何创建一个 Amazon ECS 任务，该任务运行具有凭证的 Windows 容器，以使用 AWS CLI 访问 Active Directory。通过使用无域 gMSA，容器实例不会加入该域，实例上的其他应用程序无法使用凭证访问该域，并且加入不同域的任务可以在同一个实例上运行。

**Topics**
+ [先决条件](#tutorial-gmsa-windows-prerequisites)
+ [步骤 1：在 Active Directory 域服务（AD DS）上创建和配置 gMSA 账户](#tutorial-gmsa-windows-step1)
+ [步骤 2：将凭证上传到 Secrets Manager](#tutorial-gmsa-windows-step2)
+ [步骤 3：修改您的 CredSpec JSON 以包含无域 gMSA 信息](#tutorial-gmsa-windows-step3)
+ [步骤 4：将 CredSpec 上传到 Amazon S3](#tutorial-gmsa-windows-step4)
+ [步骤 5：（可选）创建 Amazon ECS 集群](#tutorial-gmsa-windows-step5)
+ [步骤 6：为容器实例创建 IAM 角色](#tutorial-gmsa-windows-step6)
+ [步骤 7：创建自定义任务执行角色](#tutorial-gmsa-windows-step7)
+ [步骤 8：为 Amazon ECS Exec 创建任务角色](#tutorial-gmsa-windows-step8)
+ [步骤 9：注册一个使用无域 gMSA 的任务定义](#tutorial-gmsa-windows-step9)
+ [步骤 10：将 Windows 容器实例注册到集群](#tutorial-gmsa-windows-step10)
+ [步骤 11：验证容器实例](#tutorial-gmsa-windows-step11)
+ [步骤 12：运行 Windows 任务](#tutorial-gmsa-windows-step12)
+ [步骤 13：验证容器是否有 gMSA 凭证](#tutorial-gmsa-windows-step13)
+ [步骤 14：清除](#tutorial-gmsa-windows-step14)
+ [调试适用于 Windows 容器的 Amazon ECS 无域 gMSA](#tutorial-gmsa-windows-debugging)

## 先决条件
<a name="tutorial-gmsa-windows-prerequisites"></a>

本教程假设以下先决条件已完成：
+ [设置以使用 Amazon ECS](get-set-up-for-amazon-ecs.md) 中的步骤已完成。
+ 您的 IAM 用户具有 [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess) IAM 策略示例中指定的必需权限。
+  安装并配置了最新版本的 AWS CLI。有关安装或升级 AWS CLI 的更多信息，请参阅[安装 AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
**注意**  
您可以使用双堆栈服务端点通过 IPv4 和 IPv6 从 AWS CLI、SDK 和 Amazon ECS API 与 Amazon ECS 进行交互。有关更多信息，请参阅 [使用 Amazon ECS 双堆栈端点](dual-stack-endpoint.md)。
+ 您可以使用您希望容器访问的资源设置 Active Directory 域。Amazon ECS 支持以下设置：
  + Directory Service Active Directory。Directory Service 是托管在 Amazon EC2 上的 AWS 托管式 Active Directory。有关更多信息，请参阅 *AWS Directory Service 管理指南*中的 [AWS 托管 Microsoft AD 入门](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)。
  + 本地 Active Directory。您必须确保 Amazon ECS Linux 容器实例可以加入域。有关更多信息，请参阅 [AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect-network-to-amazon.html)。
+ 您有一个 VPC 和可以解析 Active Directory 域名的子网。
+ 您可以在**无域 gMSA** 和**将每个实例加入单个域**之间进行选择。通过使用无域 gMSA，容器实例不会加入该域，实例上的其他应用程序无法使用凭证访问该域，并且加入不同域的任务可以在同一个实例上运行。

  然后，选择数据存储用于 CredSpec，以及无域 gMSA 的 Active Directory 用户凭证（可选）。

  Amazon ECS 使用 Active Directory 凭证规范文件（CredSpec）。该文件包含用于将 gMSA 账户上下文传播到容器的 gMSA 元数据。您可以生成 CredSpec 文件，然后将其存储在下表中的一个 CredSpec 存储选项中，该存储选项特定于容器实例的操作系统。要使用无域方法，CredSpec 文件中的可选部分可以在下表中的其中一个 *domainless user credentials* 存储选项中指定凭证，这些凭证特定于容器实例的操作系统。    
<a name="gmsa-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tutorial-gmsa-windows.html)
+ （可选）AWS CloudShell 是一种为客户提供命令行的工具，而无需创建自己的 EC2 实例。有关更多信息，请参阅《AWS CloudShell 用户指南》**中的[什么是 AWS CloudShell？](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html)。

## 步骤 1：在 Active Directory 域服务（AD DS）上创建和配置 gMSA 账户
<a name="tutorial-gmsa-windows-step1"></a>

在 Active Directory 域上创建和配置 gMSA 账户。

**注意**  
此步骤将创建两个独立账户：一个为容器提供身份的组托管服务账户（gMSA），以及一个用于域身份验证的普通用户账户。这些账户有不同的用途，所以应采用不同的名称。

1. 

**生成密钥分发服务根密钥**
**注意**  
如果您使用 Directory Service，可以跳过此步骤。

   KDS 根密钥和 gMSA 权限是使用您的 AWS 托管的 Microsoft AD 配置的。

   如果您尚未在域中创建 gMSA 服务账户，则需要先生成密钥分发服务（KDS）根密钥。KDS 负责创建、轮换 gMSA 密码并将其发布给授权的主机。当 `ccg.exe` 需要检索 gMSA 凭证时，它会联系 KDS 以检索当前密码。

   要检查是否已创建 KDS 根密钥，请使用 `ActiveDirectory` PowerShell 模块在域控制器上以域管理员权限运行以下 PowerShell cmdlet。有关该模块的更多信息，请参阅 Microsoft Learn 网站上的 [ActiveDirectory 模块](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps)。

   ```
   PS C:\> Get-KdsRootKey
   ```

   如果命令返回密钥 ID，您可以跳过此步骤的其余部分。否则，请通过运行以下命令创建 KDS 根密钥：

   ```
   PS C:\> Add-KdsRootKey -EffectiveImmediately
   ```

   尽管该命令的参数 `EffectiveImmediately` 暗示密钥立即生效，但您需要等待 10 小时才能复制 KDS 根密钥并使其可在所有域控制器上使用。

1. 

**创建 gMSA 账户**

   要创建 gMSA 账户并允许 `ccg.exe` 检索 gMSA 密码，请从具有域访问权限的 Windows 服务器或客户端上运行以下 PowerShell 命令。将 `ExampleAccount` 替换为您想要的 gMSA 账户名称，然后将 `example-domain` 替换为您的 Active Directory 域名（例如，如果域名是 `contoso.com`，则使用 `contoso`）。

   1. 

      ```
      PS C:\> Install-WindowsFeature RSAT-AD-PowerShell
      ```

   1. 

      ```
      PS C:\> New-ADGroup -Name "ExampleAccount Authorized Hosts" -SamAccountName "ExampleAccountHosts" -GroupScope DomainLocal
      ```

   1. 

      ```
      PS C:\> New-ADServiceAccount -Name "ExampleAccount" -DnsHostName "example-domain" -ServicePrincipalNames "host/ExampleAccount", "host/example-domain" -PrincipalsAllowedToRetrieveManagedPassword "ExampleAccountHosts"
      ```

   1. 使用永不过期的永久密码创建用户。这些凭证存储在 AWS Secrets Manager 中，每个任务都使用这些凭证来加入域。这是与上面创建的 gMSA 账户不同的用户账户。将 `ExampleServiceUser` 替换为您想要的此服务用户账户的名称。

      ```
      PS C:\> New-ADUser -Name "ExampleServiceUser" -AccountPassword (ConvertTo-SecureString -AsPlainText "Test123" -Force) -Enabled 1 -PasswordNeverExpires 1
      ```

   1. 

      ```
      PS C:\> Add-ADGroupMember -Identity "ExampleAccountHosts" -Members "ExampleServiceUser"
      ```

   1. 安装用于在 Active Directory 中创建 CredSpec 对象的 PowerShell 模块并输出 CredSpec JSON。

      ```
      PS C:\> Install-PackageProvider -Name NuGet -Force
      ```

      ```
      PS C:\> Install-Module CredentialSpec
      ```

   1. 

      ```
      PS C:\> New-CredentialSpec -AccountName ExampleAccount
      ```

1. 将前一个命令的 JSON 输出复制到名为 `gmsa-cred-spec.json` 的文件中。这是 CredSpec 文件。它在步骤 3 [步骤 3：修改您的 CredSpec JSON 以包含无域 gMSA 信息](#tutorial-gmsa-windows-step3) 中使用。

## 步骤 2：将凭证上传到 Secrets Manager
<a name="tutorial-gmsa-windows-step2"></a>

将 Active Directory 凭证复制到安全的凭证存储系统中，以便每个任务都能检索该凭证。这是无域 gMSA 方法。通过使用无域 gMSA，容器实例不会加入该域，实例上的其他应用程序无法使用凭证访问该域，并且加入不同域的任务可以在同一个实例上运行。

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。
+ 运行以下 AWS CLI 命令并替换用户名、密码和域名以匹配您的环境。使用服务用户账户名称（不是 gMSA 账户名称）作为用户名。保留密钥的 ARN 以便在下一步 [步骤 3：修改您的 CredSpec JSON 以包含无域 gMSA 信息](#tutorial-gmsa-windows-step3) 中使用

  以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

  ```
  $ aws secretsmanager create-secret \
  --name gmsa-plugin-input \
  --description "Amazon ECS - gMSA Portable Identity." \
  --secret-string "{\"username\":\"ExampleServiceUser\",\"password\":\"Test123\",\"domainName\":\"contoso.com\"}"
  ```

## 步骤 3：修改您的 CredSpec JSON 以包含无域 gMSA 信息
<a name="tutorial-gmsa-windows-step3"></a>

在将 CredSpec 上传到其中一个存储选项之前，请使用上一步中的 Secrets Manager 中的密钥 ARN 向 CredSpec 添加信息。有关更多信息，请参阅 Microsoft Learn 网站上的[非加入域的容器主机使用案例的其他凭证规范配置](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#additional-credential-spec-configuration-for-non-domain-joined-container-host-use-case)。

1. 将以下信息添加到 `ActiveDirectoryConfig` 内的 CredSpec 文件。将 ARN 替换为上一步中的 Secrets Manager 中的密钥。

   请注意，`PluginGUID` 值必须与以下示例代码段中的 GUID 相匹配，并且是必填项。

   ```
   "HostAccountConfig": {
         "PortableCcgVersion": "1",
         "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
         "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
   ```

   您也可以使用以下格式的 ARN 在 SSM Parameter Store 中使用密钥：`\"arn:aws:ssm:aws-region:111122223333:parameter/gmsa-plugin-input\"`。

1. CredSpec 文件修改后，应类似于以下示例：

   ```
   {
     "CmsPlugins": [
       "ActiveDirectory"
     ],
     "DomainJoinConfig": {
       "Sid": "S-1-5-21-4066351383-705263209-1606769140",
       "MachineAccountName": "ExampleAccount",
       "Guid": "ac822f13-583e-49f7-aa7b-284f9a8c97b6",
       "DnsTreeName": "example-domain",
       "DnsName": "example-domain",
       "NetBiosName": "example-domain"
     },
     "ActiveDirectoryConfig": {
       "GroupManagedServiceAccounts": [
         {
           "Name": "ExampleAccount",
           "Scope": "example-domain"
         },
         {
           "Name": "ExampleAccount",
           "Scope": "example-domain"
         }
       ],
       "HostAccountConfig": {
         "PortableCcgVersion": "1",
         "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
         "PluginInput": "{\"credentialArn\": \"arn:aws:secretsmanager:aws-region:111122223333:secret:gmsa-plugin-input\"}"
       }
     }
   }
   ```

## 步骤 4：将 CredSpec 上传到 Amazon S3
<a name="tutorial-gmsa-windows-step4"></a>



此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 将 CredSpec 文件复制到您正在其中运行 AWS CLI 命令的计算机或环境中。

1. 运行以下 AWS CLI 命令以将 CredSpec 上载到 Amazon S3。将 `MyBucket` 替换为您的 Amazon S3 存储桶的名称。您可以将文件作为对象存储在任何存储桶和位置，但您必须允许访问该存储桶和您附加到任务执行角色的策略中的位置。

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws s3 cp gmsa-cred-spec.json \
   s3://MyBucket/ecs-domainless-gmsa-credspec
   ```

## 步骤 5：（可选）创建 Amazon ECS 集群
<a name="tutorial-gmsa-windows-step5"></a>

默认情况下，您的账户有一个名为 `default` 的 Amazon ECS 集群。默认情况下，在 AWS CLI、SDK 和 CloudFormation 中使用此集群。您可以使用其他集群来分组和组织任务和基础设施，并为某些配置分配默认值。

您可以从 AWS 管理控制台、AWS CLI、SDK 或 CloudFormation 中创建集群。集群中的设置和配置不影响 gMSA。

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

```
$ aws ecs create-cluster --cluster-name windows-domainless-gmsa-cluster
```

**重要**  
如果您选择创建自己的集群，您必须为您打算用于该集群的每个命令指定 `--cluster clusterName`。

## 步骤 6：为容器实例创建 IAM 角色
<a name="tutorial-gmsa-windows-step6"></a>

*容器实例*是在 ECS 任务中运行容器的主机，例如 Amazon EC2 实例。每个容器实例都注册到 Amazon ECS 集群。在启动 Amazon EC2 实例并将其注册到集群之前，必须为容器实例创建 IAM 角色以供使用。

要创建容器实例角色，请参阅 [Amazon ECS 容器实例 IAM 角色](instance_IAM_role.md)。默认的 `ecsInstanceRole` 有足够的权限完成本教程。

## 步骤 7：创建自定义任务执行角色
<a name="tutorial-gmsa-windows-step7"></a>

Amazon ECS 可以使用不同的 IAM 角色来获得启动每项任务所需的权限，而不是容器实例角色。此角色称为*任务执行角色*。建议创建一个仅具有 ECS 运行任务所需的权限（也称为*最低权限*）的任务执行角色。有关最低权限原则的更多信息，请参阅 *AWS Well-Architected Framework* 中的 [SEC03-BP02 授予最低权限访问](https://docs.aws.amazon.com/wellarchitected/latest/framework/sec_permissions_least_privileges.html)。

1. 要创建任务执行角色，请参阅 [创建任务执行 角色](task_execution_IAM_role.md#create-task-execution-role)。默认权限允许容器实例从您的应用程序的 Amazon Elastic Container Registry and `stdout` 和 `stderr` 中提取容器映像，以将其记录到 Amazon CloudWatch Logs 中。

   由于该角色在本教程中需要自定义权限，因此您可以为该角色指定一个不同于 `ecsTaskExecutionRole` 的名称。本教程在后续步骤中使用 `ecsTaskExecutionRole`。

1. 通过创建自定义策略来添加以下权限，可以是仅存在于此角色中的内联策略，也可以是您可以重复使用的策略。将第一条语句中 `Resource` 的 ARN 替换为 Amazon S3 存储桶和位置，将第二个 `Resource` 替换为 Secrets Manager 中密钥的 ARN。

   如果您使用自定义密钥对 Secrets Manager 中的密钥进行加密，则还必须为该密钥允许 `kms:Decrypt`。

   如果您使用 SSM Parameter Store 而不是 Secrets Manager，则必须为该参数允许 `ssm:GetParameter`，而不是 `secretsmanager:GetSecretValue`。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::MyBucket/ecs-domainless-gmsa-credspec/gmsa-cred-spec.json"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:gmsa-plugin-AbCdEf"
           }
       ]
   }
   ```

------

## 步骤 8：为 Amazon ECS Exec 创建任务角色
<a name="tutorial-gmsa-windows-step8"></a>

本教程使用 Amazon ECS Exec 通过在正在运行的任务中运行命令来验证功能。要使用 ECS Exec，服务或任务必须开启 ECS Exec，并且任务角色（但不是任务执行角色）必须具有 `ssmmessages` 权限。有关所需的 IAM 策略，请参阅 [ECS Exec 权限](task-iam-roles.md#ecs-exec-required-iam-permissions)。

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

要使用 AWS CLI 创建任务角色，请执行以下步骤。

1. 使用以下内容创建名为 `ecs-tasks-trust-policy.json` 的文件：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "Service": "ecs-tasks.amazonaws.com"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. 创建 IAM 角色。您可以替换名称 `ecs-exec-demo-task-role`，但保留该名称以供后续步骤使用。

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws iam create-role --role-name ecs-exec-demo-task-role \
   --assume-role-policy-document file://ecs-tasks-trust-policy.json
   ```

   您可以删除文件 `ecs-tasks-trust-policy.json`。

1. 使用以下内容创建名为 `ecs-exec-demo-task-role-policy.json` 的文件：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ssmmessages:CreateControlChannel",
                   "ssmmessages:CreateDataChannel",
                   "ssmmessages:OpenControlChannel",
                   "ssmmessages:OpenDataChannel"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 创建 IAM 策略并将其附加到上一步的角色中。

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws iam put-role-policy \
       --role-name ecs-exec-demo-task-role \
       --policy-name ecs-exec-demo-task-role-policy \
       --policy-document file://ecs-exec-demo-task-role-policy.json
   ```

   您可以删除文件 `ecs-exec-demo-task-role-policy.json`。

## 步骤 9：注册一个使用无域 gMSA 的任务定义
<a name="tutorial-gmsa-windows-step9"></a>



此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 使用以下内容创建名为 `windows-gmsa-domainless-task-def.json` 的文件：

   ```
   {
     "family": "windows-gmsa-domainless-task",
     "containerDefinitions": [
       {
         "name": "windows_sample_app",
         "image": "mcr.microsoft.com/windows/servercore/iis",
         "cpu": 1024,
         "memory": 1024,
         "essential": true,
         "credentialSpecs": [
                   "credentialspecdomainless:arn:aws:s3:::ecs-domainless-gmsa-credspec/gmsa-cred-spec.json"
         ],
         "entryPoint": [
           "powershell",
           "-Command"
         ],
         "command": [
           "New-Item -Path C:\\inetpub\\wwwroot\\index.html -ItemType file -Value '<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.</p>' -Force ; C:\\ServiceMonitor.exe w3svc"
         ],
         "portMappings": [
           {
             "protocol": "tcp",
             "containerPort": 80,
             "hostPort": 8080
           }
         ]
       }
     ],
     "taskRoleArn": "arn:aws:iam::111122223333:role/ecs-exec-demo-task-role",
     "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole"
   }
   ```

1. 通过运行以下命令注册任务定义：

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws ecs register-task-definition \
   --cli-input-json file://windows-gmsa-domainless-task-def.json
   ```

## 步骤 10：将 Windows 容器实例注册到集群
<a name="tutorial-gmsa-windows-step10"></a>

启动 Amazon EC2 Windows 实例并运行 ECS 容器代理将其注册为集群中的容器实例。ECS 在注册到启动任务的集群的容器实例上运行任务。

1. 要启动在 AWS 管理控制台 中为 Amazon ECS 配置的 Amazon EC2 Windows 实例，请参阅 [启动 Amazon ECS Windows 容器实例](launch_window-container_instance.md)。在步骤中停下来获取*用户数据*。

1. 对于 gMSA，用户数据必须在启动 ECS 容器代理之前设置环境变量 `ECS_GMSA_SUPPORTED`。

   对于 ECS Exec，代理必须以参数 `-EnableTaskIAMRole` 开头。

   要通过阻止任务访问 EC2 IMDS Web 服务来检索角色凭证来保护实例 IAM 角色的安全，请添加参数 `-AwsvpcBlockIMDS`。这仅适用于使用 `awsvpc` 网络模式的任务。

   ```
   <powershell>
   [Environment]::SetEnvironmentVariable("ECS_GMSA_SUPPORTED", $TRUE, "Machine")
   Import-Module ECSTools
   Initialize-ECSAgent -Cluster windows-domainless-gmsa-cluster -EnableTaskIAMRole -AwsvpcBlockIMDS
   </powershell>
   ```

1. 查看 **Summary**（摘要）面板中您的实例配置的摘要，当您准备好后，选择 **Launch instance**（启动实例）。

## 步骤 11：验证容器实例
<a name="tutorial-gmsa-windows-step11"></a>

您可以使用 AWS 管理控制台 验证集群中是否有容器实例。但是，gMSA 需要以*属性*表示的其他功能。这些属性在 AWS 管理控制台 中不可见，因此本教程使用 AWS CLI。

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 列出集群中的容器实例。容器实例的 ID 与 EC2 实例的 ID 不同。

   ```
   $ aws ecs list-container-instances
   ```

   输出：

   ```
   {
       "containerInstanceArns": [
           "arn:aws:ecs:aws-region:111122223333:container-instance/default/MyContainerInstanceID"
       ]
   }
   ```

   例如，`526bd5d0ced448a788768334e79010fd` 是有效的容器实例 ID。

1. 使用上一步中的容器实例 ID 获取容器实例的详细信息。将 `MyContainerInstanceID` 替换为 ID。

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws ecs describe-container-instances \
        ----container-instances MyContainerInstanceID
   ```

   请注意，输出很长。

1. 验证 `attributes` 列表中是否有一个键名为 `name` 和值为 `ecs.capability.gmsa-domainless` 的对象。以下是对象的示例。

   输出：

   ```
   {
       "name": "ecs.capability.gmsa-domainless"
   }
   ```

## 步骤 12：运行 Windows 任务
<a name="tutorial-gmsa-windows-step12"></a>

运行 Amazon ECS 任务。如果集群中只有 1 个容器实例，则可以使用 `run-task`。如果有许多不同的容器实例，那么使用 `start-task` 和指定运行任务的容器实例 ID 可能比在任务定义中添加放置约束来控制在哪种类型的容器实例上运行该任务要容易得多。

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   aws ecs run-task --task-definition windows-gmsa-domainless-task \
       --enable-execute-command --cluster windows-domainless-gmsa-cluster
   ```

   记下该命令返回的任何 ID。

1. 运行以下命令验证任务是否已启动。此命令会等待，直到任务开始后才返回 shell 提示符。将 `MyTaskID` 替换为上一步中的任务 ID。

   ```
   $ aws ecs wait tasks-running --task MyTaskID
   ```

## 步骤 13：验证容器是否有 gMSA 凭证
<a name="tutorial-gmsa-windows-step13"></a>

验证任务中的容器是否有 Kerberos 令牌。gMSA

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws ecs execute-command \
   --task MyTaskID \
   --container windows_sample_app \
   --interactive \
   --command powershell.exe
   ```

   输出将是 PowerShell 提示符。

1. 在容器内的 PowerShell 终端中运行以下命令。

   ```
   PS C:\> klist get ExampleAccount$
   ```

   在输出中，请注意 `Principal` 是您之前创建的输出。

## 步骤 14：清除
<a name="tutorial-gmsa-windows-step14"></a>

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

此步骤使用 AWS CLI。您可以在默认 shell 的 AWS CloudShell 中运行这些命令，即 `bash`。

1. 停止任务。将 `MyTaskID` 替换为步骤 12 [步骤 12：运行 Windows 任务](#tutorial-gmsa-windows-step12) 中的任务 ID。

   ```
   $ aws ecs stop-task --task MyTaskID
   ```

1. 终止 Amazon EC2 实例。之后，集群中的容器实例将在一小时后自动删除。

   您可以使用 Amazon EC2 控制台查找和终止实例。或者，您可以运行以下命令。要运行该命令，请在步骤 1 [步骤 11：验证容器实例](#tutorial-gmsa-windows-step11) 的 `aws ecs describe-container-instances` 命令输出中找到 EC2 实例 ID。i-10a64379 是 EC2 实例 ID 的示例。

   ```
   $ aws ec2 terminate-instances --instance-ids MyInstanceID
   ```

1. 删除 Amazon S3 中的 CredSpec 文件。将 `MyBucket` 替换为您的 Amazon S3 存储桶的名称。

   ```
   $ aws s3api delete-object --bucket MyBucket --key ecs-domainless-gmsa-credspec/gmsa-cred-spec.json
   ```

1. 在 Secrets Manager 中删除密钥。如果您改用 SSM Parameter Store，请删除该参数。

   以下命令使用由 `sh` 和兼容的 shell 使用的反斜杠连续字符。此命令与 PowerShell 不兼容。您必须修改该命令才能将其与 PowerShell 配合使用。

   ```
   $ aws secretsmanager delete-secret --secret-id gmsa-plugin-input \
        --force-delete-without-recovery
   ```

1. 取消注册并删除任务定义。通过取消注册任务定义，可以将其标记为非活动状态，这样它就无法用于启动新任务。然后，您可以删除任务定义。

   1. 通过指定版本来取消注册任务定义。ECS 会自动生成任务定义的版本，这些版本从 1 开始编号。您可以按照与容器映像上的标签相同的格式来引用版本，例如 `:1`。

      ```
      $ aws ecs deregister-task-definition --task-definition windows-gmsa-domainless-task:1
      ```

   1. 删除任务定义。

      ```
      $ aws ecs delete-task-definitions --task-definition windows-gmsa-domainless-task:1
      ```

1. （可选）如果您创建了集群，请删除 ECS 集群。

   ```
   $ aws ecs delete-cluster --cluster windows-domainless-gmsa-cluster
   ```

## 调试适用于 Windows 容器的 Amazon ECS 无域 gMSA
<a name="tutorial-gmsa-windows-debugging"></a>



Amazon ECS 任务状态  
ECS 只会尝试启动任务一次。任何有问题的任务都将停止，并设置为状态 `STOPPED`。任务问题有两种常见类型。首先，是无法启动的任务。其次，应用程序已在其中一个容器内停止的任务。在 AWS 管理控制台 中，查看任务的**停止原因**字段中，了解任务停止的原因。在 AWS CLI 中，描述任务并查看 `stoppedReason`。有关 AWS 管理控制台 和 AWS CLI 中的步骤，请参阅 [查看 Amazon ECS 已停止任务错误](stopped-task-errors.md)。

Windows 事件  
容器中 gMSA 的 Windows 事件记录在 `Microsoft-Windows-Containers-CCG` 日志文件中，可以在 `Logs\Microsoft\Windows\Containers-CCG\Admin` 的“应用程序和服务”部分中的事件查看器中找到。有关更多调试技巧，请参阅 Microsoft Learn 网站上的[适用于 Windows 容器的 gMSA 的故障排除](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/gmsa-troubleshooting#non-domain-joined-container-hosts-use-event-logs-to-identify-configuration-issues)。

ECS 代理 gMSA 插件  
Windows 容器实例上的 ECS 代理的 gMSA 插件的日志位于以下目录 `C:/ProgramData/Amazon/gmsa-plugin/` 中。查看此日志，以了解无域用户凭证是否是从存储位置（例如 Secrets Manager）下载的，以及凭证格式是否正确读取。