將應用程式移轉至新的節點群組 - Amazon EKS

協助改進此頁面

若要為本使用者指南貢獻內容,請點選每個頁面右側面板中的在 GitHub 上編輯此頁面連結。

將應用程式移轉至新的節點群組

此主題會說明如何建立新的節點群組,將現有的應用程式從容遷移至新群組,接著從叢集移除舊的節點群組。您可以使用 eksctl 或 AWS 管理主控台 遷移至新的節點群組。

eksctl

使用 eksctl 將應用程式移轉至新的節點群組

如需有關將 eksctl 用於移轉的詳細資訊,請參閱 eksctl 文件中的未受管的節點群組

此程序需要 eksctl 版本 0.214.0 或更新版本。您可使用以下命令檢查您的版本:

eksctl version

如需有關安裝或更新 eksctl 的指示,請參閱 eksctl 文件中的 Installation 一節。

注意

此程序只適用於使用 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 的新節點群組。在命令中,使用您自己的值取代每一個範例值。版本編號不能晚於控制平面的 Kubernetes 版本。也不能比控制平面的 Kubernetes 版本早兩個以上的次要版本。建議使用與控制平面相同的版本。

    如果下列條件為真,我們建議封鎖 Pod 對 IMDS 的存取:

    • 您計劃將 IAM 角色指派給您的所有 Kubernetes 服務帳戶,以便 Pod 僅具有所需的最低許可。

    • 叢集中沒有 Pod 出於其他原因 (例如擷取當前的 AWS 區域) 需要存取 Amazon EC2 執行個體中繼資料服務 (IMDS)。

      如需詳細資訊,請參閱‬限制存取指派給工作節點的執行個體設定檔‭

      若要封鎖 Pod 對 IMDS 的存取,請將 --disable-pod-imds 選項新增至下列命令。

      注意

      如需更多可用旗標及其描述的資訊,請參閱 https://eksctl.io/

    eksctl create nodegroup \ --cluster my-cluster \ --version 1.33 \ --name standard-nodes-new \ --node-type t3.medium \ --nodes 3 \ --nodes-min 1 \ --nodes-max 4 \ --managed=false
  3. 之前的命令完成時,使用下列命令來確認所有節點已達到 Ready 狀態:

    kubectl get nodes
  4. 使用下列命令來刪除原始的節點群組。在命令中,使用您的叢集和節點群組名稱取代每一個範例值

    eksctl delete nodegroup --cluster my-cluster --name standard-nodes-old

AWS 管理主控台 和 AWS CLI

使用 AWS 管理主控台 和 AWS CLI 將應用程式移轉至新的節點群組

  1. 依照建立自我管理的 Amazon Linux 節點中概述的步驟啟動新的節點群組。

  2. 當當堆疊已完成建立時,從主控台將其選取,然後選擇 Outputs (輸出)

  3. 為已建立的節點群組記錄 NodeInstanceRole。您需要這樣才能新增 Amazon EKS 節點至叢集。

    注意

    如果已將任何額外的 IAM 政策連接至舊節點群組 IAM 角色,則請將相同政策連接至新節點群組 IAM 角色,以便在新群組維持該功能。例如,如果為 Kubernetes Cluster Autoscaler 新增許可,則適用此操作。

  4. 更新兩個節點群組的安全群組,使其能夠互相通訊。如需詳細資訊,請參閱 檢視叢集的 Amazon EKS 安全群組要求

    1. 記錄兩個節點群組的安全群組 ID。這在 AWS CloudFormation 堆疊輸出中顯示為 NodeSecurityGroup 值。

      您可以使用下列 AWS CLI 命令從堆疊名稱取得安全群組 ID。在這些命令中,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)
    2. 新增輸入規則至每個節點安全群組,使其接受彼此的流量。

      下列 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
  5. 編輯 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

    使用您在上一個步驟中記錄的 NodeInstanceRole 值來取代執行個體角色 ARN (非執行個體設定檔) 程式碼片段。接著,儲存並關閉檔案以套用更新的 configmap。

  6. 注意節點狀態並等待新的節點加入叢集和達到 Ready 狀態。

    kubectl get nodes --watch
  7. (選用) 如果您使用的是 Kubernetes Cluster Autoscaler,請將部署縮減為零 (0) 個複本以避免衝突的擴展動作。

    kubectl scale deployments/cluster-autoscaler --replicas=0 -n kube-system
  8. 使用以下命令污染每個您想要用 NoSchedule 移除的節點。這樣就不會在您要取代的節點上排程或重新排程新的 Pod。如需詳細資訊,請參閱 Kubernetes 文件中的污點和容差

    kubectl taint nodes node_name key=value:NoSchedule

    如果要將節點升級至新的 Kubernetes 版本,您可以使用以下程式碼片段識別並標示特定 Kubernetes 版本 (在此情況下為 1.31) 的所有節點。版本編號不能晚於控制平面的 Kubernetes 版本。也不能比控制平面的 Kubernetes 版本早兩個以上的次要版本。建議使用與控制平面相同的版本。

    K8S_VERSION=1.31 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 解析度使用 CoreDNS,但您的叢集可能會傳回 kube-dns

    NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 1 1 1 1 31m
  10. 如果您目前的部署執行少於 2 個複本,請將部署擴增為 2 個複本。如果您先前的命令輸出傳回該項目,請以 kubedns 取代 coredns

    kubectl scale deployments/coredns --replicas=2 -n kube-system
  11. 使用以下命令清空您想要從叢集移除的每個節點:

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

    如果要將節點升級至新的 Kubernetes 版本,請使用以下程式碼片段識別並耗盡特定 Kubernetes 版本 (在此情況下為 1.31) 的所有節點。

    K8S_VERSION=1.31 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. 在舊的節點完成消耗後,請撤銷您先前授權的安全群組傳入規則。接著,請刪除 AWS CloudFormation 堆疊來終止執行個體。

    注意

    如果已將任何額外的 IAM 政策連接至舊節點群組 IAM 角色 (例如針對 Kubernetes Cluster Autoscaler 新增許可),則必須先從角色分開這些額外政策,才能夠刪除 AWS CloudFormation 堆疊。

    1. 撤銷您先前為節點安全群組建立的傳入規則。在這些命令中,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
    2. 開啟 AWS CloudFormation 主控台

    3. 選取舊的節點堆疊。

    4. 選擇 刪除

    5. Delete stack (刪除堆疊) 確認對話方塊中,選擇 Delete stack (刪除堆疊)。

  13. 編輯 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。

  14. (選用) 如果您使用的是 Kubernetes Cluster Autoscaler,請將部署縮減回 1 個複本。

    注意

    您也必須適當標記新的 Auto Scaling 群組 (例如 k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster),並更新 Cluster Autoscaler 部署的命令,以指向新標記的 Auto Scaling 群組。如需詳細資訊,請參閱 AWS 上的 Cluster Autoscaler

    kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
  15. (選用) 確認您使用的是最新版本的 Kubernetes 專用 Amazon VPC CNI 外掛程式。您可能需要更新 CNI 版本,才能使用最新支援的執行個體類型。如需詳細資訊,請參閱 使用 Amazon VPC CNI 將 IP 指派給 Pod

  16. 如果您的叢集針對 DNS 解析度使用 kube-dns (請參閱 [migrate-determine-dns-step]),請將 kube-dns 部署縮減至一個複本。

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