本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
迁移到新的节点组
本主题可帮助您创建新节点组,将现有应用程序正常地迁移到新组,然后从集群中删除旧节点组。您可以使用 eksctl 或 AWS 管理控制台 迁移到新的节点组。
使用 eksctl
将应用程序迁移到新节点组
此过程需要 eksctl
版本 0.35.0
或更高版本。可以使用以下命令来查看您的版本:
eksctl version
有关安装或升级 eksctl
的更多信息,请参阅安装或升级 eksctl。
此过程仅适用于使用 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 values>
(包括<>
)替换为您自己的值。版本号不能高于控制层面的 Kubernetes 版本,并且不能比控制层面的 Kubernetes 版本早两个以上的次要版本,不过我们建议您使用与控制层面相同的版本。如果您计划将 IAM 角色分配给所有 Kubernetes 服务账户,以便 Pod 只拥有所需的最低权限,并且集群中没有 Pod 出于其他原因(例如,检索当前区域)需要访问 Amazon EC2 实例元数据服务 (IMDS),那么我们建议阻止 Pod 访问 IMDS。有关更多信息,请参阅 服务账户的 IAM 角色 和 限制对 IMDS 和 Amazon EC2 实例配置文件凭证的访问。如果要阻止 Pod 对 IMDS 的访问,请将--disable-pod-imds
选项添加到以下命令。注意 有关更多可用的标签及其对应描述,请参阅 https://eksctl.io/
。 eksctl create nodegroup \ --cluster <my-cluster> \ --version <1.18> \ --name <standard-nodes-new> \ --node-type <t3.medium> \ --nodes <3> \ --nodes-min <1> \ --nodes-max <4> \ --node-ami auto
-
当上一个命令完成后,使用以下命令验证您的所有节点是否已达到
Ready
状态:kubectl get nodes
-
使用以下命令删除原始节点组,同时将
<example values>
(包括<>
)替换为您的集群和节点组名称:eksctl delete nodegroup --cluster <my-cluster> --name <standard-nodes>
使用 AWS 管理控制台 和 AWS CLI 将应用程序迁移到新节点组
-
按照启动自管理 Amazon Linux 节点中概述的步骤启动新的节点组。
-
完成创建堆栈后,在控制台中选中它,然后选择 Outputs (输出).
-
记录已创建的节点组的 NodeInstanceRole。您需要此值来将新的 Amazon EKS 节点添加到集群。
注意 如果您已将任何其他 IAM 策略附加到旧节点组 IAM 角色(例如为 Kubernetes Cluster Autoscaler
添加权限),则应将这些相同的策略附加到新节点组 IAM 角色以在新组上维护该功能。 -
更新两个节点组的安全组,以便它们可以相互通信。有关更多信息,请参阅 Amazon EKS 安全组注意事项.
-
记录两个节点组的安全组 ID。这显示为 堆栈输出中的 NodeSecurityGroupAWS CloudFormation 值。
您可以使用以下 AWS CLI 命令从堆栈名称中获取安全组 ID。在这些命令中,
oldNodes
是您的较早节点堆栈的 AWS 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)
-
向每个节点安全组添加入口规则,以便它们接受彼此的流量。
以下 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
-
-
编辑
aws-auth
配置映射以在 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 操作,以便在要替换的节点上不计划或重新计划新的 Pod:kubectl taint nodes <node_name> key=value:NoSchedule
如果要将节点升级到新的 Kubernetes 版本,则可以使用以下代码段标识特定 Kubernetes 版本(此示例中为 1.16)的所有节点并对其执行 Taint 操作。版本号不能高于控制层面的 Kubernetes 版本,并且不能比控制层面的 Kubernetes 版本早两个以上的次要版本,不过我们建议您使用与控制层面相同的版本。
K8S_VERSION=<1.16> 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
输出(此集群使用的是适用于 DNS 解析的
kube-dns
,但您的集群可能会改为返回coredns
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE <kube-dns> 1 1 1 1 31m
-
如果您的当前部署所运行的副本少于 2 个,请将部署扩展到 2 个副本。如果上一个命令输出返回了
<kube-dns>
,则将coredns
替换为 。kubectl scale deployments/<kube-dns> --replicas=2 -n kube-system
-
使用以下命令耗尽要从集群中删除的每个节点:
kubectl drain <node_name> --ignore-daemonsets --delete-local-data
如果要将节点升级到新的 Kubernetes 版本,则可以使用以下代码段标识并耗尽特定 Kubernetes 版本(在本例中为 1.16)的所有节点。
K8S_VERSION=<1.16> 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
-
从 https://console.amazonaws.cn/cloudformation
打开 AWS CloudFormation 控制台。 -
选择您的旧节点堆栈。
-
选择 Actions (操作),然后选择 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
,请将部署缩减为一个副本。 注意 您还必须适当地标记新的 Auto Scaling 组(例如,
k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME>
)并将您的 Cluster Autoscaler 部署的命令更新为指向新标记的 Auto Scaling 组。有关更多信息,请参阅 AWS 上的 Cluster Autoscaler. kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
-
(可选)确认您使用的是最新版本的 Kubernetes 的 Amazon VPC CNI 插件
. 您可能需要更新 CNI 版本来利用最新的受支持的实例类型。有关更多信息,请参阅 Amazon VPC适用于 Kubernetes 的 CNI 插件升级. -
如果您的集群使用适用于 DNS 解析的
kube-dns
(请参阅上一步),请将kube-dns
部署缩减为一个副本。kubectl scale deployments/kube-dns --replicas=1 -n kube-system