

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 使用托管式节点组简化节点生命周期
<a name="managed-node-groups"></a>

Amazon EKS 托管节点组为 Amazon EKS Kubernetes 集群自动对节点（Amazon EC2 实例）进行预置和生命周期管理。

使用 Amazon EKS 托管节点组，您无需单独预置或注册 Amazon EC2 实例以提供计算容量来运行 Kubernetes 应用程序。您可以通过单个操作为集群创建、自动更新或终止节点。节点的更新和终止操作会自动耗尽节点，以确保您的应用程序保持为可用的状态。

所有托管节点均作为由 Amazon EKS 为您管理的 Amazon EC2 Auto Scaling 组的一部分进行预置。所有资源（包括实例和自动扩缩组在内）都在您的 AWS 账户中运行。每个节点组跨您定义的多个可用区运行。

托管式节点组还可以选择利用节点自动修复功能，从而持续监控节点的运行状况。此功能还会自动处理检测到的问题，并在可能的情况下替换节点。这有助于在尽可能减少手动干预的情况下提高集群的整体可用性。有关更多信息，请参阅 [检测节点运行状况问题并启用自动节点修复](node-health.md)。

您可以使用 Amazon EKS 控制台、`eksctl`、AWS CLI、AWS API 或基础设施即代码工具（包括 AWS CloudFormation），将托管式节点组添加到新的或现有集群中。作为托管节点组一部分启动的节点会自动进行标记，以便 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) 能自动发现这些节点。您可以使用节点组将 Kubernetes 标签应用到节点并随时更新它们。

使用 Amazon EKS 托管节点组没有额外的费用，您只需为预置的 AWS 资源付费。这些资源包括 Amazon EC2 实例、Amazon EBS 卷、Amazon EKS 集群小时数和任何其他 AWS 基础设施。无最低费用，无预先承诺。

要开始使用新 Amazon EKS 集群和托管节点组，请参阅 [开始使用 Amazon EKS – AWS 管理控制台和 AWS CLI](getting-started-console.md)。

要将托管节点组添加到现有集群，请参阅 [为集群创建托管式节点组](create-managed-node-group.md)。

