选择您的 Cookie 首选项

我们使用必要 Cookie 和类似工具提供我们的网站和服务。我们使用性能 Cookie 收集匿名统计数据,以便我们可以了解客户如何使用我们的网站并进行改进。必要 Cookie 无法停用,但您可以单击“自定义”或“拒绝”来拒绝性能 Cookie。

如果您同意,AWS 和经批准的第三方还将使用 Cookie 提供有用的网站功能、记住您的首选项并显示相关内容,包括相关广告。要接受或拒绝所有非必要 Cookie,请单击“接受”或“拒绝”。要做出更详细的选择,请单击“自定义”。

将应用程序迁移到新的节点组

聚焦模式
将应用程序迁移到新的节点组 - Amazon EKS

帮助改进此页面

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

帮助改进此页面

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

本主题介绍如何创建新的节点组,将您的现有应用程序自然地迁移到新组,然后从您的集群中删除旧的节点组。您可以使用 eksctl 或 AWS Management Console 迁移到新的节点组。

eksctl

使用 eksctl 将您的应用程序迁移到新的节点组

有关使用 eksctl 进行迁移的更多信息,请参阅 eksctl 文档中的非托管节点组

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

eksctl version

有关安装或升级 eksctl 的说明,请参阅 eksctl 文档中的 Installation

注意

此过程仅适用于使用 eksctl 创建的集群和节点组。

  1. 检索您现有节点组的名称,同时将 my-cluster 替换为您的集群名称。

    eksctl get nodegroups --cluster=my-cluster

    示例输出如下。

    CLUSTER NODEGROUP CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID default standard-nodes 2019-05-01T22:26:58Z 1 4 3 t3.medium ami-05a71d034119ffc12
  2. eksctl 和下面的命令启动新节点组。将命令中的所有 example value 替换为您自己的值。版本号不能高于控制面板的 Kubernetes 版本,也不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。

    如果满足以下条件,我们建议阻止容器组(pod)访问 IMDS:

    • 您计划将 IAM 角色分配给所有 Kubernetes 服务账户,以便容器组(pod)仅具有其所需的最低权限。

    • 集群中没有任何容器组(pod)需要出于其他原因(例如检索当前 AWS 区域)访问 Amazon EC2 实例元数据服务(IMDS)。

      有关更多信息,请参阅限制对分配给 Worker 节点的实例配置文件的访问

      要阻止容器组(pod)对 IMDS 的访问,请将 --disable-pod-imds 选项添加到以下命令。

      注意

      有关更多可用标志及其说明,请参阅 https://eksctl.io/

    eksctl create nodegroup \ --cluster my-cluster \ --version 1.32 \ --name standard-nodes-new \ --node-type t3.medium \ --nodes 3 \ --nodes-min 1 \ --nodes-max 4 \ --managed=false
  3. 当上一个命令完成时,使用以下命令验证您的所有节点是否已达到 Ready 状态:

    kubectl get nodes
  4. 使用以下命令删除原始节点组。在命令中,将所有 example value 替换为集群和节点组名称:

    eksctl delete nodegroup --cluster my-cluster --name standard-nodes-old

AWS Management Console 和 AWS CLI

