迁移到新的节点组
本主题介绍如何创建新的节点组,将您的现有应用程序自然地迁移到新组,然后从您的集群中删除旧的节点组。您可以使用 eksctl 或 Amazon Web Services Management Console 迁移到新的节点组。
- eksctl
-
使用
eksctl将您的应用程序迁移到新的节点组有关使用 eksctl 进行迁移的更多信息,请参阅
eksctl文档中的 Unmanaged nodegroup upgrades(非托管节点组升级)。 此过程需要
eksctl版本0.135.0或更高版本。可以使用以下命令来查看您的版本:eksctl version有关如何安装或升级
eksctl的说明,请参阅 安装或更新 eksctl。注意
此过程仅适用于使用
eksctl创建的集群和节点组。-
检索您现有节点组的名称,同时将
替换为您的集群名称。my-clustereksctl 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 服务账户,以便容器组(pod)只具有他们所需的最低权限。
集群中没有任何容器组(pod)需要出于其他原因(例如检索当前 Amazon Web Services 区域)访问 Amazon EC2 实例元数据服务(IMDS)。
有关更多信息,请参阅限制对分配给工作节点的实例配置文件的访问
。 要阻止 pod 对 IMDS 的访问,请将
--disable-pod-imds选项添加到以下命令。注意
有关更多可用标志及其说明,请参阅 https://eksctl.io/
。 eksctl create nodegroup \ --clustermy-cluster\ --version1.25\ --namestandard-nodes-new\ --node-typet3.medium\ --nodes3\ --nodes-min1\ --nodes-max4\ --managed=false -
当上一个命令完成时,使用以下命令验证您的所有节点是否已达到
Ready状态:kubectl get nodes -
使用以下命令删除原始节点组。在命令中,将每个
替换为集群和节点组名称:example valueeksctl delete nodegroup --clustermy-cluster--namestandard-nodes-old
-
- Amazon Web Services Management Console and Amazon CLI
-
使用 Amazon Web Services Management Console 和 Amazon CLI 将您的应用程序迁移到新的节点组。
-
执行 启动自行管理的 Amazon Linux 节点 中概述的步骤,启动新的节点组。
-
完成创建堆栈后,在控制台中选中它,然后选择 Outputs(输出)。
-
记录已创建的节点组的 NodeInstanceRole。您需要它来将新的 Amazon EKS 节点添加到集群。
注意
如果您已将任何其他 IAM policy 附加到旧节点组 IAM 角色,则应将这些相同的策略附加到新节点组 IAM 角色以在新组上保持该功能。这适用于为 Kubernetes Cluster Autoscaler
添加权限的情况。 -
同时更新两个节点组的安全组,以便它们可以相互通信。有关更多信息,请参阅Amazon EKS 安全组要求和注意事项。
-
记下两个节点组的安全组 ID。这在 Amazon CloudFormation 堆栈输出中显示为 NodeSecurityGroup 值。
您可以使用以下 Amazon CLI 命令从堆栈名称中获取安全组 ID。在这些命令中,
oldNodes是您的较旧节点堆栈的 Amazon CloudFormation 堆栈名称,newNodes是要迁移到的堆栈的名称。将每个替换为您自己的值。example valueoldNodes="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) -
向每个节点安全组添加入口规则,以便它们接受彼此的流量。
以下 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
-
-
编辑
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:iam::111122223333:role/nodes-1-16-NodeInstanceRole-U11V27W93CX5username: 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 nodesnode_namekey=value:NoSchedule如果您要将节点升级到新的 Kubernetes 版本,则可以使用以下代码段标识特定 Kubernetes 版本(此示例中为
1.23)的所有节点并对其执行污点操作。版本号不能高于控制面板的 Kubernetes 版本。此外,它不能比控制面板的 Kubernetes 版本低两个以上的次要版本。我们建议您使用与控制面板相同的版本。K8S_VERSION=1.23nodes=$(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。kubednskubectl scale deployments/coredns--replicas=2 -n kube-system -
使用以下命令耗尽要从集群中删除的每个节点:
kubectl drainnode_name--ignore-daemonsets --delete-local-data如果您要将节点升级到新的 Kubernetes 版本,则使用以下代码段标识并耗尽特定 Kubernetes 版本(此示例中为
)的所有节点。1.23K8S_VERSION=1.23nodes=$(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 -
在旧节点耗尽后,请撤销您之前授权的安全组入口规则。然后删除 Amazon CloudFormation 堆栈以终止实例。
注意
如果您已将任何其他 IAM policy 附加到旧节点组 IAM 角色(例如,为 Kubernetes Cluster Autoscaler
添加权限),请先将这些附加策略与该角色分离,然后才能删除 Amazon CloudFormation 堆栈。 -
撤销您之前为节点安全组创建的入站规则。在这些命令中,
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 打开 Amazon CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation
。 -
选择您的旧节点堆栈。
-
选择 Delete (删除)。
-
在 Delete stack(删除堆栈)确认对话框中,请选择 Delete stack(删除堆栈)。
-
-
编辑
aws-authconfigmap 以从 RBAC 中删除旧节点实例角色。kubectl edit configmap -n kube-system aws-auth删除旧节点组的
mapRoles条目。apiVersion: v1 data: mapRoles: | - rolearn:arn:aws:iam::111122223333:role/nodes-1-16-NodeInstanceRole-W70725MZQFF8username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes - rolearn:arn:aws:iam::111122223333:role/nodes-1-15-NodeInstanceRole-U11V27W93CX5username: 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 组。有关更多信息,请参阅 Amazon 上的 Cluster Autoscalermy-cluster。 kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system -
(可选)确认您使用的是最新版本的 Kubernetes 的 Amazon VPC CNI 插件
。您可能需要更新 CNI 版本以使用最新的受支持实例类型。有关更多信息,请参阅使用 Amazon VPC CNI plugin for Kubernetes Amazon EKS 附加组件。 -
如果您的集群使用适用于 DNS 解析的
kube-dns(请参阅上一步),请将kube-dns部署缩减为 1 个副本。kubectl scale deployments/kube-dns --replicas=1 -n kube-system
-