## 托管节点组概念
<a name="managed-node-group-concepts"></a>
+ Amazon EKS 托管节点组为您创建和管理 Amazon EC2 实例。
+ 所有托管节点均作为由 Amazon EKS 为您管理的 Amazon EC2 Auto Scaling 组的一部分进行预置。此外，包括 Amazon EC2 实例和自动扩缩组在内的所有资源都在您的 AWS 账户中运行。
+ 托管节点组的弹性伸缩组涵盖您在创建组时指定的所有子网。
+ Amazon EKS 标记托管节点组资源，以便将其配置为使用 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)。
**重要**  
如果要使用 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) 在由 Amazon EBS 卷支持的多个可用区中运行有状态应用程序，则应该配置多个节点组，且每个节点组的范围都限定为一个可用区。此外，您还应该启用 `--balance-similar-node-groups` 功能。
+ 在部署托管节点时，可以使用自定义启动模板以获得更大灵活性和自定义性。例如，您可以指定额外的 `kubelet` 参数并使用自定义 AMI。有关更多信息，请参阅 [使用启动模板自定义托管式节点](launch-templates.md)。如果首次创建托管节点组时没有使用自定义启动模板，则会有自动生成的启动模板。不要手动修改此自动生成的模板，否则会发生错误。
+ Amazon EKS 在托管节点组上遵循 CVE 和安全补丁的责任共担模式。当托管节点运行 Amazon EKS 优化版 AMI 时，Amazon EKS 负责在报告 Bug 或问题时构建 AMI 的修补版本。我们可以发布修复程序。但是，您负责将这些修补的 AMI 版本部署到托管节点组。当托管节点运行自定义 AMI 时，您要负责在报告 Bug 或问题时构建 AMI 的修补版本，然后部署 AMI。有关更多信息，请参阅 [更新集群的托管式节点组](update-managed-node-group.md)。
+ Amazon EKS 托管节点组既可以在公有子网也可以在私有子网中启动。如果您在不早于 2020 年 4 月 22 日启动了公有子网中的托管节点组，则子网必须将 `MapPublicIpOnLaunch` 设置为 true，这些实例才能成功加入集群。如果公有子网是使用 `eksctl` 或 [Amazon EKS 发布的 AWS CloudFormation 模板](creating-a-vpc.md)并在 2020 年 3 月 26 日或之后创建的，则此设置已设置为 true。如果在 2020 年 3 月 26 日之前创建了公有子网，则必须手动更改设置。有关更多信息，请参阅[修改子网的公有 IPv4 寻址属性](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-public-ip)。
+ 在私有子网中部署托管节点组时，必须确保它可以访问 Amazon ECR 来拉取容器映像。您可以通过将 NAT 网关连接到子网的路由表或添加以下 [AWS PrivateLink VPC 端点](https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html#ecr-setting-up-vpc-create)来实现此目的：
  + Amazon ECR API 端点接口 – `com.amazonaws.region-code.ecr.api` 
  + Amazon ECR Docker 注册表 API 端点接口 – `com.amazonaws.region-code.ecr.dkr` 
  + Amazon S3 网关端点 – `com.amazonaws.region-code.s3` 

  有关其他常用服务和端点的信息，请参阅 [部署具有有限互联网访问权限的私有集群](private-clusters.md)。
+ 托管节点组无法部署在 [AWS Outposts](eks-outposts.md) 上或 [AWS Wavelength](https://docs.aws.amazon.com/wavelength/) 中。托管节点组现已可在 [AWS Local Zones](https://aws.amazon.com/about-aws/global-infrastructure/localzones/) 中创建。有关更多信息，请参阅 [使用 AWS Local Zones 启动低延迟 EKS 集群](local-zones.md)。
+ 您可以在单个集群中创建多个托管节点组。例如，您可以为某些工作负载使用标准的 Amazon EKS 优化版 Amazon Linux AMI 创建一个节点组，为需要 GPU 支持的工作负载使用 GPU 变体创建另一个节点组。
+ 如果您的托管节点组遇到 [Amazon EC2 实例状况检查](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html)失败，则 Amazon EKS 会返回错误代码来帮助您诊断问题。有关更多信息，请参阅 [托管节点组错误代码](troubleshooting.md#troubleshoot-managed-node-groups)。
+ Amazon EKS 将 Kubernetes 标签添加到托管节点组实例。Amazon EKS 提供的这些标签带有前缀 `eks.amazonaws.com`。
+ 在终止或更新期间，Amazon EKS 使用 Kubernetes API 自动耗尽节点。
+ 使用 `AZRebalance` 终止节点或减少所需节点数量时，未遵守容器组（pod）中断预算。这些操作试图驱逐节点上的容器组（pod）。但如果超过 15 分钟，则无论节点上的所有容器组（pod）是否都被终止，该节点都会终止。要将时间延长至节点终止，请向自动扩缩组添加生命周期挂钩。有关更多信息，请参阅《Amazon EC2 Auto Scaling 用户指南》**中的[添加生命周期挂钩](https://docs.aws.amazon.com/autoscaling/ec2/userguide/adding-lifecycle-hooks.html)。
+ 为了在收到 Spot 中断通知或容量再平衡通知后正确运行耗尽进程，必须将 `CapacityRebalance` 设置为 `true`。
+ 更新托管节点组遵循您为容器组（pod）设置的容器组（pod）中断预算。有关更多信息，请参阅 [了解节点更新的各个阶段](managed-node-update-behavior.md)。
+ 使用 Amazon EKS 托管节点组不会产生额外的费用。您仅需为预置的AWS资源付费。
+ 如果要为节点加密 Amazon EBS 卷，可以使用启动模板部署节点。要在不使用启动模板的情况下部署包含加密 Amazon EBS 卷的托管节点，必须对账户中创建的所有新 Amazon EBS 卷进行加密。有关更多信息，请参阅 *Amazon EC2 用户指南*中的[默认加密](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default)。

## 托管节点组容量类型
<a name="managed-node-group-capacity-types"></a>

创建托管节点组时，您可以选择按需容量或 Spot 容量类型。Amazon EKS 使用 Amazon EC2 Auto Scaling 组部署托管节点组，该组只包含按需实例或只包含 Amazon EC2 竞价型实例。您可以将容错应用程序的容器组（pod）调度到 Spot 托管节点组，将容错应用程序调度到单个 Kubernetes 集群中的按需节点组。预设情况下，托管节点组部署按需 Amazon EC2 实例。

### 按需
<a name="managed-node-group-capacity-types-on-demand"></a>

使用按需实例，您按秒为计算容量支付费用，无需长期订阅。

预设情况下，如果您没有指定**容量类型**，则会使用按需实例预置托管节点组。托管节点组会代表您配置 Amazon EC2 Auto Scaling 组，并应用以下设置：
+ 预置按需容量的分配策略设置为 `prioritized`。托管节点组使用实例类型在 API 中的传入顺序，确定在满足按需容量时首先使用哪种实例类型。例如，您可以按以下顺序指定三种实例类型：`c5.large`、`c4.large` 和 `c3.large`。在启动您的按需实例时，托管节点组满足按需容量的顺序是从 `c5.large` 开始，然后是 `c4.large`，再然后是 `c3.large`。有关更多信息，请参阅 *Amazon EC2 Auto Scaling 用户指南*中的 [Amazon EC2 Auto Scaling 组](https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-purchase-options.html#asg-allocation-strategies)。
+ Amazon EKS 会向您指定了容量类型的托管节点组中的所有节点添加以下 Kubernetes 标注：`eks.amazonaws.com/capacityType: ON_DEMAND`。您可以使用此标注在按需节点上调度有状态或不容错的应用程序。

### Spot
<a name="managed-node-group-capacity-types-spot"></a>

Amazon EC2 Spot 实例是备用的 Amazon EC2 容量，价格相当于在按需实例价格上打了巨大折扣。当 EC2 需要收回容量时，Amazon EC2 Spot 实例可能中断并发出一个两分钟的中断通知。有关更多信息，请参阅 *Amazon EC2 用户指南*中的[竞价型实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html)。您可以使用 Amazon EC2 Spot 实例配置托管节点组，以优化 Amazon EKS 集群中运行的计算节点的成本。

要在托管节点组中使用 Spot 实例，请将容量类型设置为 `spot`，创建托管节点组。托管节点组使用以下 Spot 最佳实践代表您配置 Amazon EC2 Auto Scaling 组：
+ 为确保在最佳 Spot 容量池中预置 Spot 节点，将分配策略设置为以下策略之一：
  +  `price-capacity-optimized`（PCO）– 在 Kubernetes `1.28` 版本或更高版本的集群中创建新节点组时，将分配策略设置为 `price-capacity-optimized`。但是，对于在 Amazon EKS 托管节点组开始支持 PCO 之前使用 `capacity-optimized` 创建的节点组，分配策略不会更改。
  +  `capacity-optimized`（CO）– 在 Kubernetes `1.27` 版本或更低版本的集群中创建新节点组时，将分配策略设置为 `capacity-optimized`。

  要增加可用于分配容量的 Spot 容量池的数量，请将托管节点组配置为使用多个实例类型。
+ 启用了 Amazon EC2 Spot 容量再平衡，以便 Amazon EKS 能够顺畅地耗尽和重新平衡您的 Spot 节点，从而在 Spot 节点中断风险增加时最大限度地减少应用程序中断。有关更多信息，请参阅 *Amazon EC2 Auto Scaling 用户指南*中的 [Amazon EC2 Auto Scaling 容量再平衡](https://docs.aws.amazon.com/autoscaling/ec2/userguide/capacity-rebalance.html)。
  + Spot 节点收到再平衡建议时，Amazon EKS 会自动尝试启动新的替换 Spot 节点。
  + 如果 Spot 两分钟中断通知在替换 Spot 节点进入 `Ready` 状态之前到达时间，Amazon EKS 将开始耗尽收到再平衡建议的 Spot 节点。Amazon EKS 会尽最大努力耗尽节点。因此，无法保证 Amazon EKS 会等待替换节点加入集群后再耗尽现有节点。
  + 当替换 Spot 节点引导启动并在 Kubernetes 中处于 `Ready` 状态后，Amazon EKS 将封锁并耗尽收到再平衡建议的 Spot 节点。封锁 Spot 节点可确保服务控制器不会向此 Spot 节点发送任何新请求。它还将其从其运行状况良好的活动 Spot 节点列表中删除。耗尽 Spot 节点可确保正在运行的容器组（pod）被自然地逐出。
+ Amazon EKS 会向您指定了容量类型的托管节点组中的所有节点添加以下 Kubernetes 标注：`eks.amazonaws.com/capacityType: SPOT`。您可以使用此标注在 Spot 节点上安排容错应用程序。
**重要**  
EC2 会在终止您的竞价型实例前两分钟发出[竞价型实例中断通知](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-instance-termination-notices.html)。但是，竞价型实例节点上的容器组（pod）可能无法获得完整的 2 分钟正常关闭时段。当 EC2 发出通知时，Amazon EKS 开始驱逐容器组（pod）之前会有延迟。驱逐按顺序进行，以保护 Kubernetes API 服务器，因此在同时进行多次竞价型实例回收期间，某些容器组（pod）可能会收到延迟驱逐的通知。容器组（pod）可能会在未接收到终止信号的情况下被强制终止，尤其是在高密度的容器组（pod）节点上、并发回收期间或使用较长的终止宽限期时。对于竞价型实例工作负载，建议将应用程序设计为可承受中断，使用 30 秒或更短的终止宽限期，避免长时间运行的 PreStop 钩子，并监控容器组（pod）驱逐指标以了解集群中的实际宽限期。对于需要保证正常终止的工作负载，建议改用按需容量。

在决定是部署具有按需容量还是 Spot 容量的节点组时，应考虑以下条件：
+ Spot 实例适合无状态、容错且灵活的应用程序。其中包括批处理和机器学习培训工作负载、大数据 ETL（例如 Apache Spark）、队列处理应用程序和无状态 API 端点。由于 Spot 是备用 Amazon EC2 容量，这些容量可能会随时间变化，因此我们建议您对可容忍中断的工作负载使用 Spot 容量。更具体地说，Spot 容量适合可以容忍所需容量不可用的时段的工作负载。
+ 我们建议您为不容错的应用程序使用 On-Demand。这包括集群管理工具，例如监控和操作工具，需要 `StatefulSets` 的部署，以及有状态的应用程序，如数据库。
+ 为了在使用 Spot 实例时最大限度地提高应用程序的可用性，我们建议您将 Spot 托管节点组配置为使用多个实例类型。我们建议在使用多个实例类型时应用以下规则：
  + 在托管节点组中，如果使用 [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)，我们建议使用具有相同数量 vCPU 和内存资源的灵活实例类型集。这是为了确保集群中的节点按预期进行扩缩。例如，如果需要 4 个 vCPU 和 8 GiB 内存，请使用 `c3.xlarge`、`c4.xlarge`、`c5.xlarge`、`c5d.xlarge`、`c5a.xlarge`、`c5n.xlarge` 或其他类似实例类型。
  + 为了提高应用程序可用性，我们建议部署多个 Spot 托管节点组。为此，每个组应使用一组具有相同 vCPU 和内存资源的灵活实例类型。例如，如果您需要 4 个 vCPU 和 8 GiB 内存，我们建议您使用 `c3.xlarge`、`c4.xlarge`、`c5.xlarge`、`c5d.xlarge`、`c5a.xlarge`、`c5n.xlarge` 或其他类似的实例类型创建一个托管节点组，并使用 `m3.xlarge`、`m4.xlarge`、`m5.xlarge`、`m5d.xlarge`、`m5a.xlarge`、`m5n.xlarge` 或其他类似的实例类型创建第二个托管节点组。
  + 用使用自定义启动模板的 Spot 容量类型部署节点组时，请使用 API 传递多个实例类型。不要通过启动模板传递单个实例类型。有关使用启动模板部署节点组的更多信息，请参阅 [使用启动模板自定义托管式节点](launch-templates.md)。

# 为集群创建托管式节点组
<a name="create-managed-node-group"></a>

本主题介绍了如何启动向 Amazon EKS 集群注册的节点的 Amazon EKS 托管节点组。在这些节点加入集群后，您可以向其部署 Kubernetes 应用程序。

如果这是您首次启动 Amazon EKS 托管节点组，建议您改为遵循[开始使用 Amazon EKS](getting-started.md)中的指南之一。这些指南提供了有关创建包含节点的 Amazon EKS 集群的演练。

**重要**  
Amazon EKS 节点是标准的 Amazon EC2 实例。将根据正常的 Amazon EC2 价格向您计费。有关更多信息，请参阅 [Amazon EC2 定价](https://aws.amazon.com/ec2/pricing/)。
您无法在启用了 AWS Outposts 或 AWS Wavelength 的 AWS 区域创建托管节点。您可以创建自行管理的节点。有关更多信息，请参阅 [创建自行管理的 Amazon Linux 节点](launch-workers.md)、[创建自主管理型 Microsoft Windows 节点](launch-windows-workers.md) 和 [创建自主管理型 Bottlerocket 节点](launch-node-bottlerocket.md)。您还可以在 Outpost 上创建自行管理的 Amazon Linux 节点组。有关更多信息，请参阅 [在 AWS Outpost 上创建 Amazon Linux 节点](eks-outposts-self-managed-nodes.md)。
如果您没有为包含在 Amazon EKS 优化版 Linux 或 Bottlerocket 中的 `bootstrap.sh` 文件[指定 AMI ID](launch-templates.md#launch-template-custom-ami)，则托管节点组会对 `maxPods` 的值强制实施最大数量。对于 vCPU 少于 30 个的实例，最大数量为 `110`。对于 vCPU 大于 30 个的实例，最大数量将跳至 `250`。此强制执行措施会覆盖其他 `maxPods` 配置，包括 `maxPodsExpression`。有关如何确定 `maxPods` 以及如何对其进行自定义的更多信息，请参阅 [如何确定 maxPods](choosing-instance-type.md#max-pods-precedence)。
+ 现有 Amazon EKS 集群。要部署一个角色，请参阅[创建一个 Amazon EKS 集群。](create-cluster.md)。
+ 供节点使用的现有 IAM 角色。要创建该文件，请参阅 [Amazon EKS 节点 IAM 角色](create-node-role.md)。如果此角色没有 VPC CNI 的任一策略，则需要为 VPC CNI Pod 使用随后的单独角色。
+ （可选，但推荐）适用于 Kubernetes 附加组件的 Amazon VPC CNI 插件已配置自己的 IAM 角色，并附加了必要的 IAM 策略。有关更多信息，请参阅 [配置 Amazon VPC CNI 插件以使用 IRSA](cni-iam-role.md)。
+ 熟悉[选择最优的 Amazon EC2 节点实例类型](choosing-instance-type.md)中列出的注意事项。根据您选择的实例类型，您的集群和 VPC 可能还有其他先决条件。
+ 要添加 Windows 托管节点组，必须先启用对集群的 Windows 支持。有关更多信息，请参阅 [在 EKS 集群上部署 Windows 节点](windows-support.md)。

您可以使用以下任一途径创建托管节点组：
+  [`eksctl`](#eksctl_create_managed_nodegroup) 
+  [AWS 管理控制台](#console_create_managed_nodegroup) 

## `eksctl`
<a name="eksctl_create_managed_nodegroup"></a>

 **使用 eksctl 创建托管节点组** 

此过程需要 `eksctl` 版本 `0.215.0` 或更高版本。可以使用以下命令来查看您的版本：

```
eksctl version
```

有关安装或升级 `eksctl` 的说明，请参阅 `eksctl` 文档中的 [Installation](https://eksctl.io/installation)。

1. （可选）如果 **AmazonEKS\$1CNI\$1Policy** 托管的 IAM 策略附加到 [Amazon EKS 节点 IAM 角色](create-node-role.md)，我们建议将其分配给您与 Kubernetes `aws-node` 服务账户关联的 IAM 角色。有关更多信息，请参阅 [配置 Amazon VPC CNI 插件以使用 IRSA](cni-iam-role.md)。

1. 使用或不使用自定义启动模板创建托管节点组。手动指定启动模板可允许对节点组进行更好的自定义。例如，它可以允许部署自定义 AMI 或向 Amazon EKS 优化的 AMI 中的 `boostrap.sh` 脚本提供参数。要查看所有可用选项和原定设置的完整列表，请输入以下命令。

   ```
   eksctl create nodegroup --help
   ```

   在以下命令中，将 *my-cluster* 替换为您的集群名称，并将 *my-mng* 替换为您的节点组名称。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头，但也可以包括其余字符的连字符和下划线。
**重要**  
如果首次创建托管节点组时没有使用自定义启动模板，则以后不要对节点组使用模板。如果没有指定自定义启动模板，系统会自动生成启动模板，我们不建议您手动修改该模板。手动修改此自动生成的启动模板可能会导致错误。

 **不使用启动模板** 

 `eksctl` 在您的账户中创建默认的 Amazon EC2 启动模板，并使用它根据您指定的选项创建的启动模板来部署节点组。在为 `--node-type` 指定值之前，请参阅 [选择最优的 Amazon EC2 节点实例类型](choosing-instance-type.md)。

将 *ami-family* 替换为允许的关键字。有关更多信息，请参阅 `eksctl` 文档中的 [Setting the node AMI Family](https://eksctl.io/usage/custom-ami-support/#setting-the-node-ami-family)（设置节点 AMI 系列）。将 *my-key* 替换为您的 Amazon EC2 密钥对或公有密钥的名称。此密钥用于在节点启动后通过 SSH 进入节点。

**注意**  
对于 Windows，此命令不会启用 SSH。反之，它会将 Amazon EC2 密钥对与实例关联，并允许您 RDP 到实例中。

如果还没有 Amazon EC2 密钥对，可以在 AWS 管理控制台 中创建一个。有关 Linux 信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EC2 密钥对和 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。有关 Windows 信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EC2 密钥对和 Windows 实例](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-key-pairs.html)。

如果满足以下条件，我们建议阻止容器组（pod）访问 IMDS：
+ 您计划将 IAM 角色分配给所有 Kubernetes 服务账户，以便容器组（pod）仅具有其所需的最低权限。
+ 集群中没有任何容器组（pod）需要出于其他原因（例如检索当前 AWS 区域）访问 Amazon EC2 实例元数据服务（IMDS）。

有关更多信息，请参阅[限制对分配给工作节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。

如果要阻止容器组（pod）访问 IMDS，请将 `--disable-pod-imds` 选项添加到以下命令。

```
eksctl create nodegroup \
  --cluster my-cluster \
  --region region-code \
  --name my-mng \
  --node-ami-family ami-family \
  --node-type m5.large \
  --nodes 3 \
  --nodes-min 2 \
  --nodes-max 4 \
  --ssh-access \
  --ssh-public-key my-key
```

实例可以选择为容器组（pod）分配更多 IP 地址，为其他 CIDR 块（而不是实例的 CIDR 块）中的容器组（pod）分配 IP 地址，并将其部署到没有互联网访问的集群。有关更多信息，请参阅 [为带前缀的 Amazon EKS 节点分配更多 IP 地址](cni-increase-ip-addresses.md)、[使用自定义网络在备用子网中部署容器组（pod）](cni-custom-network.md) 和 [部署具有有限互联网访问权限的私有集群](private-clusters.md)，以获取要添加到上一个命令中的其他选项。

托管节点组将根据实例类型计算并应用单个值，以作为可以在节点组的每个节点上运行的最大容器组（pod）数量。如果创建具有不同实例类型的节点组，则在所有实例类型中计算得出的最小值将应用为可以在节点组中每种实例类型上运行的最大容器组（pod）数量。托管节点组会使用 中引用的脚本计算值。

 **使用启动模板** 

启动模板必须已存在，并且必须满足[启动模板配置基础知识](launch-templates.md#launch-template-basics)中指定的要求。如果满足以下条件，我们建议阻止容器组（pod）访问 IMDS：
+ 您计划将 IAM 角色分配给所有 Kubernetes 服务账户，以便容器组（pod）仅具有其所需的最低权限。
+ 集群中没有任何容器组（pod）需要出于其他原因（例如检索当前 AWS 区域）访问 Amazon EC2 实例元数据服务（IMDS）。

有关更多信息，请参阅[限制对分配给工作节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。

如果要阻止容器组（pod）访问 IMDS，请在启动模板中指定必要的设置。

1. 将以下内容复制到您的设备。替换示例值，然后运行修改后的命令以创建 `eks-nodegroup.yaml` 文件。在不使用启动模板的情况下进行部署时指定的多个设置将移动到启动模板中。如果未指定 `version`，则使用模板的默认版本。

   ```
   cat >eks-nodegroup.yaml <<EOF
   apiVersion: eksctl.io/v1alpha5
   kind: ClusterConfig
   metadata:
     name: my-cluster
     region: region-code
   managedNodeGroups:
   - name: my-mng
     launchTemplate:
       id: lt-id
       version: "1"
   EOF
   ```

   有关 `eksctl` 配置文件设置的完整列表，请参阅 `eksctl` 文档中的[配置文件架构](https://eksctl.io/usage/schema/)。实例可以选择将更多的 IP 地址分配到容器组（pod），将 IP 地址分配到其他 CIDR 块（而不是实例的 CIDR 块）中的容器组（pod），并将其部署到没有出站互联网访问的集群。有关更多信息，请参阅[为带前缀的 Amazon EKS 节点分配更多 IP 地址](cni-increase-ip-addresses.md)、[使用自定义网络在备用子网中部署容器组（pod）](cni-custom-network.md)和[部署具有有限互联网访问权限的私有集群](private-clusters.md)，以获取添加到配置文件的其他选项。

   如果没有在启动模板中指定 AMI ID，则托管节点组将根据实例类型计算并应用单个值，以作为可以在节点组的每个节点上运行的最大容器组（pod）数量。如果创建具有不同实例类型的节点组，则在所有实例类型中计算得出的最小值将应用为可以在节点组中每种实例类型上运行的最大容器组（pod）数量。托管节点组会使用 中引用的脚本计算值。

   如果在启动模板中指定了 AMI ID，请指定可以在节点组的每个节点上运行的最大容器组（pod）数量（如果您使用的是[自定义网络](cni-custom-network.md)或者想要[增加分配给实例的 IP 地址数量](cni-increase-ip-addresses.md)）。有关更多信息，请参阅 。

1. 使用以下命令部署节点组。

   ```
   eksctl create nodegroup --config-file eks-nodegroup.yaml
   ```

## AWS 管理控制台
<a name="console_create_managed_nodegroup"></a>

 **使用 AWS 管理控制台创建托管节点组** 

1. 等待集群状态显示为 `ACTIVE`。无法为状态尚未处于 `ACTIVE` 的集群创建托管节点组。

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 选择要在其中创建托管节点组的集群的名称。

1. 选择 **Compute**（计算）选项卡。

1. 请选择 **Add node group**（添加节点组）。

1. 在 **Configure node group (配置节点组)** 页面上，填写相应参数，然后选择 **Next (下一步)**。
   +  **名称** – 为托管节点组输入唯一名称。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头，但也可以包括其余字符的连字符和下划线。
   +  **节点 IAM 角色** – 选择要与节点组一起使用的节点实例角色。有关更多信息，请参阅 [Amazon EKS 节点 IAM 角色](create-node-role.md)。
**重要**  
您不能使用创建任何集群时使用的相同角色。
我们建议使用任何自行管理节点组当前未使用的角色。否则，计划与新的自行管理节点组配合使用。有关更多信息，请参阅 [从集群中删除托管式节点组](delete-managed-node-group.md)。
   +  **使用启动模板** -（可选）选择是否要使用现有启动模板。选择 **Launch Template Name**（启动模板名称）。然后，选择 **Launch template version**（启动模板版本）。如果您未选择版本，Amazon EKS 将使用模板的默认版本。启动模板允许您对节点组进行更多自定义，例如允许您部署自定义 AMI、将更多的 IP 地址分配给容器组（pod）、将 IP 地址分配给其他 CIDR 块（而不是实例的 CIDR 块）中的容器组（pod），并将节点部署到没有出站互联网访问的集群。有关更多信息，请参阅 [为带前缀的 Amazon EKS 节点分配更多 IP 地址](cni-increase-ip-addresses.md)、[使用自定义网络在备用子网中部署容器组（pod）](cni-custom-network.md) 和 [部署具有有限互联网访问权限的私有集群](private-clusters.md)。

     启动模板必须满足中的[使用启动模板自定义托管式节点](launch-templates.md)中的要求。如果您不使用自己的启动模板，Amazon EKS API 会在您的账户中创建默认 Amazon EC2 启动模板，并使用默认启动模板部署节点组。

     如果实施[服务账户的 IAM 角色](iam-roles-for-service-accounts.md)，请将必要的权限直接分配给需要访问 AWS 服务的所有容器组（pod）。如果集群中没有容器组（pod）出于其他原因（例如检索当前 AWS 区域）而需要访问 IMDS，您还可以在启动模板中为不使用主机网络的容器组（pod）禁用 IMDS 的访问权限。有关更多信息，请参阅[限制对分配给工作节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。
   +  **Kubernetes 标签** –（可选）您可以选择对托管节点组中的节点应用 Kubernetes 标签。
   +  **Kubernetes 污点** –（可选）您可以选择对托管节点组中的节点应用 Kubernetes 污点。**Effect**（效果）菜单中的可用选项包括 ` NoSchedule `、` NoExecute ` 和 ` PreferNoSchedule `。有关更多信息，请参阅 [方案：防止在特定节点上调度容器组（pod）](node-taints-managed-node-groups.md)。
   +  **标签** –（可选）您可以选择对 Amazon EKS 托管节点组进行标记。这些标签不会传播到节点组中的其它资源，例如自动扩缩组或实例。有关更多信息，请参阅 [使用标签整理 Amazon EKS 资源](eks-using-tags.md)。

1. 在 **Set compute and scaling configuration（设置计算和扩展配置）**页面上，填写相应参数，然后选择 **Next（下一步）**。
   +  **AMI 类型** – 选择一个 AMI 类型。如果要部署 Arm 实例，请务必在部署前查看 [Amazon EKS 优化版 Arm Amazon Linux AMI](eks-optimized-ami.md#arm-ami) 中的注意事项。

     如果您在上一页指定了启动模板，并在启动模板中指定了 AMI，则无法选择值。此时将显示模板中的值。模板中指定的 AMI 必须满足[指定 AMI](launch-templates.md#launch-template-custom-ami) 中的要求。
   +  **容量类型** – 选择容量类型。有关选择容量类型的更多信息，请参阅 [托管节点组容量类型](managed-node-groups.md#managed-node-group-capacity-types)。不能在同一节点组中混合使用不同的容量类型。如果要同时使用这两种容量类型，请创建单独的节点组，每个节点组都有自己的容量和实例类型。有关预置和扩展由 GPU 加速的 Worker 节点的信息，请参阅[为托管节点组预留 GPU](https://docs.aws.amazon.com/eks/latest/userguide/capacity-blocks-mng.html)。
   +  **实例类型** – 默认指定一个或多个实例类型。要删除默认实例类型，请选择实例类型右侧的 `X`。选择要在托管节点组中使用的实例类型。有关更多信息，请参阅 [选择最优的 Amazon EC2 节点实例类型](choosing-instance-type.md)。

     控制台显示一组常用的实例类型。如果需要使用未显示的实例类型创建托管节点组，请使用 `eksctl`、AWS CLI、AWS CloudFormation 或 SDK 创建节点组。如果在上一页指定了启动模板，则无法选择值，因为必须在启动模板中指定实例类型。将显示启动模板中的值。如果为**容量类型**选择了 **Spot 实例**，我们建议您指定多个实例类型以增强可用性。
   +  **磁盘大小** – 输入要用于节点根卷的磁盘大小（单位为 GiB）。

     如果在上一页指定了启动模板，则无法选择值，因为必须在启动模板中指定该值。
   +  **所需大小** – 指定托管节点组在启动时应当维持的当前节点数量。
**注意**  
Amazon EKS 不会自动扩展或缩减节点组。但是，您可以配置 Kubernetes Cluster Autoscaler 来为您执行此操作。有关更多信息，请参阅 [AWS 上的 Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)。
   +  **最小大小** – 指定托管节点组可以横向缩减到的最小节点数量。
   +  **最大大小** – 指定托管节点组可以横向扩展到的最大节点数量。
   +  **节点组更新配置** –（可选）您可以选择要并行更新的节点的数量或百分比。这些节点在更新期间将不可用。对于**最大不可用**，选择下列选项之一，然后指定一个**值**：
     +  **Number**（数字）– 选择并指定节点组中可以并行更新的节点数。
     +  **Percentage**（百分比）– 选择并指定节点组中可并行更新的节点的百分比。如果您的节点组中有大量节点，这将非常有用。
   +  **节点自动修复配置** –（可选）如果您激活了**启用节点自动修复**复选框，Amazon EKS 将在检测到问题时自动替换节点。有关更多信息，请参阅 [检测节点运行状况问题并启用自动节点修复](node-health.md)。

1. 在 **Specify networking（指定联网）**页面上，相应填写参数，然后选择 **Next（下一步）**。
   +  **子网** – 选择要在其中启动托管节点的子网。
**重要**  
如果要使用 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) 在由 Amazon EBS 卷支持的多个可用区中运行有状态应用程序，则应该配置多个节点组，且每个节点组的范围都限定为一个可用区。此外，您还应该启用 `--balance-similar-node-groups` 功能。
**重要**  
如果您选择公有子网，并且您的集群仅启用公有 API 服务器端点，则子网必须将 `MapPublicIPOnLaunch` 设置为 `true`，实例才能成功加入集群。如果子网是使用 `eksctl` 或 [Amazon EKS 发布的 AWS CloudFormation 模板](creating-a-vpc.md)在 2020 年 3 月 26 日或之后创建的，则此设置已设置为 `true`。如果子网是在 2020 年 3 月 26 日之前使用 `eksctl` 或 AWS CloudFormation 模板创建的，则需要手动更改设置。有关更多信息，请参阅[修改子网的公有 IPv4 寻址属性](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-public-ip)。
如果使用启动模板并指定多个网络接口，即使 `MapPublicIpOnLaunch` 设置 `true`，Amazon EC2 也不会自动分配公有 `IPv4` 地址。在这种情况下，要让节点加入集群，您必须启用集群的私有 API 服务器端点，或者在具有出站 Internet 访问的私有子网中启动节点（Internet 访问通过如 NAT 网关等其它方法提供）。有关更多信息，请参阅 *Amazon EC2 用户指南*中的 [Amazon EC2 实例 IP 寻址](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html)。
   +  **Configure SSH access to nodes**（配置对节点的 SSH 访问）（可选）。启用 SSH 后，如果出现问题，您可以连接到实例并收集诊断信息。我们强烈建议您在创建节点组时启用远程访问。创建节点组后，将无法启用远程访问。

     如果您选择使用启动模板，则不会显示此选项。要启用对节点的远程访问，请在启动模板中指定密钥对，并确保为您在启动模板中指定的安全组中的节点打开正确的端口。有关更多信息，请参阅 [使用自定义安全组](launch-templates.md#launch-template-security-groups)。
**注意**  
对于 Windows，此命令不会启用 SSH。反之，它会将 Amazon EC2 密钥对与实例关联，并允许您 RDP 到实例中。
   + 对于 **SSH 密钥对**（可选），请选择要使用的 Amazon EC2 SSH 密钥。有关 Linux 信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EC2 密钥对和 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。有关 Windows 信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EC2 密钥对和 Windows 实例](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-key-pairs.html)。如果您选择使用启动模板，则无法选择密钥对。使用 Bottlerocket AMI 为节点组提供 Amazon EC2 SSH 密钥后，还启用管理容器。有关更多信息，请参阅 GitHub 上的 [Admin 容器](https://github.com/bottlerocket-os/bottlerocket#admin-container)。
   + 对于 **Allow SSH remote access from**（允许来自以下的远程访问），如果要限制对特定实例的访问，请选择与这些实例关联的安全组。如果没有选择特定的安全组，则允许从 Internet 上的任何位置进行 SSH 访问（`0.0.0.0/0`）。

1. 在 **Review and create (审核并创建)** 页面上，审核托管节点组配置并选择 **Create (创建)**。

   如果节点无法加入集群，则请参阅故障排除一章中的 [节点未能加入集群](troubleshooting.md#worker-node-fail)。

1. 查看节点的状态并等待它们达到 `Ready` 状态。

   ```
   kubectl get nodes --watch
   ```

1. （仅限 GPU 节点）如果选择 GPU 实例类型和 Amazon EKS 优化版加速型 AMI，则必须将[适用于 Kubernetes 的 NVIDIA 设备插件](https://github.com/NVIDIA/k8s-device-plugin)用作集群上的 DaemonSet。将 *vX.X.X* 替换为您需要的 [NVIDIA/k8s-device-plugin](https://github.com/NVIDIA/k8s-device-plugin/releases) 版本，然后运行以下命令。

   ```
   kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/vX.X.X/deployments/static/nvidia-device-plugin.yml
   ```

## 安装 Kubernetes 附加组件
<a name="_install_kubernetes_add_ons"></a>

现在，您已有使用节点运行的 Amazon EKS 集群，那么就可以准备开始安装 Kubernetes 附加组件并将应用程序部署到集群。以下文档主题可帮助您扩展集群的此功能。
+ 创建集群的 [IAM 主体](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-principal)是唯一可以使用 `kubectl` 或 AWS 管理控制台 调用 Kubernetes API 服务器的主体。如果您希望其他 IAM 主体拥有访问您的集群的权限，您需要添加它们。有关更多信息，请参阅[向 IAM 用户和角色授予对 Kubernetes API 的访问权限](grant-k8s-access.md)和[所需的权限](view-kubernetes-resources.md#view-kubernetes-resources-permissions)。
+ 如果满足以下条件，我们建议阻止容器组（pod）访问 IMDS：
  + 您计划将 IAM 角色分配给所有 Kubernetes 服务账户，以便容器组（pod）仅具有其所需的最低权限。
  + 集群中没有任何容器组（pod）需要出于其他原因（例如检索当前 AWS 区域）访问 Amazon EC2 实例元数据服务（IMDS）。

  有关更多信息，请参阅[限制对分配给 Worker 节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。
+ 配置 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) 以自动调整节点组中的节点数。
+ 将[示例应用程序](sample-deployment.md)部署到您的集群。
+  使用管理集群的重要工具来[组织和监控集群资源](eks-managing.md)。

# 更新集群的托管式节点组
<a name="update-managed-node-group"></a>

启动托管节点组更新后，Amazon EKS 会自动更新您的节点，完成[了解节点更新的各个阶段](managed-node-update-behavior.md)中列出的步骤。如果您使用的是 Amazon EKS 优化版 AMI，Amazon EKS 会自动将最新的安全补丁和操作系统更新应用到您的节点，作为最新 AMI 版本的一部分。

在几种情况下，需要更新 Amazon EKS 托管节点组的版本或配置：
+ 您已更新 Amazon EKS 集群的 Kubernetes 版本，并且您希望更新节点以使用相同 Kubernetes 版本。
+ 新 AMI 发行版本可用于您的托管节点组。有关 AMI 版本的更多信息，请参阅以下章节：
  +  [检索 Amazon Linux AMI 版本信息](eks-linux-ami-versions.md) 
  +  [使用优化版 Bottlerocket AMI 创建节点](eks-optimized-ami-bottlerocket.md) 
  +  [检索 Windows AMI 版本信息](eks-ami-versions-windows.md) 
+ 您希望调整托管节点组中的最少、最多或所需实例数。
+ 您希望对托管节点组中的实例添加或删除 Kubernetes 标签。
+ 您希望对托管节点组添加或删除 AWS 标签。
+ 您需要部署包含配置更改（如更新的自定义 AMI）的最新版本启动模板。
+ 您已部署了版本 `1.9.0` 或更高版本的 Amazon VPC CNI 附加组件，启用了前缀委派附加组件，并希望节点组中的新 AWS Nitro 实例支持数量显著增加的容器组（pod）。有关更多信息，请参阅 [为带前缀的 Amazon EKS 节点分配更多 IP 地址](cni-increase-ip-addresses.md)。
+ 您已为 Windows 节点启用了 IP 前缀委派，并希望节点组中的新 AWS Nitro System 实例支持数量显著增加的容器组（pod）。有关更多信息，请参阅 [为带前缀的 Amazon EKS 节点分配更多 IP 地址](cni-increase-ip-addresses.md)。

如果有相比您托管节点组的 Kubernetes 版本更新的 AMI 发行版，则可以将您节点组的版本更新为使用较新的 AMI 版本。同理，如果集群运行的 Kubernetes 版本比节点组更新，则可以将节点组更新为使用与集群 Kubernetes 版本匹配的最新 AMI 发行版。

如果托管节点组中的节点因扩展操作或更新而终止，则会先耗尽该节点中的容器组（pod）。有关更多信息，请参阅 [了解节点更新的各个阶段](managed-node-update-behavior.md)。

## 更新节点组版本
<a name="mng-update"></a>

您可以使用以下任一方式更新节点组版本：
+  [`eksctl`](#eksctl_update_managed_nodegroup) 
+  [AWS 管理控制台](#console_update_managed_nodegroup) 

您更新到的版本不能高于控制面板的版本。

## `eksctl`
<a name="eksctl_update_managed_nodegroup"></a>

 **使用 `eksctl` 更新托管节点组** 

使用以下命令，将托管节点组更新到节点上当前部署的相同 Kubernetes 版本的最新 AMI 版本。将所有 *example value* 替换为您自己的值。

```
eksctl upgrade nodegroup \
  --name=node-group-name \
  --cluster=my-cluster \
  --region=region-code
```

**注意**  
如果要将使用启动模板部署的节点组升级到新的启动模板版本，请将 `--launch-template-version version-number ` 添加到上述命令。启动模板必须满足[使用启动模板自定义托管节点](launch-templates.md)中所述的要求。如果启动模板包含自定义 AMI，则 AMI 必须满足[指定 AMI](launch-templates.md#launch-template-custom-ami) 中的要求。将节点组升级到启动模板的更新版本后，将回收所有节点，以匹配指定的启动模板版本的新配置。

您不能将未使用启动模板部署的节点组直接升级到新的启动模板版本。相反，您必须使用启动模板部署新的节点组，以将节点组更新为新的启动模板版本。

您可以将节点组升级到与控制面板的 Kubernetes 版本相同的版本。例如，如果您的集群运行 Kubernetes `1.35`，则您可以使用以下命令，将当前运行 Kubernetes `1.34` 的节点升级到版本 `1.35`。

```
eksctl upgrade nodegroup \
  --name=node-group-name \
  --cluster=my-cluster \
  --region=region-code \
  --kubernetes-version=1.35
```

## AWS 管理控制台
<a name="console_update_managed_nodegroup"></a>

 **要使用 AWS 管理控制台创建托管节点组** 

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 选择包含要更新的节点组的集群。

1. 如果至少有一个节点组具有可用更新，则页面顶部将出现一个提示框，通知存在可用的更新。如果选择**计算**选项卡，则在具有可用更新的节点组的**节点组**表中，**AMI 发行版本**列会显示**立即更新**。要更新节点组，请选择 **Update now**（立即更新）。

   对于使用自定义 AMI 部署的节点组，不会显示通知。如果您的节点是使用自定义 AMI 部署的，请完成以下步骤以部署更新的自定义 AMI。

   1. 创建 AMI 的新版本。

   1. 使用新 AMI ID 创建新的启动模板版本。

   1. 将节点升级到新版本的启动模板。

1. 在 **Update node group version**（更新节点组版本）对话框中，激活或停用以下选项：
   +  **Update node group version**（更新节点组版本）：如果您部署了自定义 AMI，或者您的 Amazon EKS 优化版 AMI 当前位于集群的最新版本上，则此选项不可用。
   +  **Change launch template version**（更改启动模板版本）：如果部署节点组时没有使用自定义启动模板，则此选项不可用。您只能更新已使用自定义启动模板部署的节点组的启动模板版本。选择要将节点组更新到的 **Launch template version**（启动模板版本）。如果您的节点组配置了自定义 AMI，则您选择的版本还必须指定 AMI。升级到更新版本的启动模板后，所有节点都会被回收，以匹配指定的启动模板版本的新配置。

1. 对于 **Update strategy**（更新策略），选择下列选项之一：
   +  **滚动更新** – 此选项会考虑集群的容器组（pod）中断预算。如果容器组（pod）中断预算问题导致 Amazon EKS 无法正常耗尽在此节点组上运行的容器组（pod），则更新将失败。
   +  **强制更新** – 此选项不考虑容器组（pod）中断预算。通过强制节点重新启动，无论是否存在容器组（pod）中断预算问题，都会发生更新。

1. 选择**更新**。

## 编辑节点组配置
<a name="mng-edit"></a>

您可以修改托管节点组的某些配置。

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 选择包含要编辑的节点组的集群。

1. 选择**计算**选项卡。

1. 选择要编辑的节点组，然后选择 **Edit**（编辑）。

1. （可选）在**编辑节点组**页面上，执行以下操作：

   1. 编辑 **Node group scaling configuration**（节点组扩展配置）。
      +  **所需大小** – 指定托管节点组应当维持的当前节点数量。
      +  **最小大小** – 指定托管节点组可以横向缩减到的最小节点数量。
      +  **最大大小** – 指定托管节点组可以横向扩展到的最大节点数量。有关节点组中支持的最大节点数，请参阅 [查看和管理 Amazon EKS 和 Fargate 服务配额](service-quotas.md)。

   1. （可选）向节点组中的节点添加或删除 **Kubernetes 标签**。此处显示的标签仅为已应用于 Amazon EKS 的标签。节点上可能存在此处未显示的其它标签。

   1. （可选）向节点组中的节点添加或删除 **Kubernetes 污点**。添加的污点可以具有 ` NoSchedule `、` NoExecute ` 或 ` PreferNoSchedule ` 效果。有关更多信息，请参阅 [方案：防止在特定节点上调度容器组（pod）](node-taints-managed-node-groups.md)。

   1. （可选）向节点组资源添加或删除 **Tags**（标签）。这些标签仅应用于 Amazon EKS 节点组。这些标签不会传播到其它资源，例如节点组中的子网或 Amazon EC2 实例。

   1. （可选）编辑**节点组更新配置**。选择**数字**或**百分比**。
      +  **Number**（数字）– 选择并指定节点组中可以并行更新的节点数。这些节点在更新过程中将不可用。
      +  **Percentage**（百分比）– 选择并指定节点组中可并行更新的节点的百分比。这些节点在更新过程中将不可用。如果您的节点组中有大量节点，这将非常有用。

   1. 编辑完成后，选择**保存更改**。

**重要**  
更新节点组配置时，修改 [https://docs.aws.amazon.com/eks/latest/APIReference/API_NodegroupScalingConfig.html](https://docs.aws.amazon.com/eks/latest/APIReference/API_NodegroupScalingConfig.html) 不会考虑容器组（pod）中断预算（PDB）。与[更新节点组](managed-node-update-behavior.md)进程（在升级阶段耗尽节点并考虑 PDB）不同，更新扩展配置会导致通过自动扩缩组（ASG）缩减调用立即终止节点。这种情况在不考虑 PDB 的情况下发生，无论缩减到什么目标大小。这意味着，当您减少 Amazon EKS 托管节点组的 `desiredSize` 时，只要节点终止，容器组（pod）就会立即被驱逐，而不考虑任何 PDB。

# 了解节点更新的各个阶段
<a name="managed-node-update-behavior"></a>

Amazon EKS 托管 Worker 节点升级策略有四个不同的阶段，将在以下各节中介绍。

## 设置阶段
<a name="managed-node-update-set-up"></a>

设置阶段有以下步骤：

1. 为与节点组关联的自动扩缩组创建新的 Amazon EC2 启动模板版本。新的启动模板版本使用目标 AMI 或自定义启动模板版本进行更新。

1. 对自动扩缩组进行更新，以便使用最新的启动模板版本。

1. 使用节点组的 `updateConfig` 属性确定要并行升级的节点最大数量。最大不可用的配额为 100 个节点。原定设置值为一个节点。有关更多信息，请参阅《Amazon EKS API 参考》**中的 [updateConfig](https://docs.aws.amazon.com/eks/latest/APIReference/API_UpdateNodegroupConfig.html#API_UpdateNodegroupConfig_RequestSyntax) 属性。

## 扩展阶段
<a name="managed-node-update-scale-up"></a>

升级托管节点组中的节点时，已升级的节点将在与正在升级的节点在相同可用区中启动。为了保证这一点，我们使用 Amazon EC2 的可用区重新平衡。有关更多信息，请参阅 *Amazon EC2 Auto Scaling 用户指南*的[可用区重新平衡](https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-benefits.html#AutoScalingBehavior.InstanceUsage)。为了满足此要求，将为托管节点组中的每个可用区启动最多两个实例。

扩展阶段有以下步骤：

1. 它增加自动扩缩组的最大大小和所需大小，增加幅度为以下两者中的较大者：
   + 部署自动扩缩组可用区数量的最多两倍。
   + 升级不可用的最大值。

     例如，如果节点组有五个可用区，`maxUnavailable` 为 1，则升级过程可以启动最多 10 个节点。但是如果 `maxUnavailable` 为 20（或者任何高于 10 的值），则该过程将启动 20 个新节点。

1. 扩展 Auto Scaling 组后，将检查节点组中是否存在使用最新配置的节点。只有在满足以下标准时，此步骤才会成功：
   + 在节点所在的每个可用区中启动至少一个新节点。
   + 每个新节点都应该处于 `Ready` 状态。
   + 新节点应该有应用 Amazon EKS 的标签。

     以下是常规节点组中的 Worker 节点上应用 Amazon EKS 的标签：
     +  `eks.amazonaws.com/nodegroup-image=$amiName` 
     +  `eks.amazonaws.com/nodegroup=$nodeGroupName` 

     以下是自定义启动模板或 AMI 节点组中的 Worker 节点上应用 Amazon EKS 的标签：
     +  `eks.amazonaws.com/nodegroup-image=$amiName` 
     +  `eks.amazonaws.com/nodegroup=$nodeGroupName` 
     +  `eks.amazonaws.com/sourceLaunchTemplateId=$launchTemplateId` 
     +  `eks.amazonaws.com/sourceLaunchTemplateVersion=$launchTemplateVersion` 

1. 将节点标记为不可调度，避免调度新的容器组（pod）。它还使用 `node.kubernetes.io/exclude-from-external-load-balancers=true` 标记节点，以便在终止节点之前从负载均衡器中移除旧节点。

下面是导致这一阶段 `NodeCreationFailure` 出现错误的已知原因：

 **可用区中容量不足**   
可用区可能没有请求的实例类型的容量。建议在创建托管节点组时配置多种实例类型。

 **账户的 EC2 实例限制**   
可能需要使用服务配额增加账户可以同时运行的 Amazon EC2 实例数量。有关更多信息，请参阅*适用于 Linux 实例的 Amazon Elastic Compute Cloud 用户指南*中的 [EC2 Service Quotas](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-resource-limits.html)。

 **自定义用户数据**   
自定义用户数据有时会中断引导过程。这种情况可能导致节点不启动 `kubelet`，或者节点上没有获得预期的 Amazon EKS 标签。有关更多信息，请参阅 [指定 AMI](launch-templates.md#launch-template-custom-ami)。

 **使节点不正常或未就绪的任何更改**   
节点磁盘压力、内存压力和类似情况可能导致节点无法进入 `Ready` 状态。

 **每个节点的引导时间最多不超过 15 分钟**   
如果任何节点引导和加入集群的时间超过 15 分钟，则会导致升级超时。这是从需要新节点开始到新节点加入集群为止测量的引导新节点的总运行时间。升级托管节点组时，时间计数器会在自动扩缩组的大小增加后启动。

## 升级阶段
<a name="managed-node-update-upgrade"></a>

升级阶段有两种行为方式，具体取决于*更新策略*。更新策略分为**默认**策略和**最小**策略这两种。

建议在大多数情况下使用默认策略。该策略会在终止旧节点之前创建新节点，这样就能在升级阶段保持可用容量。在资源或成本受限的情况下，例如使用 GPU 等硬件加速器，最小策略非常有用。该策略会在创建新节点之前终止旧节点，这样总容量永远不会超过配置的数量。

*默认*更新策略包含如下步骤：

1. 增加自动扩缩组中的节点数量（所需数量），导致该节点组创建更多节点。

1. 它随机选择一个需要更新的节点，最多为该节点组配置的最大不可用性。

1. 耗尽节点的容器组（pod）。如果容器组（pod）在 15 分钟内没有离开节点并且没有强制标志，则升级阶段将失败并显示 `PodEvictionFailure` 错误。对于这种情况，您可以使用 `update-nodegroup-version` 请求应用强制标志来删除容器组（pod）。

1. 在每个容器组（pod）被驱逐后封锁节点并等待 60 秒钟。这样做是为了防止服务控制器向此节点发送任何新请求，并将此节点从活动节点列表中删除。

1. 它向封锁节点的自动扩缩组发送终止请求。

1. 它重复以前的升级步骤，直到节点组中没有使用早期版本启动模板部署的节点。

*最小*更新策略包括如下步骤：

1. 首先会封锁节点组中的所有节点，确保服务控制器不会向这些节点发送任何新请求。

1. 它随机选择一个需要更新的节点，最多为该节点组配置的最大不可用性。

1. 耗尽选定节点的容器组（pod）。如果容器组（pod）在 15 分钟内没有离开节点并且没有强制标志，则升级阶段将失败并显示 `PodEvictionFailure` 错误。对于这种情况，您可以使用 `update-nodegroup-version` 请求应用强制标志来删除容器组（pod）。

1. 将所有容器组弹出并等待 60 秒后，它会向选定节点的自动扩缩组发出一条终止请求。该自动扩缩组会创建新节点（数量与选定的节点数相同）来替换缺失的容量。

1. 它重复以前的升级步骤，直到节点组中没有使用早期版本启动模板部署的节点。

### 升级期间的 `PodEvictionFailure` 错误
<a name="_podevictionfailure_errors_during_the_upgrade_phase"></a>

下面是导致这一阶段 `PodEvictionFailure` 出现错误的已知原因：

 **积极的 PDB**   
积极的 PDB 在容器组（pod）上定义，或者有多个 PDB 指向同一个容器组（pod）。

 **容忍所有污点的部署**   
一旦每个容器组（pod）被逐出，预计该节点将为空，因为该节点在前面的步骤中[受到污染](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)。但是，如果部署容忍每个污点，则该节点更有可能是非空的，导致容器组（pod）驱逐失败。

## 缩减阶段
<a name="managed-node-update-scale-down"></a>

缩减阶段将自动扩缩组的最大大小和所需大小减小一，返回更新开始之前的值。

如果升级工作流确定 Cluster Autoscaler 在工作流缩减阶段扩展节点组，则会立即退出，而不会使节点组恢复原始大小。

# 使用启动模板自定义托管式节点
<a name="launch-templates"></a>

为实现最高级别的自定义，您可以根据此页面上的步骤使用自己的启动模板部署托管节点。使用启动模板可以实现以下功能：在部署节点期间提供引导参数（例如，额外的 [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) 参数），从与分配给节点的 IP 地址不同的 CIDR 数据块为容器组（pod）分配 IP 地址，将自己的自定义 AMI 部署到节点，或者将自己的自定义 CNI 部署到节点。

如果您在首次创建托管节点组时提供自己的启动模板，则以后也将具有更大的灵活性。只要使用自己的启动模板部署托管节点组，您就可以使用同一启动模板的不同版本对其进行迭代更新。将节点组更新为启动模板的其他版本时，将回收组中的所有节点，以匹配指定启动模板版本的新配置。

托管式节点组始终部署用于 Amazon EC2 Auto Scaling 组的启动模板。当您不提供启动模板时，Amazon EKS API 会在您的账户中自动创建一个具有默认值的模板。但是，我们建议不要修改自动生成的启动模板。而且，无法直接更新不使用自定义启动模板的现有节点组。相反，您必须使用自定义启动模板创建新的节点组才能执行此操作。

## 启动模板配置基础知识
<a name="launch-template-basics"></a>

您可以使用 AWS 管理控制台、AWS CLI 或 AWS SDK 创建 Amazon EC2 Auto Scaling 启动模板。有关更多信息，请参阅《Amazon EC2 Auto Scaling 用户指南》**中的[为自动扩缩组创建启动模板](https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-launch-template.html)。启动模板中的某些设置类似于用于托管节点配置的设置。使用启动模板部署或更新节点组时，必须在节点组配置或启动模板中指定某些设置。不要在两个位置都指定一个设置。如果某个设置出现在错误的位置，则创建或更新节点组之类的操作将失败。

下表列出启动模板中禁止的设置，它还列出托管节点组配置中所需的类似设置（如果有）。列出的设置是显示在控制台中的设置。它们在 AWS CLI 和 SDK 中可能具有相似但不同的名称。


| 启动模板 - 已禁止 | Amazon EKS 节点组配置 | 
| --- | --- | 
|   **Network interfaces（网络接口）**（**Add network interface（添加网络接口）**）下的**Subnet（子网）**  |   **Specify networking**（指定联网）页面上 **Node group network configuration**（节点组网络配置）下的 **Subnets**（子网）  | 
|   **Advanced details（高级详细信息）**下的 **IAM instance profile（IAM 实例配置文件）**   |   **Configure Node group**（配置节点组）页面上 **Node group configuration**（节点组配置）下的 **Node IAM role**（节点 IAM 角色）  | 
|   **Advanced details（高级详细信息）**下的 **Shutdown behavior（关机行为）**和 **Stop - Hibernate behavior（停止 - 休眠行为）**。在启动模板中，对于两个设置都保留默认的**不包含在启动模板设置中**。  |  无等效项 Amazon EKS 必须控制实例生命周期，而不是自动扩缩组。  | 

下表列出托管节点组配置中禁止的设置，还列出启动模板中所需的类似设置（如果有）。列出的设置是显示在控制台中的设置。它们在 AWS CLI 和 SDK 中可能有类似的名称。


| Amazon EKS 节点组配置 – 已禁止 | 启动模板 | 
| --- | --- | 
|  （仅当在启动模板中指定了自定义 AMI 时）**设置计算和扩缩配置**页面上**节点组计算配置**下的 **AMI 类型** – 控制台显示**已在启动模板中指定**和指定的 AMI ID。 如果未在启动模板中指定**应用程序和操作系统映像（Amazon 机器映像）**，则可以在节点组配置中选择 AMI。  |   **Launch template contents**（启动模板内容）下的 **Application and OS Images (Amazon Machine Image)**（应用程序和操作系统映像（Amazon 机器映像））– 如果您有以下任一要求，则必须指定 ID： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/eks/latest/userguide/launch-templates.html)  | 
|   **Set compute and scaling configuration**（设置计算和扩展配置）页面上 **Node group compute configuration**（节点组计算配置）下的 **Disk size**（磁盘大小）– 控制台显示 **Specified in launch template**（已在启动模板中指定）。  |   **Storage (Volumes)（存储（卷））**（**Add new volume（添加新卷）**）下的 **Size（大小）**。您必须在启动模板中指定此项。  | 
|   **Specify Networking**（指定网络）页面上 **Node group configuration**（节点组配置）下的 **SSH key pair**（SSH 密钥对）– 控制台显示在启动模板中指定的密钥或显示 **Not specified in launch template**（未在启动模板中指定）。  |   **Key pair (login)（密钥对（登录））**下的 **Key pair name（密钥对名称**。  | 
|  在使用启动模板时，您无法指定允许远程访问的源安全组。  |   实例的 **Network settings（网络设置）**下的 **Security groups（安全组）**，或者 **Network interfaces（网络接口）**（**Add network interface（添加网络接口）**）下的 **Security groups（安全组）**，但不能同时兼具。有关更多信息，请参阅 [使用自定义安全组](#launch-template-security-groups)。  | 

**注意**  
如果使用启动模板部署节点组，请在启动模板的 **Launch template contents**（启动模板内容）下指定 0 或 1 个 **Instance type**（实例类型）。您也可以为控制台 **Set compute and scaling configuration**（设置计算和扩缩配置）页面的 **Instance types**（实例类型）指定 0-20 个实例类型。或者，您可以使用其他使用 Amazon EKS API 的工具来执行此操作。如果您在启动模板中指定实例类型，并使用该启动模板部署节点组，则无法在控制台中或通过使用 Amazon EKS API 的其它工具指定任何实例类型。如果没有在启动模板、控制台中或通过使用 Amazon EKS API 的其它工具指定实例类型，则使用 `t3.medium` 实例类型。如果您的节点组使用 Spot 容量类型，我们建议您使用控制台指定多个实例类型。有关更多信息，请参阅 [托管节点组容量类型](managed-node-groups.md#managed-node-group-capacity-types)。
如果部署到节点组的任何容器使用实例元数据服务版本 2，请确保在启动模板中将**Metadata response hop limit**（元数据响应跃点限制）设置为 `2`。有关更多信息，请参阅《Amazon EC2 用户指南**》中的[实例元数据和用户数据](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。
启动模板不支持 `InstanceRequirements` 功能，借助该功能可以灵活选择实例类型。

## 为 Amazon EC2 实例添加标签
<a name="launch-template-tagging"></a>

您可以使用启动模板的 `TagSpecification` 参数来指定将哪些标签应用于节点组中的 Amazon EC2 实例。调用 `CreateNodegroup` 或 `UpdateNodegroupVersion` API 的 IAM 实体必须具有 `ec2:RunInstances` 和 `ec2:CreateTags` 的权限，并且必须将标签添加到启动模板中。

## 使用自定义安全组
<a name="launch-template-security-groups"></a>

您可以使用启动模板指定自定义 Amazon EC2 [安全组](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)以应用到节点组中的实例。这可以在实例级安全组参数中，也可以作为网络接口配置参数的一部分。但是，您无法创建同时指定实例级安全组和网络接口安全组的启动模板。请考虑以下适用于为托管节点组使用自定义安全组的条件：
+ 使用 AWS 管理控制台时，Amazon EKS 仅允许使用具有单个网络接口规范的启动模板。
+ 预设情况下，Amazon EKS 将[集群安全组](sec-group-reqs.md)应用于节点组中的实例，以便于节点和控制层面之间的通信。如果您使用前面提到的任一选项在启动模板中指定自定义安全组，则 Amazon EKS 不会添加集群安全组。因此，您必须确保安全组的入站和出站规则启用了与集群端点的通信。如果您的安全组规则不正确，则 worker 节点无法加入集群。有关安全组规则的更多信息，请参阅 [查看集群的 Amazon EKS 安全组要求](sec-group-reqs.md)。
+ 如果需要对节点组中的实例进行 SSH 访问，请确保包含允许该访问的安全组。

## Amazon EC2 用户数据
<a name="launch-template-user-data"></a>

启动模板包括自定义用户数据的部分。您可以在此部分为节点组指定配置设置，而无需手动创建单个自定义 AMI。有关 Bottlerocket 可用设置的更多信息，请参阅 GitHub 上的[使用用户数据](https://github.com/bottlerocket-os/bottlerocket#using-user-data)。

在启动实例时，您可以使用 `cloud-init` 在启动模板中提供 Amazon EC2 用户数据。有关更多信息，请参阅 [cloud-init 文档](https://cloudinit.readthedocs.io/en/latest/index.html)。您的用户数据可用于执行常见配置操作。其中包括以下操作：
+  [包含用户或组](https://cloudinit.readthedocs.io/en/latest/topics/examples.html#including-users-and-groups) 
+  [安装程序包](https://cloudinit.readthedocs.io/en/latest/topics/examples.html#install-arbitrary-packages) 

启动模板中用于托管节点组的 Amazon EC2 用户数据必须采用 [MIME 分段归档](https://cloudinit.readthedocs.io/en/latest/topics/format.html#mime-multi-part-archive)格式（用于 Amazon Linux AMI）和 TOML 格式（用于 Bottlerocket AMI）。这是因为您的用户数据与节点加入集群所需的 Amazon EKS 用户数据合并。不要在用户数据中指定任何启动或修改 `kubelet` 的命令。这是作为 Amazon EKS 合并的用户数据的一部分执行的。某些 `kubelet` 参数（例如节点上的设置标签）可以直接通过托管节点组 API 进行配置。

**注意**  
如果需要高级 `kubelet` 自定义，包括手动启动或传入自定义配置参数，请参阅 [指定 AMI](#launch-template-custom-ami)。如果在启动模板中指定自定义 AMI ID，Amazon EKS 不会合并用户数据。

以下详细信息提供有关用户数据部分的更多信息。

 **Amazon Linux 2 用户数据**   
您可以将多个用户数据块合并到一个 MIME 分段文件中。例如，您可以将配置 Docker 守护进程的云 Boothook 与安装自定义软件包的用户数据 Shell 脚本合并。MIME 分段文件包含以下组成部分：  
+ 内容类型和段边界声明 - `Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="` 
+ MIME 版本声明 - `MIME-Version: 1.0` 
+ 一个或多个用户数据块，其包含以下组成部分：
  + 开口边界，表示用户数据块的开头 - `--==MYBOUNDARY==` 
  + 数据块的内容类型声明：`Content-Type: text/cloud-config; charset="us-ascii"`。有关内容类型的更多信息，请参阅 [cloud-init](https://cloudinit.readthedocs.io/en/latest/topics/format.html) 文档。
  + 用户数据的内容（例如 Shell 命令或 `cloud-init` 指令的列表）。
  + 封闭边界，表示 MIME 分段文件的结尾：`--==MYBOUNDARY==--`

  以下是 MIME 分段文件的示例，您可以用它来创建您自己的文件。

```
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="

--==MYBOUNDARY==
Content-Type: text/x-shellscript; charset="us-ascii"

#!/bin/bash
echo "Running custom user data script"

--==MYBOUNDARY==--
```

 **Amazon Linux 2023 用户数据**   
Amazon Linux 2023（AL2023）引入了使用 YAML 配置架构的新节点初始化流程 `nodeadm`。如果您使用的是自行管理的节点组或带有启动模板的 AMI，则在创建新节点组时，现在需要明确提供其它集群元数据。以下是最低必需参数的[示例](https://awslabs.github.io/amazon-eks-ami/nodeadm/)，其中 `apiServerEndpoint`、`certificateAuthority` 和服务 `cidr` 是必需的：  

```
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: my-cluster
    apiServerEndpoint: https://example.com
    certificateAuthority: Y2VydGlmaWNhdGVBdXRob3JpdHk=
    cidr: 10.100.0.0/16
```
通常，您将在用户数据中设置此配置，无论是按原样设置还是嵌入 MIME 多部分文档中：  

```
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"

--BOUNDARY
Content-Type: application/node.eks.aws

---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig spec: [...]

--BOUNDARY--
```
在 AL2 中，来自这些参数的元数据是从 Amazon EKS `DescribeCluster` API 调用中发现的。使用 AL2023，这种行为发生了变化，因为在大型节点纵向扩展期间，额外的 API 调用有节流风险。如果您使用的是没有启动模板的托管节点组或者 Karpenter，则此更改不会对您产生影响。有关 `certificateAuthority` 和服务 `cidr` 的更多信息，请参阅《Amazon EKS API 参考》**中的 [https://docs.aws.amazon.com/eks/latest/APIReference/API_DescribeCluster.html](https://docs.aws.amazon.com/eks/latest/APIReference/API_DescribeCluster.html)。  
以下是一个完整的 AL2023 用户数据示例，该实例将用于自定义节点（例如安装程序包或预缓存容器映像）的 shell 脚本与所需的 `nodeadm` 配置进行组合。该示例展示了常见的自定义设置，包括：\$1 安装附加系统程序包 \$1 预缓存容器影响以缩短容器组（pod）启动时间 \$1 设置 HTTP 代理配置 \$1 配置用于节点标记的 `kubelet` 标志  

```
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"

--BOUNDARY
Content-Type: text/x-shellscript; charset="us-ascii"

#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset

# Install additional packages
yum install -y htop jq iptables-services

# Pre-cache commonly used container images
nohup docker pull public.ecr.aws/eks-distro/kubernetes/pause:3.2 &

# Configure HTTP proxy if needed
cat > /etc/profile.d/http-proxy.sh << 'EOF'
export HTTP_PROXY="http://proxy.example.com:3128"
export HTTPS_PROXY="http://proxy.example.com:3128"
export NO_PROXY="localhost,127.0.0.1,169.254.169.254,.internal"
EOF

--BOUNDARY
Content-Type: application/node.eks.aws

apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: my-cluster
    apiServerEndpoint: https://example.com
    certificateAuthority: Y2VydGlmaWNhdGVBdXRob3JpdHk=
    cidr: 10.100.0.0/16
  kubelet:
    config:
      clusterDNS:
      - 10.100.0.10
    flags:
    - --node-labels=app=my-app,environment=production

--BOUNDARY--
```

 **Bottlerocket 用户数据**   
Bottlerocket 采用 TOML 格式构建用户数据。您可以提供要与 Amazon EKS 提供的用户数据合并的用户数据。例如，您可以提供额外的 `kubelet` 设置。  

```
[settings.kubernetes.system-reserved]
cpu = "10m"
memory = "100Mi"
ephemeral-storage= "1Gi"
```
有关支持设置的更多信息，请参阅 GitHub 上的 [Bottlerocket 文档](https://github.com/bottlerocket-os/bottlerocket)。您可以在用户数据中配置节点标签和[污点](node-taints-managed-node-groups.md)。但是，我们建议在节点组中对其进行配置。在您这样做时，Amazon EKS 应用这些配置。  
合并用户数据时，不保留格式，但内容保持不变。您在用户数据中提供的配置将覆盖 Amazon EKS 配置的任何设置。所以，如果设置 `settings.kubernetes.max-pods` 或 `settings.kubernetes.cluster-dns-ip`，用户数据中的这些值将应用到节点。  
Amazon EKS 不支持所有有效的 TOM。以下是已知不受支持的格式的列表：  
+ 引用的键中的引号：`'quoted "value"' = "value"`
+ 值中的转义引号：`str = "I’m a string. \"You can quote me\""`
+ 混合浮点数和整数：`numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]`
+ 数组中的混合类型：`contributors = ["[foo@example.com](mailto:foo@example.com)", { name = "Baz", email = "[baz@example.com](mailto:baz@example.com)" }]`
+ 带引用键的括号标题：`[foo."bar.baz"]`

 **Windows 用户数据**   
Windows 用户数据使用 PowerShell 命令。创建托管节点组时，您的自定义用户数据与 Amazon EKS 托管用户数据结合使用。您的 PowerShell 命令排在首位，然后是托管用户数据命令，所有这些命令都在一个 `<powershell></powershell>` 标签内。  
创建 Windows 节点组时，Amazon EKS 会更新 `aws-auth` `ConfigMap`，以便允许基于 Linux 的节点加入集群。该服务不会自动配置 Windows AMI 权限。如果使用的是 Windows 节点，则需要通过访问条目 API 或通过直接更新 `aws-auth` `ConfigMap` 来管理访问权限。有关更多信息，请参阅 [在 EKS 集群上部署 Windows 节点](windows-support.md)。
如果在启动模板中未指定 AMI ID，请勿在用户数据中使用 Windows Amazon EKS 引导脚本来配置 Amazon EKS。
用户数据示例如下所示。  

```
<powershell>
Write-Host "Running custom user data script"
</powershell>
```

## 指定 AMI
<a name="launch-template-custom-ami"></a>

如果您具有以下任一要求，请在启动模板的 `ImageId` 字段中指定一个 AMI ID。选择您对其他信息的要求。

### 提供用户数据，将参数传递给随 Amazon EKS 优化版 Linux/Bottlerocket AMI 一起提供的 `bootstrap.sh` 文件
<a name="mng-specify-eks-ami"></a>

Bootstrapping（引导启动）是一个术语，用于描述添加可以在实例启动时运行的命令。例如，引导允许使用额外的 [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) 参数。您可以使用 `eksctl` 将参数传递给 `bootstrap.sh` 脚本，无需指定启动模板。或者，您可以在启动模板的用户数据部分中指定信息来实现此目标。

 **eksctl 无需指定启动模板**   
创建一个名为 *my-nodegroup.yaml* 的文件，其中包含以下内容。将所有 *example value* 替换为您自己的值。`--apiserver-endpoint`、`--b64-cluster-ca` 和 `--dns-cluster-ip` 参数是可选的。但是，定义它们可使 `bootstrap.sh` 脚本避免进行 `describeCluster` 调用。在私有集群设置或频繁扩展节点的集群中，这是非常有用的。有关 `bootstrap.sh` 脚本的更多信息，请参阅 GitHub 上的 [bootstrap.sh](https://github.com/awslabs/amazon-eks-ami/blob/main/templates/al2/runtime/bootstrap.sh) 文件。  
+ 唯一必需的参数是集群名称（*my-cluster*）。
+ 要检索 `ami-1234567890abcdef0 ` 的优化版 AMI ID，请参阅以下部分：
  +  [检索建议的 Amazon Linux AMI ID](retrieve-ami-id.md) 
  +  [检索建议的 Bottlerocket AMI ID](retrieve-ami-id-bottlerocket.md) 
  +  [检索建议的 Microsoft Windows AMI ID](retrieve-windows-ami-id.md) 
+ 要检索您的集群的 *certificate-authority*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.certificateAuthority.data" --output text --name my-cluster --region region-code
  ```
+ 要检索您的集群的 *api-server-endpoint*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.endpoint" --output text --name my-cluster --region region-code
  ```
+ `--dns-cluster-ip` 的值是您的服务 CIDR，末尾为 `.10`。要检索您的集群的 *service-cidr*，请运行以下命令。例如，如果返回值为 `ipv4 10.100.0.0/16`，则您的值为 *10.100.0.10*。

  ```
  aws eks describe-cluster --query "cluster.kubernetesNetworkConfig.serviceIpv4Cidr" --output text --name my-cluster --region region-code
  ```
+ 此示例使用包含在 Amazon EKS 优化版 AMI 中的 `bootstrap.sh` 脚本提供一个 `kubelet` 参数来设置一个自定义 `max-pods` 值。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头，但也可以包括其余字符的连字符和下划线。有关选择 *my-max-pods-value* 的帮助，请参阅 。有关使用托管节点组时如何确定 `maxPods` 的更多信息，请参阅 [如何确定 maxPods](choosing-instance-type.md#max-pods-precedence)。

  ```
  ---
  apiVersion: eksctl.io/v1alpha5
  kind: ClusterConfig
  
  metadata:
    name: my-cluster
    region: region-code
  
  managedNodeGroups:
    - name: my-nodegroup
      ami: ami-1234567890abcdef0
      instanceType: m5.large
      privateNetworking: true
      disableIMDSv1: true
      labels: { x86-al2-specified-mng }
      overrideBootstrapCommand: |
        #!/bin/bash
        /etc/eks/bootstrap.sh my-cluster \
          --b64-cluster-ca certificate-authority \
          --apiserver-endpoint api-server-endpoint \
          --dns-cluster-ip service-cidr.10 \
          --kubelet-extra-args '--max-pods=my-max-pods-value' \
          --use-max-pods false
  ```

  对于每一个可用的 `eksctl` `config` 文件选项，请参阅 `eksctl` 文档中的[配置文件架构](https://eksctl.io/usage/schema/)。`eksctl` 实用程序仍会为您创建启动模板，并使用您在 `config` 文件中提供的数据填充其用户数据。

  使用以下命令创建节点组。

  ```
  eksctl create nodegroup --config-file=my-nodegroup.yaml
  ```

 **启动模板中的用户数据**   
在启动模板的用户数据部分指定以下信息。将所有 *example value* 替换为您自己的值。`--apiserver-endpoint`、`--b64-cluster-ca` 和 `--dns-cluster-ip` 参数是可选的。但是，定义它们可使 `bootstrap.sh` 脚本避免进行 `describeCluster` 调用。在私有集群设置或频繁扩展节点的集群中，这是非常有用的。有关 `bootstrap.sh` 脚本的更多信息，请参阅 GitHub 上的 [bootstrap.sh](https://github.com/awslabs/amazon-eks-ami/blob/main/templates/al2/runtime/bootstrap.sh) 文件。  
+ 唯一必需的参数是集群名称（*my-cluster*）。
+ 要检索您的集群的 *certificate-authority*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.certificateAuthority.data" --output text --name my-cluster --region region-code
  ```
+ 要检索您的集群的 *api-server-endpoint*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.endpoint" --output text --name my-cluster --region region-code
  ```
+ `--dns-cluster-ip` 的值是您的服务 CIDR，末尾为 `.10`。要检索您的集群的 *service-cidr*，请运行以下命令。例如，如果返回值为 `ipv4 10.100.0.0/16`，则您的值为 *10.100.0.10*。

  ```
  aws eks describe-cluster --query "cluster.kubernetesNetworkConfig.serviceIpv4Cidr" --output text --name my-cluster --region region-code
  ```
+ 此示例使用包含在 Amazon EKS 优化版 AMI 中的 `bootstrap.sh` 脚本提供一个 `kubelet` 参数来设置一个自定义 `max-pods` 值。有关选择 *my-max-pods-value* 的帮助，请参阅 。有关使用托管节点组时如何确定 `maxPods` 的更多信息，请参阅 [如何确定 maxPods](choosing-instance-type.md#max-pods-precedence)。

  ```
  MIME-Version: 1.0
  Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="
  
  --==MYBOUNDARY==
  Content-Type: text/x-shellscript; charset="us-ascii"
  
  #!/bin/bash
  set -ex
  /etc/eks/bootstrap.sh my-cluster \
    --b64-cluster-ca certificate-authority \
    --apiserver-endpoint api-server-endpoint \
    --dns-cluster-ip service-cidr.10 \
    --kubelet-extra-args '--max-pods=my-max-pods-value' \
    --use-max-pods false
  
  --==MYBOUNDARY==--
  ```

### 提供用户数据，将参数传递给随 Amazon EKS 优化版 Windows AMI 一起提供的 `Start-EKSBootstrap.ps1` 文件
<a name="mng-specify-eks-ami-windows"></a>

Bootstrapping（引导启动）是一个术语，用于描述添加可以在实例启动时运行的命令。您可以使用 `eksctl` 将参数传递给 `Start-EKSBootstrap.ps1` 脚本，无需指定启动模板。或者，您可以在启动模板的用户数据部分中指定信息来实现此目标。

如果您想指定自定义 Windows AMI ID，请记住以下注意事项：
+ 您必须使用启动模板并在用户数据部分提供所需的引导命令。要检索所需的 Windows ID，您可以使用[使用优化版 Windows AMI 创建节点](eks-optimized-windows-ami.md)中的表。
+ 有一些限制和条件。例如，您必须将 `eks:kube-proxy-windows` 添加到您的 AWS IAM 身份验证器配置映射中。有关更多信息，请参阅 [指定 AMI ID 时的限制和条件](#mng-ami-id-conditions)。

在启动模板的用户数据部分指定以下信息。将所有 *example value* 替换为您自己的值。`-APIServerEndpoint`、`-Base64ClusterCA` 和 `-DNSClusterIP` 参数是可选的。但是，定义它们可使 `Start-EKSBootstrap.ps1` 脚本避免进行 `describeCluster` 调用。
+ 唯一必需的参数是集群名称（*my-cluster*）。
+ 要检索您的集群的 *certificate-authority*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.certificateAuthority.data" --output text --name my-cluster --region region-code
  ```
+ 要检索您的集群的 *api-server-endpoint*，请运行以下命令。

  ```
  aws eks describe-cluster --query "cluster.endpoint" --output text --name my-cluster --region region-code
  ```
+ `--dns-cluster-ip` 的值是您的服务 CIDR，末尾为 `.10`。要检索您的集群的 *service-cidr*，请运行以下命令。例如，如果返回值为 `ipv4 10.100.0.0/16`，则您的值为 *10.100.0.10*。

  ```
  aws eks describe-cluster --query "cluster.kubernetesNetworkConfig.serviceIpv4Cidr" --output text --name my-cluster --region region-code
  ```
+ 有关更多参数，请参阅 [引导脚本配置参数](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters)。
**注意**  
如果您使用自定义服务 CIDR，则需要使用 `-ServiceCIDR` 参数进行指定。否则，集群中的容器组（pod）DNS 解析将失败。

```
<powershell>
[string]$EKSBootstrapScriptFile = "$env:ProgramFiles\Amazon\EKS\Start-EKSBootstrap.ps1"
& $EKSBootstrapScriptFile -EKSClusterName my-cluster `
	 -Base64ClusterCA certificate-authority `
	 -APIServerEndpoint api-server-endpoint `
	 -DNSClusterIP service-cidr.10
</powershell>
```

### 由于特定的安全性、合规性或内部策略要求，运行自定义 AMI
<a name="mng-specify-custom-ami"></a>

有关更多信息，请参阅《Amazon EC2 用户指南》**中的[亚马逊机器映像（AMI）](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)。Amazon EKS AMI 构建规范包含用于构建基于 Amazon Linux 的自定义 Amazon EKS AMI 的资源和配置脚本。有关更多信息，请参阅 GitHub 上的 [Amazon EKS AMI 构建规范](https://github.com/awslabs/amazon-eks-ami/)。要构建与其他操作系统一起安装的自定义 AMI，请参阅 GitHub 上的 [Amazon EKS 示例自定义 AMI](https://github.com/aws-samples/amazon-eks-custom-amis)。

在与托管式节点组一起使用的启动模板中，AMI ID 不能使用动态参数引用。

**重要**  
在指定 AMI 时，Amazon EKS 不会将您的 AMI 中嵌入的 Kubernetes 版本与您的集群控制面板版本进行比对验证。您有责任确保您的自定义 AMI 的 Kubernetes 版本符合 [Kubernetes 版本偏斜策略](https://kubernetes.io/releases/version-skew-policy)：  
您节点上的 `kubelet` 版本不得高于您的集群版本
您节点上的 `kubelet` 版本必须与集群版本相同，或者比集群版本低 3 个或更少的次要版本（对于 Kubernetes 版本 `1.28` 或更高版本）；或者比集群版本低 2 个或更少的次要版本（对于 Kubernetes 版本 `1.27` 或更低版本）  
创建存在版本偏差违规情况的托管节点组可能会导致：
节点未能加入集群
未定义的行为或 API 不兼容
集群不稳定或工作负载故障
指定 AMI 时，Amazon EKS 不会合并任何用户数据。实际上，您要负责提供节点加入集群所需的 `bootstrap` 命令。如果您的节点无法加入集群，那么 Amazon EKS `CreateNodegroup` 和 `UpdateNodegroupVersion` 操作也会失败。

## 指定 AMI ID 时的限制和条件
<a name="mng-ami-id-conditions"></a>

使用托管节点组指定 AMI ID 所涉及的限制和条件如下：
+ 您必须创建一个新的节点组，以便在在启动模板中指定 AMI ID 和不指定 AMI ID 之间进行切换。
+ 当有较新的 AMI 版本可用时，控制台中不会通知您。要将节点组更新为更新的 AMI 版本，需要使用更新的 AMI ID 创建新版本的启动模板。然后需要使用新的启动模板版本更新节点组。
+ 如果您指定 AMI ID，则无法在 API 中设置以下字段：
  +  `amiType` 
  +  `releaseVersion` 
  +  `version` 
+ 如果您指定 AMI ID，则会异步应用 API 中的任何 `taints` 设置。要在节点加入集群之前应用污点，必须使用 `--register-with-taints` 命令行标志将污点传递到用户数据中的 `kubelet`。有关更多信息，请参阅 Kubernetes 文档中的 [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/)。
+ 为 Windows 托管节点组指定自定义 AMI ID 时，请将 `eks:kube-proxy-windows` 添加到您的 AWS IAM 身份验证器配置映射中。需要执行此操作 DNS 才能正常运行。

  1. 打开 AWS IAM 身份验证器配置映射进行编辑。

     ```
     kubectl edit -n kube-system cm aws-auth
     ```

  1. 将此条目添加到每个与 Windows 节点关联的 `rolearn` 下的 `groups` 列表中。您的配置图应该看起来像 [aws-auth-cm-windows.yaml](https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/aws-auth-cm-windows.yaml)。

     ```
     - eks:kube-proxy-windows
     ```

  1. 保存文件并退出文本编辑器。
+ 对于使用自定义启动模板的任何 AMI，托管节点组的默认 `HttpPutResponseHopLimit` 均设置为 `2`。

# 从集群中删除托管式节点组
<a name="delete-managed-node-group"></a>

本主题介绍如何删除 Amazon EKS 托管节点组。删除托管式节点组时，Amazon EKS 会首先将自动扩缩组的最小、最大和所需大小设置为零。然后，这会导致节点组缩小。

在每个实例终止前，Amazon EKS 会发送一个信号对该节点执行排空操作。在节点排空流程中，Kubernetes 会对节点上的每个容器组（pod）执行以下操作：运行所有已配置的 `preStop` 生命周期挂钩，向容器发送 `SIGTERM` 信号，随后等待 `terminationGracePeriodSeconds` 完成正常关闭。如果 5 分钟后节点仍未完成排空，Amazon EKS 会允许自动扩缩组继续执行实例的强制终止操作。终止所有实例后，将删除自动扩缩组。

**重要**  
如果您删除的托管节点组使用的节点 IAM 角色未由集群中任何其它托管节点组使用，则该角色将从 `aws-auth` `ConfigMap` 中移除。如果集群中的任何自行托管节点组使用相同的节点 IAM 角色，则自行管理的节点将变为 `NotReady` 状态。此外，集群操作也被中断。如果您的集群的平台版本至少为[使用 EKS 访问条目向 IAM 用户授予对 Kubernetes 的访问权限](access-entries.md) 的先决条件部分中列出的最低版本，要为仅用于自行管理的节点组的角色添加映射，请参阅[创建访问条目](creating-access-entries.md)。如果您的平台版本早于访问条目所需的最低版本，则可以将该条目重新添加到 `aws-auth` `ConfigMap`。要了解更多信息，请在您的终端中输入 `eksctl create iamidentitymapping --help`。

您可以使用以下工具删除托管节点组：
+  [`eksctl`](#eksctl-delete-managed-nodegroup) 
+  [AWS 管理控制台](#console-delete-managed-nodegroup) 
+  [AWS CLI](#awscli-delete-managed-nodegroup) 

## `eksctl`
<a name="eksctl-delete-managed-nodegroup"></a>

 **用 `eksctl` 删除托管节点组** 

输入以下命令。将每个 `<example value>` 替换为您自己的值。

```
eksctl delete nodegroup \
  --cluster <my-cluster> \
  --name <my-mng> \
  --region <region-code>
```

有关更多选项，请参阅 `eksctl` 文档中的[删除和清空节点组](https://eksctl.io/usage/nodegroups/#deleting-and-draining-nodegroups)。

## AWS 管理控制台
<a name="console-delete-managed-nodegroup"></a>

 **用 AWS 管理控制台删除托管节点组** 

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 在**集群**页面上，请选择包含要删除的节点组的集群。

1. 在所选集群页面上，请选择**计算**选项卡。

1. 在 **Node groups**（节点组）部分中，选择要删除的节点组。然后选择**删除**。

1. 在**删除节点组**确认对话框中，请输入节点组的名称。然后选择**删除**。

## AWS CLI
<a name="awscli-delete-managed-nodegroup"></a>

 **用 AWS CLI 删除托管节点组** 

1. 输入如下命令。将每个 `<example value>` 替换为您自己的值。

   ```
   aws eks delete-nodegroup \
     --cluster-name <my-cluster> \
     --nodegroup-name <my-mng> \
     --region <region-code>
   ```

1. 若 CLI 配置中已设置 `cli_pager=`，则使用键盘上的方向键滚动查看响应输出内容。完成后按 `q` 键。

   有关更多选项，请参阅 *AWS CLI 命令参考*中的 ` [delete-nodegroup](https://docs.aws.amazon.com/cli/latest/reference/eks/delete-nodegroup.html) ` 命令。