使用 AWS Management Console和 AWS CLI 将您的应用程序迁移到新的节点组。

  1. 执行创建自行管理的 Amazon Linux 节点中概述的步骤,启动新的节点组。

  2. 完成创建堆栈后,在控制台中选中它,然后选择 Outputs(输出)

  3. 记录已创建的节点组的 NodeInstanceRole。您需要它来将新的 Amazon EKS 节点添加到集群。

    注意

    如果您已将任何其他 IAM 策略附加到旧节点组 IAM 角色,则应将这些相同的策略附加到新节点组 IAM 角色以在新组上保持该功能。这适用于为 Kubernetes Cluster Autoscaler 添加权限的情况。

  4. 同时更新两个节点组的安全组,以便它们可以相互通信。有关更多信息,请参阅 查看集群的 Amazon EKS 安全组要求

    1. 记下两个节点组的安全组 ID。这在 AWS CloudFormation 堆栈输出中显示为 NodeSecurityGroup 值。

      您可以使用以下 AWS CLI 命令从堆栈名称中获取安全组 ID。在这些命令中,oldNodes 是您的较旧节点堆栈的 AWS CloudFormation 堆栈名称,newNodes 是要迁移到的堆栈的名称。将所有 example value 替换为您自己的值。

      oldNodes="old_node_CFN_stack_name" newNodes="new_node_CFN_stack_name" oldSecGroup=$(aws cloudformation describe-stack-resources --stack-name $oldNodes \ --query 'StackResources[?ResourceType==`AWS::EC2::SecurityGroup`].PhysicalResourceId' \ --output text) newSecGroup=$(aws cloudformation describe-stack-resources --stack-name $newNodes \ --query 'StackResources[?ResourceType==`AWS::EC2::SecurityGroup`].PhysicalResourceId' \ --output text)
    2. 向每个节点安全组添加入口规则,以便它们接受彼此的流量。

      以下 AWS CLI 命令向每个安全组添加入站规则,以允许来自另一个安全组的所有协议上的所有流量。通过此配置,在您将工作负载迁移到新组时,每个节点组中的容器组(pod)都可以相互通信。

      aws ec2 authorize-security-group-ingress --group-id $oldSecGroup \ --source-group $newSecGroup --protocol -1 aws ec2 authorize-security-group-ingress --group-id $newSecGroup \ --source-group $oldSecGroup --protocol -1
  5. 编辑 aws-auth configmap 以在 RBAC 中映射新的节点实例角色。

    kubectl edit configmap -n kube-system aws-auth

    为新的节点组添加新的 mapRoles 条目。

    apiVersion: v1 data: mapRoles: | - rolearn: ARN of instance role (not instance profile) username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes> - rolearn: arn:aws:iam::111122223333:role/nodes-1-16-NodeInstanceRole-U11V27W93CX5 username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes

    ARN of instance role (not instance profile) 代码段替换为在上一步中记录的 NodeInstanceRole 值。保存并关闭该文件以应用更新后的 configmap。

  6. 查看节点的状态并等待新节点加入您的集群并达到 Ready 状态。

    kubectl get nodes --watch
  7. (可选)如果使用 Kubernetes Cluster Autoscaler,请将部署缩减到 0 个副本以避免相互冲突的扩缩操作。

    kubectl scale deployments/cluster-autoscaler --replicas=0 -n kube-system
  8. 使用以下命令,对要使用 NoSchedule 删除的每个节点执行 Taint 操作。如此一来,就不会在要替换的节点上调用或重新调用新的容器组(pod)。有关更多信息,请参阅 Kubernetes 文档中的 Taints and Tolerations

    kubectl taint nodes node_name key=value:NoSchedule

    如果要将节点升级到新的 Kubernetes 版本,则可使用以下代码段来标识并污染特定 Kubernetes 版本(此示例中为 1.30 版本)的所有节点。版本号不能高于控制面板的 Kubernetes 版本,也不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。

    K8S_VERSION=1.30 nodes=$(kubectl get nodes -o jsonpath="{.items[?(@.status.nodeInfo.kubeletVersion==\"v$K8S_VERSION\")].metadata.name}") for node in ${nodes[@]} do echo "Tainting $node" kubectl taint nodes $node key=value:NoSchedule done
  9. 确定集群的 DNS 提供商。

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

    示例输出如下。此集群使用 CoreDNS 解析 DNS,但您的集群可能会返回 kube-dns):

    NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 1 1 1 1 31m
  10. 如果您的当前部署所运行的副本少于 2 个,请将部署扩展到 2 个副本。如果您的上一个命令输出返回了该项,请将 coredns 替换为kubedns

    kubectl scale deployments/coredns --replicas=2 -n kube-system
  11. 使用以下命令耗尽要从集群中删除的每个节点:

    kubectl drain node_name --ignore-daemonsets --delete-local-data

    如果您要将节点升级到新的 Kubernetes 版本,请使用以下代码段标识并耗尽特定 Kubernetes 版本(此示例中为 1.30 版本)的所有节点。

    K8S_VERSION=1.30 nodes=$(kubectl get nodes -o jsonpath="{.items[?(@.status.nodeInfo.kubeletVersion==\"v$K8S_VERSION\")].metadata.name}") for node in ${nodes[@]} do echo "Draining $node" kubectl drain $node --ignore-daemonsets --delete-local-data done
  12. 在旧节点耗尽后,请撤销您之前授权的安全组入口规则。然后删除 AWS CloudFormation 堆栈以终止实例。

    注意

    如果您已将任何其它 IAM 策略附加到旧节点组 IAM 角色(例如,为 Kubernetes Cluster Autoscaler 添加权限),请先将这些附加策略与该角色分离,然后才能删除 AWS CloudFormation 堆栈。

    1. 撤销您之前为节点安全组创建的入站规则。在这些命令中,oldNodes 是您的较旧节点堆栈的 AWS CloudFormation 堆栈名称,newNodes 是要迁移到的堆栈的名称。

      oldNodes="old_node_CFN_stack_name" newNodes="new_node_CFN_stack_name" oldSecGroup=$(aws cloudformation describe-stack-resources --stack-name $oldNodes \ --query 'StackResources[?ResourceType==`AWS::EC2::SecurityGroup`].PhysicalResourceId' \ --output text) newSecGroup=$(aws cloudformation describe-stack-resources --stack-name $newNodes \ --query 'StackResources[?ResourceType==`AWS::EC2::SecurityGroup`].PhysicalResourceId' \ --output text) aws ec2 revoke-security-group-ingress --group-id $oldSecGroup \ --source-group $newSecGroup --protocol -1 aws ec2 revoke-security-group-ingress --group-id $newSecGroup \ --source-group $oldSecGroup --protocol -1
    2. 打开 AWS CloudFormation 控制台

    3. 选择您的旧节点堆栈。

    4. 选择删除

    5. Delete stack(删除堆栈)确认对话框中,请选择 Delete stack(删除堆栈)。

  13. 编辑 aws-auth configmap 以从 RBAC 中删除旧节点实例角色。

    kubectl edit configmap -n kube-system aws-auth

    删除旧节点组的 mapRoles 条目。

    apiVersion: v1 data: mapRoles: | - rolearn: arn:aws:iam::111122223333:role/nodes-1-16-NodeInstanceRole-W70725MZQFF8 username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes - rolearn: arn:aws:iam::111122223333:role/nodes-1-15-NodeInstanceRole-U11V27W93CX5 username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes>

    保存并关闭该文件以应用更新后的 configmap。

  14. (可选)如果您使用的是 Kubernetes Cluster Autoscaler,请将部署缩减为 1 个副本。

    注意

    您还必须适当地标记新的自动扩缩组(例如,k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster)并将您的 Cluster Autoscaler 部署命令更新为指向新标记的自动扩缩组。有关更多信息,请参阅 AWS 上的 Cluster Autoscaler

    kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
  15. (可选)确认您使用的是最新版本的 Kubernetes 的 Amazon VPC CNI 插件。您可能需要更新 CNI 版本以使用最新的受支持实例类型。有关更多信息,请参阅 使用 Amazon VPC CNI 将 IP 分配给容器组(pod)

  16. 如果您的集群使用适用于 DNS 解析的 kube-dns(请参阅[migrate-determine-dns-step]),请将 kube-dns 部署横向缩减为 1 个副本。

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

本页内容

隐私网站条款Cookie 首选项
© 2025, Amazon Web Services, Inc. 或其附属公司。保留所有权利。