迁移到新的节点组 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

迁移到新的节点组

本主题将帮助您创建新的节点组,将您的现有应用程序正常地迁移到新组,然后从集群中删除旧节点组。您可以使用eksctl或Amazon Web Services Management Console。

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

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

eksctl version

有关安装或升级 eksctl 的更多信息,请参阅安装或升级 eksctl

注意

此过程仅适用于使用创建的集群和节点组。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 values>(包括<>)与您自己的值。版本号不能晚于控制平面的 Kubernetes 版本,并且不能比控制平面的 Kubernetes 版本早于两个次要版本,尽管我们建议您使用与控制平面相同的版本。如果您计划将 IAM 角色分配给您的所有 Kubernetes 服务账户,以便容器只具有所需的最低权限,并且集群中没有容器因其他原因(如检索当前区域)需要访问 Amazon EC2 实例元数据服务 (IMDS),那么我们建议您使用阻止对 IMDS 的容器访问。有关更多信息,请参阅 服务账户的 IAM 角色限制对 IMDS 和 Amazon EC2 实例配置文件证书的访问权限。如果要阻止 Pod 对 IMDS 的访问,请将--disable-pod-imds选项添加到以下命令。

    注意

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

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

    kubectl get nodes
  4. 使用以下命令删除原始节点组,将<example values>(包括<>)与您的集群和节点组名称一起使用:

    eksctl delete nodegroup --cluster <my-cluster> --name <standard-nodes>

使用将您的应用程序迁移到新的节点组Amazon Web Services Management Console和Amazon CLI

  1. 执行中概述的步骤来启动新节点组启动自我管理的亚马逊 Linux 节点

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

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

    注意

    如果您已将任何其他 IAM 策略附加到旧节点组 IAM 角色(例如为 Kubernetes 添加权限)Cluster Autoscaler,您应将这些相同的策略附加到新节点组 IAM 角色以在新组上维护该功能。

  4. 更新两个节点组的安全组,以便它们可以相互通信。有关更多信息,请参阅 Amazon EKS 安全组注意事项

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

      您可以使用以下 Amazon CLI 命令从堆栈名称中获取安全组 ID。在这些命令中,oldNodes是Amazon CloudFormation堆栈名称,以及newNodes是您要迁移到的堆栈的名称。将<example values>(包括<>) 与您自己的值。

      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. 向每个节点安全组添加入口规则,以便它们接受彼此的流量。

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

      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-authconfigmap 映射 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-cn: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值,您记录在上一步,然后保存并关闭该文件以应用更新后的配置映射。

  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:

    kubectl taint nodes <node_name> key=value:NoSchedule

    如果您要将节点升级到新的 Kubernetes 版本,则可以使用以下代码段标识特定 Kubernetes 版本(此示例中为版本 1.18)的所有节点并对其执行 Taint 操作。版本号不能晚于控制平面的 Kubernetes 版本,并且不能比控制平面的 Kubernetes 版本早于两个次要版本,尽管我们建议您使用与控制平面相同的版本。

    K8S_VERSION=<1.18> 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

    输出(此集群使用的是适用于 DNS 解析的 kube-dns,但您的集群可能会改为返回 coredns):

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

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

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

    如果您要将节点升级到新的 Kubernetes 版本,则可以标识并耗尽特定 Kubernetes 版本(此示例中为1.18)与以下代码片段一起使用。

    K8S_VERSION=<1.18> 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. 在旧节点耗尽后,请撤销您之前授权的安全组入口规则,然后删除Amazon CloudFormation堆栈以终止实例。

    注意

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

    1. 撤销您之前为节点安全组创建的入口规则。在这些命令中,oldNodes是Amazon 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. 打开 Amazon CloudFormation 控制台,网址:https://console.aws.amazon.com/cloudformation

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

    4. 选择 Actions (操作),然后选择 Delete stack (删除堆栈)

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

    kubectl edit configmap -n kube-system aws-auth

    删除存储在设备上的mapRoles条目。

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

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

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

    注意

    您还必须适当地标记新的 Auto Scaling 组(例如k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME>)并将您的集群 Autoscaler 部署的命令更新为指向新标记的 Auto Scaling 组。有关更多信息,请参阅 Amazon 上的 Cluster Autoscaler

    kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
  15. (可选)确认您使用的是最新版本的适用于 Kubernetes 的 Amazon VPC CNI 插件。您可能需要更新 CNI 版本来利用最新的受支持的实例类型。有关更多信息,请参阅 手动更新亚马逊 VPC CNI 加载项

  16. 如果您的集群使用kube-dns了解 DNS 解析(请参阅上一步),在kube-dns部署到一个副本。

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