

 **帮助改进此页面** 

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

# 更新 AWS CloudFormation 节点堆栈
<a name="update-stack"></a>

本主题介绍如何使用新 AMI 更新现有 AWS CloudFormation 自行管理的节点堆栈。在集群更新后，可以使用此过程将节点更新为新版本的 Kubernetes。或者，您可以更新到针对现有 Kubernetes 版本的最新 Amazon EKS 优化 AMI。

**重要**  
本主题介绍适用于自行管理的节点的节点更新。有关[使用托管式节点组简化节点生命周期](managed-node-groups.md)的信息，请参阅[更新集群的托管式节点组](update-managed-node-group.md)。

最新的默认 Amazon EKS 节点 AWS CloudFormation 模板将配置为使用新 AMI 在集群中启动实例，然后再删除旧 AMI，一次删除一个。此配置可确保您在滚动更新期间始终具有集群中自动扩缩组所需的活动实例计数。

**注意**  
使用 `eksctl` 创建的节点组不支持此方法。如果您使用 `eksctl` 创建了集群或节点组，请参阅 [将应用程序迁移到新的节点组](migrate-stack.md)。

1. 确定集群的 DNS 提供商。

   ```
   kubectl get deployments -l k8s-app=kube-dns -n kube-system
   ```

   示例输出如下。此集群使用 CoreDNS 解析 DNS，但您的集群可能会返回 `kube-dns`。您的输出可能看起来有所不同，具体取决于您使用的 `kubectl` 版本。

   ```
   NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
   coredns   1         1         1            1           31m
   ```

1. 如果您的当前部署所运行的副本少于 2 个，请将部署扩展到 2 个副本。如果您的上一个命令输出返回了该项，请将 *coredns* 替换为`kube-dns`。

   ```
   kubectl scale deployments/coredns --replicas=2 -n kube-system
   ```

1. （可选）如果使用 [Kubernetes Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)，请将部署缩减到 0 个副本以避免相互冲突的扩缩操作。

   ```
   kubectl scale deployments/cluster-autoscaler --replicas=0 -n kube-system
   ```

1.  确定当前节点组的实例类型和所需的实例计数。以后更新该组的 AWS CloudFormation 模板时将输入这些值。

   1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

   1. 请在左侧导航窗格中，选择 **Launch Configurations**（启动配置），然后记下现有节点启动配置的实例类型。

   1. 请在左侧导航窗格中，选择**自动扩缩组**，并记下现有节点自动扩缩组的**所需**实例计数。

