帮助改进此页面
想为本用户指南做出贡献? 选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。您的贡献有助于我们的用户指南为每个人提供更充分的参考。
将应用程序迁移到新的节点组
本主题介绍如何创建新的节点组,将您的现有应用程序自然地迁移到新组,然后从您的集群中删除旧的节点组。您可以使用 eksctl
或 AWS Management Console 迁移到新的节点组。
eksctl
使用 eksctl
将您的应用程序迁移到新的节点组
有关使用 eksctl 进行迁移的更多信息,请参阅 eksctl
文档中的非托管节点组
此过程需要 eksctl
版本 0.199.0
或更高版本。可以使用以下命令来查看您的版本:
eksctl version
有关安装或升级 eksctl
的说明,请参阅 eksctl
文档中的 Installation
注意
此过程仅适用于使用 eksctl
创建的集群和节点组。
-
检索您现有节点组的名称,同时将
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
-
用
eksctl
和下面的命令启动新节点组。将命令中的所有example value
替换为您自己的值。版本号不能高于控制面板的 Kubernetes 版本。此外,它不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。如果满足以下条件,我们建议阻止 Pod 访问 IMDS:
-
您计划将 IAM 角色分配到所有 Kubernetes 服务账户,以便 Pods 只具有所需的最低权限。
-
集群中没有任何 Pods 需要出于其它原因(例如检索当前 AWS 区域)访问 Amazon EC2 实例元数据服务(IMDS)。
有关更多信息,请参阅限制对分配给 Worker 节点的实例配置文件的访问
。 要阻止 Pod 对 IMDS 的访问,请将
--disable-pod-imds
选项添加到以下命令。注意
有关更多可用标志及其说明,请参阅 https://eksctl.io/
。
eksctl create nodegroup \ --cluster my-cluster \ --version 1.30 \ --name standard-nodes-new \ --node-type t3.medium \ --nodes 3 \ --nodes-min 1 \ --nodes-max 4 \ --managed=false
-
-
当上一个命令完成时,使用以下命令验证您的所有节点是否已达到
Ready
状态:kubectl get nodes
-
使用以下命令删除原始节点组。在命令中,将所有
example value
替换为集群和节点组名称:eksctl delete nodegroup --cluster my-cluster --name standard-nodes-old
AWS Management Console 和 AWS CLI
使用 AWS Management Console和 AWS CLI 将您的应用程序迁移到新的节点组。
-
执行创建自行管理的 Amazon Linux 节点中概述的步骤,启动新的节点组。
-
完成创建堆栈后,在控制台中选中它,然后选择 Outputs(输出)。
-
记录已创建的节点组的 NodeInstanceRole。您需要它来将新的 Amazon EKS 节点添加到集群。
注意
如果您已将任何其他 IAM 策略附加到旧节点组 IAM 角色,则应将这些相同的策略附加到新节点组 IAM 角色以在新组上保持该功能。这适用于为 Kubernetes Cluster Autoscaler
添加权限的情况。 -
同时更新两个节点组的安全组,以便它们可以相互通信。有关更多信息,请参阅 查看集群的 Amazon EKS 安全组要求。
-
记下两个节点组的安全组 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)
-
向每个节点安全组添加入口规则,以便它们接受彼此的流量。
以下 AWS 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
-
-
编辑
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。 -
查看节点的状态并等待新节点加入您的集群并达到
Ready
状态。kubectl get nodes --watch
-
(可选)如果使用 Kubernetes Cluster Autoscaler
,请将部署缩减到 0 个副本以避免相互冲突的扩缩操作。 kubectl scale deployments/cluster-autoscaler --replicas=0 -n kube-system
-
使用以下命令,对要使用
NoSchedule
删除的每个节点执行 Taint 操作。这样不会在要替换的节点上安排或重新安排新 Pods。有关更多信息,请参阅 Kubernetes 文档中的污点和容忍度。 kubectl taint nodes node_name key=value:NoSchedule
如果您要将节点升级到新的 Kubernetes 版本,则可以使用以下代码段标识特定 Kubernetes 版本(此示例中为
1.28
)的所有节点并对其执行污点操作。版本号不能高于控制面板的 Kubernetes 版本。此外,它不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。K8S_VERSION=1.28 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
-
确定集群的 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
-
如果您的当前部署所运行的副本少于 2 个,请将部署扩展到 2 个副本。如果您的上一个命令输出返回了该项,请将
coredns
替换为kubedns
。kubectl scale deployments/coredns --replicas=2 -n kube-system
-
使用以下命令耗尽要从集群中删除的每个节点:
kubectl drain node_name --ignore-daemonsets --delete-local-data
如果您要将节点升级到新的 Kubernetes 版本,则使用以下代码段标识并耗尽特定 Kubernetes 版本(此示例中为
1.28
)的所有节点。K8S_VERSION=1.28 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
-
在旧节点耗尽后,请撤销您之前授权的安全组入口规则。然后删除 AWS CloudFormation 堆栈以终止实例。
注意
如果您已将任何其它 IAM 策略附加到旧节点组 IAM 角色(例如,为 Kubernetes Cluster Autoscaler
添加权限),请先将这些附加策略与该角色分离,然后才能删除 AWS CloudFormation 堆栈。 -
撤销您之前为节点安全组创建的入站规则。在这些命令中,
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
-
选择您的旧节点堆栈。
-
选择删除。
-
在 Delete stack(删除堆栈)确认对话框中,请选择 Delete stack(删除堆栈)。
-
-
编辑
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。
-
(可选)如果您使用的是 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
-
(可选)确认您使用的是最新版本的 Kubernetes 的 Amazon VPC CNI 插件
。您可能需要更新 CNI 版本以使用最新的受支持实例类型。有关更多信息,请参阅 使用 Amazon VPC CNI 将 IP 分配给 Pods。 -
如果您的集群使用适用于 DNS 解析的
kube-dns
(请参阅[migrate-determine-dns-step]),请将kube-dns
部署横向缩减为 1 个副本。kubectl scale deployments/kube-dns --replicas=1 -n kube-system