新しいノードグループへの移行 - Amazon EKS

新しいノードグループへの移行

このトピックは、新しいノードグループを作成し、既存のアプリケーションを新しいグループに適切に移行し、クラスターから古いノードグループを削除する方法について説明します。新しいノードグループに移行するには、eksctl または AWS Management Console を使用します。

eksctl
eksctl を使用してアプリケーションを新しいノードグループに移行するには

eksctl を移行に使用する方法の詳細については、eksctl ドキュメントの「管理対象外のノードグループ」を参照してください。

この手順には、eksctl バージョン 0.172.0 以降が必要です。お使いのバージョンは、以下のコマンドを使用して確認できます。

eksctl version

eksctl のインストールまたはアップグレードの手順については、eksctl ドキュメントの「インストール」を参照してください。

注記

この手順は、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 で新しいノードグループを起動します。コマンドのすべての example value を独自の値に置き換えます。バージョン番号は、お使いのコントロールプレーンの Kubernetes バージョンよりも新しいものにすることはできません。また、コントロールプレーンの Kubernetes バージョンより 3 つ以上前のマイナーなバージョンにすることもできません。コントロールプレーンと同じバージョンを使用することをお勧めします。

    次の条件が true の場合、IMDS への Pod アクセスをブロックすることをお勧めします。

    • すべての Kubernetes サービスアカウントに IAM ロールを割り当てて、Pods が必要最小限のアクセス許可のみを持つように計画しています。

    • クラスター内の Pods が、現在の AWS リージョン の取得といったその他の理由で Amazon EC2 インスタンスメタデータサービス (IMDS) へのアクセスを必要としていません。

    詳細については、「ワーカーノードに割り当てられたインスタンスプロファイルへのアクセスを制限する」を参照してください。

    IMDS への Pod アクセスをブロックするには、次のコマンドに --disable-pod-imds オプションを追加します。

    注記

    使用可能なフラグとその説明については、「https://eksctl.io/」を参照してください。

    eksctl create nodegroup \ --cluster my-cluster \ --version 1.29 \ --name standard-nodes-new \ --node-type t3.medium \ --nodes 3 \ --nodes-min 1 \ --nodes-max 4 \ --managed=false
  3. 前のコマンドが完了したら、次のコマンドを使用して、すべてのノードが Ready 状態になったことを確認します。

    kubectl get nodes
  4. 次のコマンドを使用して、元のノードグループを削除します。このコマンドで、すべての example value を自分のクラスター名とノードグループ名に置き換えます。

    eksctl delete nodegroup --cluster my-cluster --name standard-nodes-old
AWS Management Console and AWS CLI
AWS Management Console と AWS CLI を使用してアプリケーションを新しいノードグループに移行するには
  1. 新しいノードグループを起動するには、セルフマネージド型の Amazon Linux ノードの起動の手順に従います。

  2. スタックの作成が完了したら、コンソールで選択し、[出力] を選択します。

  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 は、移行先のスタックの名前を表します。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)
    2. 互いにトラフィックを受け入れるように、各ノードのセキュリティグループに進入ルールを追加します。

      以下の 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
  5. 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

    ARN of instance role (not instance profile) スニペットを、前の手順で記録した [NodeInstanceRole] 値に置き換えます。次に、更新された configmap を適用するには、ファイルを保存して閉じます。

  6. ノードのステータスを監視し、新しいノードがクラスターに結合され、Ready ステータスになるまで待機します。

    kubectl get nodes --watch
  7. (オプション) Kubernetes Cluster Autoscaler を使用している場合は、スケーリングアクションの競合を回避するために、デプロイメントを 0 (ゼロ) レプリカにスケールダウンします。

    kubectl scale deployments/cluster-autoscaler --replicas=0 -n kube-system
  8. 以下のコマンドを使用して、NoSchedule で削除する各ノードをテイントに設定します。これは、置き換えるノード上で新しい Pods がスケジュールまたは再スケジュールされないようにするためです。詳細については、Kubernetes ドキュメントの「テイントと容認」を参照してください。

    kubectl taint nodes node_name key=value:NoSchedule

    ノードを新しい Kubernetes バージョンにアップグレードする場合は、次のコードスニペットを使用して、特定の Kubernetes バージョン (この場合は 1.27) のすべてのノードを識別してテイントに設定できます。バージョン番号は、お使いのコントロールプレーンの Kubernetes バージョンよりも新しいものにすることはできません。また、コントロールプレーンの Kubernetes バージョンより 3 つ以上前のマイナーなバージョンにすることもできません。コントロールプレーンと同じバージョンを使用することをお勧めします。

    K8S_VERSION=1.27 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 つのレプリカにスケールアウトします。前のコマンドで、その出力が返された場合は、corednskubedns に置き換えます。

    kubectl scale deployments/coredns --replicas=2 -n kube-system
  11. 次のコマンドを使用して、クラスターから削除する各ノードをドレーンします。

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

    ノードを新しい Kubernetes バージョンにアップグレードする場合は、次のコードスニペットを使用して、特定の Kubernetes バージョン (この場合は 1.27) のすべてのノードを識別してドレーンします。

    K8S_VERSION=1.27 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. https://console.aws.amazon.com/cloudformation で AWS CloudFormation コンソール を開きます。

    3. 古いノードスタックを選択します。

    4. [削除] をクリックします。

    5. [スタックの削除] 確認ダイアログボックスで、[スタックを削除] をクリックします。

  13. 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 を適用するには、ファイルを保存して閉じます。

  14. (オプション) Kubernetes Cluster Autoscaler を使用している場合は、デプロイメントのスケーリングを 1 レプリカに戻します。

    注記

    必要に応じて、新しい Auto Scaling グループにタグ (k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster など) を付け、新しくタグ付けした Auto Scaling グループを参照するように、Cluster Autoscaler デプロイメントのコマンドを更新する必要があります。詳細については、「AWS の Cluster Autoscaler」を参照してください。

    kubectl scale deployments/cluster-autoscaler --replicas=1 -n kube-system
  15. (オプション) 最新バージョンの Amazon VPC CNI Plugin for Kubernetes を使用していることを確認します。サポートされている最新のインスタンスタイプを利用するには、CNI のバージョンを更新することが必要になる場合があります。詳細については、「Amazon VPC CNI plugin for Kubernetes Amazon EKS アドオンの使用」を参照してください。

  16. クラスターの DNS 解決 (前のステップを参照) に kube-dns を使用している場合は、kube-dns デプロイメントを 1 レプリカにスケーリングしてください。

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