1. 打开 [AWS CloudFormation 控制台](https://console.aws.amazon.com/cloudformation/)。

1. 选择您的节点组堆栈，然后选择 **Update（更新）**。

1. 选择**替换当前模板**，然后选择 **Amazon S3 URL**。

1. 对于 **Amazon S3 URL**，请将以下 URL 粘贴到文本区域中以确保您使用的是最新版本的节点 AWS CloudFormation 模板。接下来，选择 **Next**（下一步）：

   ```
   https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2022-12-23/amazon-eks-nodegroup.yaml
   ```

1. 在 **Specify stack details (指定堆栈详细信息)** 页面上，填写以下参数，然后选择 **Next (下一步)**：
   +  **NodeAutoScalingGroupDesiredCapacity** - 输入在[上一步](#existing-worker-settings-step)记录的所需实例计数。或者输入更新堆栈时要扩展到的所需节点数目。
   +  **NodeAutoScalingGroupMaxSize**：输入您的节点自动扩缩组可横向扩展到的最大节点数。此值必须比所需容量多至少一个节点。这样更新期间可以对节点进行滚动更新而不会减少节点数。
   +  **NodeInstanceType** - 选择在[上一步](#existing-worker-settings-step)记录的实例类型。也可以为节点选择不同的实例类型。在选择其它实例类型之前，请查看[选择最优的 Amazon EC2 节点实例类型](choosing-instance-type.md)。每种 Amazon EC2 实例类型支持最大数量的弹性网络接口（网络接口），每个网络接口都支持最大数量的 IP 地址。由于为每个 Worker 节点和容器组（pod）分配了自己的 IP 地址，请务必选择一个实例类型，该实例类型可以支持您希望在每个 Amazon EC2 节点上运行的最大数量的容器组（pod）。有关实例类型支持的网络接口和 IP 地址数量的列表，请参阅[每种实例类型的每个网络接口的 IP 地址数](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)。例如，`m5.large` 实例类型最多支持 Worker 节点和容器组（pod）的 30 个 IP 地址。
**注意**  
最新版本[适用于 Kubernetes 的 Amazon VPC CNI 插件](https://github.com/aws/amazon-vpc-cni-k8s)支持的实例类型在 GitHub 上的 [vpc\$1ip\$1resource\$1limit.go](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/pkg/vpc/vpc_ip_resource_limit.go) 中显示。您可能需要更新适用于 Kubernetes 的 Amazon VPC CNI 插件版本，才能使用最新的受支持实例类型。有关更多信息，请参阅 [使用 Amazon VPC CNI 将 IP 分配给容器组（pod）](managing-vpc-cni.md)。
**重要**  
一些实例类型并非在所有 AWS 区域中都可用。
   +  **NodeImageIdSSMParam** – 要更新到的 AMI ID 的 Amazon EC2 Systems Manager 参数。以下值为 Kubernetes 版本 `1.35` 使用最新 Amazon EKS 优化版 AMI。

     ```
     /aws/service/eks/optimized-ami/1.35/amazon-linux-2/recommended/image_id
     ```

     您可以将 *1.35* 替换为相同的 [platform-version](https://docs.aws.amazon.com/eks/latest/userguide/platform-versions.html)。或者，它应该比控制面板运行的 Kubernetes 版本高最多一个版本。我们建议您将节点保持在与控制面板相同的版本。您也可以将 *amazon-linux-2* 替换为其它 AMI 类型。有关更多信息，请参阅 [检索建议的 Amazon Linux AMI ID](retrieve-ami-id.md)。
**注意**  
使用 Amazon EC2 Systems Manager 参数让您可以在以后更新节点而无需查找和指定 AMI ID。如果您的 AWS CloudFormation 堆栈使用此值，则任何堆栈更新将为您指定的 Kubernetes 版本始终启动最新建议的 Amazon EKS 优化版 AMI。即使不更改模板中的任何值，情况也是如此。
   +  **NodeImageId** – 要使用您的自定义 AMI，请输入要使用的 AMI 的 ID。
**重要**  
此值覆盖为 **NodeImageIdSSMParam** 指定的任意值。如果您要使用 **NodeImageIdSSMParam** 值，请确保 **NodeImageId** 的值为空白。
   +  **DisableIMDSv1** - 每个节点默认支持实例元数据服务版本 1 (IMDSv1) 和 IMDSv2。但可以禁用 IMDSv1。如果不希望节点组中调度的任何节点或任何容器组（pod）使用 IMDSv1，请选择 **true**。有关 IMDS 的更多信息，请参阅[配置实例元数据服务](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)。如果已实施服务账户的 IAM 角色，请将所需权限直接分配给需要访问 AWS 服务的所有容器组（pod）。这样，集群中就没有任何容器组（pod）需要出于其他原因（例如检索当前 AWS 区域）访问 IMDS。然后，对于不使用主机网络的容器组（pod），您还可以禁用 IMDSv2 的访问权限。有关更多信息，请参阅[限制对分配给工作节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。

1. （可选）在 **Options (选项)** 页面上，为您的堆栈资源添加标签。选择**下一步**。

1. 在 **Review（审核）**页面上审核您的信息，确认堆栈可创建 IAM 资源，然后选择 **Update stack（更新堆栈）**。
**注意**  
集群中每个节点的更新需要几分钟时间。等待所有节点更新完成，然后再执行后续步骤。

1. 如果您的集群的 DNS 提供商是 `kube-dns`，请将 `kube-dns` 部署横向缩减为 1 个副本。

   ```
   kubectl scale deployments/kube-dns --replicas=1 -n kube-system
   ```

1. （可选）如果您使用的是 Kubernetes [Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)，请将部署缩减为所需数量的副本。

   ```
   kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
   ```

1. （可选）确认您使用的是最新版本的 [Kubernetes 的 Amazon VPC CNI 插件](https://github.com/aws/amazon-vpc-cni-k8s)。您可能需要更新适用于 Kubernetes 的 Amazon VPC CNI 插件版本，才能使用最新的受支持实例类型。有关更多信息，请参阅 [使用 Amazon VPC CNI 将 IP 分配给容器组（pod）](managing-vpc-cni.md)。