帮助改进此页面
想为本用户指南做出贡献? 滚动到页面底部,然后选择在 GitHub 上编辑此页面。您的贡献有助于我们的用户指南为每个人提供更充分的参考。
将应用程序迁移到新的节点组
本主题介绍如何创建新的节点组,将您的现有应用程序自然地迁移到新组,然后从您的集群中删除旧的节点组。您可以使用 eksctl
或 AWS Management Console 迁移到新的节点组。
- eksctl
-
使用
eksctl
将您的应用程序迁移到新的节点组有关使用 eksctl 进行迁移的更多信息,请参阅
eksctl
文档中的非托管节点组。 此过程需要
eksctl
版本0.191.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
和下面的命令启动新节点组。将命令中的所有
替换为您自己的值。版本号不能高于控制面板的 Kubernetes 版本。此外,它不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。example value
如果满足以下条件,我们建议阻止 Pod 访问 IMDS:
您计划将 IAM 角色分配到所有 Kubernetes 服务账户,以便 Pods 只具有所需的最低权限。
集群中没有任何 Pods 需要出于其他原因(例如检索当前 AWS 区域)访问 Amazon EC2 实例元数据服务(IMDS)。
有关更多信息,请参阅限制对分配给工作节点的实例配置文件的访问
。 要阻止 Pod 对 IMDS 的访问,请将
--disable-pod-imds
选项添加到以下命令。注意
有关更多可用标志及其说明,请参阅 https://eksctl.io/
。 eksctl create nodegroup \ --cluster
my-cluster
\ --version1.31
\ --namestandard-nodes-new
\ --node-typet3.medium
\ --nodes3
\ --nodes-min1
\ --nodes-max4
\ --managed=false -
当上一个命令完成时,使用以下命令验证您的所有节点是否已达到
Ready
状态:kubectl get nodes
-
使用以下命令删除原始节点组。在命令中,将每个
替换为集群和节点组名称:example value
eksctl delete nodegroup --cluster
my-cluster
--namestandard-nodes-old
-
- AWS Management Console and AWS CLI
-
使用 AWS Management Console 和 AWS CLI 将您的应用程序迁移到新的节点组。
-
执行 创建自行管理的 Amazon Linux 节点 中概述的步骤,启动新的节点组。
-
完成创建堆栈后,在控制台中选中它,然后选择 Outputs(输出)。
-
记录已创建的节点组的 NodeInstanceRole。您需要它来将新的 Amazon EKS 节点添加到集群。
注意
如果您已将任何其他 IAM policy 附加到旧节点组 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
条目。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将arn:aws:
替换为arn:aws-us-gov:
。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将
代码段替换为您在上一步中记录的 NodeInstanceRole 值,然后保存该文件。保存并关闭该文件以应用更新后的 configmap。ARN of instance role (not instance profile)
-
查看节点的状态并等待新节点加入您的集群并达到
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.29
)的所有节点并对其执行污点操作。版本号不能高于控制面板的 Kubernetes 版本。此外,它不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。K8S_VERSION=
1.29
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.29
K8S_VERSION=
1.29
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 policy 附加到旧节点组 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 打开 AWS CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation
。 -
选择您的旧节点堆栈。
-
选择删除。
-
在 Delete stack(删除堆栈)确认对话框中,请选择 Delete stack(删除堆栈)。
-
-
编辑
aws-auth
configmap 以从 RBAC 中删除旧节点实例角色。kubectl edit configmap -n kube-system aws-auth
删除旧节点组的
mapRoles
条目。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将arn:aws:
替换为arn:aws-us-gov:
。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/
)并将您的 Cluster Autoscaler 部署命令更新为指向新标记的 Auto Scaling 组。有关更多信息,请参阅 AWS 上的 Cluster Autoscalermy-cluster
。 kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
-
(可选)确认您使用的是最新版本的 Kubernetes 的 Amazon VPC CNI 插件
。您可能需要更新 CNI 版本以使用最新的受支持实例类型。有关更多信息,请参阅 使用 Amazon VPC CNI 将 IP 分配给 Pods。 -
如果您的集群使用适用于 DNS 解析的
kube-dns
(请参阅上一步),请将kube-dns
部署缩减为 1 个副本。kubectl scale deployments/kube-dns --replicas=1 -n kube-system
-