CI/CD パイプラインを使用して Amazon EKS へのノード終了ハンドラーのデプロイを自動化する - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

CI/CD パイプラインを使用して Amazon EKS へのノード終了ハンドラーのデプロイを自動化する

Sandip Gangapadhyay (AWS)、John Vargas (AWS)、Pragtideep Singh (AWS)、Sandeep Gawande (AWS)、Viyoma Sachdeva (AWS) によって作成されました

コードリポジトリ: NTH を EKS にデプロイする

環境:本稼働

テクノロジー: コンテナとマイクロサービス DevOps

AWS サービス: AWS CodePipeline、Amazon EKS、AWS CodeBuild

[概要]

Amazon Web Services (AWS) クラウドでは、オープンソースプロジェクトの「AWS Node Termination Handler」を使用して、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのシャットダウンを正常に処理できます。AWS Node Termination Handler は、EC2 インスタンスが使用できなくなる原因となるイベントに Kubernetes コントロールプレーンが適切に対応できるようにするのに役立ちます。下記のイベントには、次が含まれます。

イベントが処理されないと、アプリケーションコードが正常に停止しない可能性があります。また、完全な可用性を回復するまでに時間がかかったり、ダウンしているノードに誤って作業をスケジューリングしてしまうこともあります。aws-node-termination-handler (NTH) は、インスタンスメタデータサービス (IMDS) とキュープロセッサの 2 つの異なるモードで動作できます。二つのノードについての詳細情報については、「Readme ファイル」を参照してください。

このパターンでは、継続的インテグレーションおよび継続的デリバリー (CI/CD) パイプラインを通じてキュープロセッサを使用して、NTHのデプロイを自動化します。

注:「EKS マネージドノードグループ」を使用している場合は、aws-node-termination-handler は必要ありません。

前提条件と制限

前提条件

  • アクティブな AWS アカウント。

  • AWS マネジメントコンソールでの使用がサポートされているウェブブラウザ。「サポートされるブラウザのリスト」を参照してください。

  • インストール済み」の AWS Cloud Development Kit (AWS CDK)

  • kubectl、Kubernetes コマンドラインツールが 「インストール」されています。

  • eksctl、Amazon Elastic Kubernetes Service (Amazon EKS) の AWS コマンドラインインターフェイス (AWS CLI) が「インストール」されています。

  • バージョン 1.20 以降の稼動中の EKS クラスター

  • EKS クラスターに接続されているセルフマネージド型ノードグループ。自己管理型ノードグループで Amazon EKS クラスターを作成するには、以下のコマンドを実行します。

    eksctl create cluster --managed=false --region <region> --name <cluster_name>

    eksctl の詳細については、「eksctl のドキュメント」を参照してください。

  • クラスターAWS Identity and Access Management (IAM) OpenID Connect (OIDC) プロバイダー 詳細について、「クラスターの IAM プロバイダーを作成する」を参照してください。

制約事項

  • Amazon EKS サービスをサポートする AWS リージョンを使用する必要があります。

製品バージョン

  • Kubernetes バージョン 1.20 以降 

  • eksctl バージョン 0.107.0 以降

  • AWS CDK バージョン 2.27.0 またはそれ以降

アーキテクチャ

ターゲットテクノロジースタック

  • 仮想プライベートクラウド (VPC)

  • EKS クラスター

  • Amazon Simple Queue Service (Amazon SQS)

  • IAM

  • Kubernetes

ターゲットアーキテクチャ

次の図は、ノードの終了が開始されたときの end-to-end ステップの概要を示しています。

Auto Scaling グループを持つ VPC、ノード終了ハンドラーを持つ EKS クラスター、SQS キュー。

このダイアグラムに示されているワークフローは、以下の大まかなステップで構成されています。

  1. 自動スケーリングの EC2 インスタンス終了イベントは SQS キューに送信されます。

  2. NTH ポッドは SQS キュー内の新しいメッセージを監視します。

  3. NTH ポッドは新しいメッセージを受信し、以下を実行します。

    • 新しいポッドがノード上で実行されないように、ノードをコード化します。

    • ノードをドレインし、既存のポッドを退避させます。

    • ライフサイクルフックシグナルを Auto Scaling グループに送信して、ノードを終了できるようにします。

自動化とスケール

  • コードは AWS CDK によって管理およびデプロイされ、AWS CloudFormation ネストされたスタックによってバックアップされます。

  • Amazon EKS コントロールプレーン」は、複数のアベイラビリティーゾーンで実行され、高可用性を保証します。

  • 自動スケーリング」については、Amazon EKS は Kubernetes「クラスター」オートスケーラーと「カーペンター」をサポートしています。

ツール

AWS サービス

  • AWS Cloud Development Kit (AWS CDK) は、AWS クラウドインフラストラクチャをコードで定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。

  • AWS CodeBuild は、ソースコードをコンパイルし、ユニットテストを実行し、すぐにデプロイできるアーティファクトを生成するのに役立つフルマネージドビルドサービスです。

  • AWS CodeCommit は、独自のソース管理システムを管理することなく、Git リポジトリをプライベートに保存および管理できるバージョン管理サービスです。

  • AWS CodePipeline を使用すると、ソフトウェアリリースのさまざまな段階を迅速にモデル化して設定し、ソフトウェアの変更を継続的にリリースするために必要なステップを自動化できます。

  • Amazon Elastic Kubernetes Service (Amazon EKS)」は、AWS で Kubernetes を実行する際に役立ち、独自の Kubernetes コントロールプレーンまたはノードをインストールまたは維持する必要はありません。

  • Amazon EC2 Auto Scaling」は、定義した条件に従って、Amazon EC2 インスタンスを自動的に追加または削除できるように、アプリケーションの可用性を維持するのに役立ちます。

  • Amazon Simple Queue Service (Amazon SQS)」は、分散したソフトウェアシステムとコンポーネントの統合と切り離しを支援し、セキュアで耐久性があり、利用可能なホスト型キューを提供します。

その他のツール

  • kubectl」は、 Kubernetes クラスターに対してコマンドを実行するための Kubernetes コマンドラインツールです。kubectl を使用して、アプリケーションのデプロイ、クラスターリソースの検査と管理、ログの表示を行うことができます。

コード

このパターンのコードは、.com の deploy-nth-to-eks repo にあります GitHub。コードリポジトリには、以下のファイルとフォルダが含まれます。

  • nth folder – Helm チャート、値ファイル、およびノード終了ハンドラーの AWS CloudFormation テンプレートをスキャンしてデプロイするスクリプト。

  • config/config.json — アプリケーションの設定パラメータファイル。このファイルには、CDK のデプロイに必要なすべてのパラメーターが含まれています。

  • cdk — AWS CDK のソースコード。

  • setup.sh — AWS CDK アプリケーションをデプロイして必要な CI/CD パイプラインとその他の必要なリソースを作成するために使用されるスクリプト。

  • uninstall.sh — リソースをクリーンアップするために使用されるスクリプト。

例のコードを使用するには、エピックセクションの指示に従います。

ベストプラクティス

AWS ノード終了ハンドラーを自動化する際のベストプラクティスについては、以下を参照してください。

エピック

タスク説明必要なスキル

リポジトリを変更します。

SSH (セキュアシェル) を使用してリポジトリをクローンするには、以下のコマンドを実行します。

git clone git@github.com:aws-samples/deploy-nth-to-eks.git

HTTPSを使用して、リポジトリを複製して、以下のコマンドを実行します。

git clone https://github.com/aws-samples/deploy-nth-to-eks.git

リポジトリを複製すると、deploy-nth-to-eks という名前のフォルダーが作成されます。

そのディレクトリに変更します。

cd deploy-nth-to-eks
アプリ開発者、AWS DevOps、 DevOps エンジニア

kubeconfig ファイルを設定します。

ターミナルで AWS 認証情報を設定し、クラスターロールを引き受ける権限があることを確認します。次の例のコードを使用できます。

aws eks update-kubeconfig --name <Cluster_Name> --region <region>--role-arn <Role_ARN>
AWS DevOps、 DevOps エンジニア、アプリ開発者
タスク説明必要なスキル

パラメータをセットアップします。

config/config.json ファイルで、以下の必須パラメータを設定します。

  • pipelineName: AWS CDK によって作成される CI/CD パイプラインの名前 (例:deploy-nth-to-eks-pipeline)。AWS CodePipeline はこの名前のパイプラインを作成します。

  • repositoryName: 作成する AWS CodeCommit リポジトリ (例: deploy-nth-to-eks-repo)。AWS CDK はこのリポジトリを作成し、CI/CD パイプラインのソースとして設定します。

    注: このソリューションは、この CodeCommit リポジトリとブランチを作成します (次のブランチパラメータで提供)。

  • branch: リポジトリ内のブランチ名 (例:main)。このブランチにコミットすると、CI/CD パイプラインが開始されます。

  • cfn_scan_script: NTH の AWS CloudFormation テンプレートをスキャンするために使用されるスクリプトのパス (scan.sh)。このスクリプトは、AWS CodeCommit リポジトリの一部となるnthフォルダに存在します。

  • cfn_deploy_script: NTH の AWS CloudFormation テンプレートのデプロイに使用されるスクリプトのパス (installApp.sh)。

  • stackName: デプロイする CloudFormation スタックの名前。

  • eksClusterName - 既存の EKS クラスターの名前。

  • eksClusterRole: すべての Kubernetes API 呼び出しで EKS クラスターにアクセスするために使用される IAM ロール (例:clusteradmin)。通常、このロールは aws-auth ConfigMap 追加されます。

  • create_cluster_role: eksClusterRole IAM ロールを作成するには、yes と入力します。eksClusterRole パラメータに既存のクラスターロールを指定する場合は、no と入力します。

  • create_iam_oidc_provider: クラスターの IAM OIDC プロバイダーを作成するには、はいを入力します。IAM OIDC プロバイダーが既に存在する場合は、no と入力します。詳細について、「クラスターの IAM プロバイダーを作成する」 を参照してください。

  • AsgGroupName: EKS クラスターの一部である Auto Scaling グループ名をカンマで区切ったリスト(例:ASG_Group_1,ASG_Group_2)。

  • region: クラスターが配置されている AWS リージョンの名前 (例: us-east-2)。

  • install_cdk: AWS CDK が現在マシンにインストールされていない場合は、yes と入力します。cdk --version コマンドを実行して、インストールされている AWS CDK のバージョンが 2.27.0 以降かどうかを確認します。その場合は no と入力します。

    yes と入力すると、setup.sh sudo npm install -g cdk@2.27.0 スクリプトはコマンドを実行して AWS CDK をマシンにインストールします。このスクリプトには sudo 権限が必要なので、プロンプトが表示されたらアカウントパスワードを入力します。

アプリ開発者、AWS DevOps、 DevOps エンジニア

NTH をデプロイする CI/CD パイプラインを作成します。

setup.sh スクリプトを実行します。

./setup.sh

このスクリプトは AWS CDK アプリケーションをデプロイし、config/config.jsonファイル内のユーザー入力パラメータに基づいてサンプルコード、パイプライン、 CodeBuild プロジェクトを含む CodeCommit リポジトリを作成します。

このスクリプトは sudo コマンドで npm パッケージをインストールする際にパスワードを要求します。

アプリ開発者、AWS DevOps、 DevOps エンジニア

CI/CD パイプラインを確認します。

AWS マネジメントコンソールを開き、スタックに作成された以下のリソースを確認します。

  • CodeCommit nthフォルダの内容を含む リポジトリ

  • AWS CodeBuild プロジェクト cfn-scan。 CloudFormation テンプレートの脆弱性をスキャンします。

  • CodeBuild プロジェクト Nth-Deploy。AWS CloudFormation テンプレートと対応する NTH Helm チャートを AWS CodePipeline パイプライン経由でデプロイします。

  • NTH をデプロイする CodePipeline パイプライン。

パイプラインが正常に実行された後、Helm release aws-node-termination-handler が EKS クラスターにインストールされます。また、aws-node-termination-handler という名前のポッドがクラスターの kube-system 名前空間で実行されています。

アプリ開発者、AWS DevOps、 DevOps エンジニア
タスク説明必要なスキル

Auto Scaling グループのスケールインイベントをシミュレートします。

自動スケーリングスケールインイベントをシミュレートするには、以下を実行します。

  1. AWS コンソールで EC2 コンソールを開き、[Auto Scaling グループ] を選択します。

  2. config/config.json で指定されているものと同じ名前の Auto Scaling グループを選択し、編集を選択します。

  3. 必要容量と最小容量を 1 ずつ減らします。

  4. [更新] を選択します。

ログを見直します。

スケールインイベント中、NTH ポッドは対応するワーカーノード (スケールインイベントの一部として終了する EC2 インスタンス) をコードオンしてドレインします。ログを確認するには、追加情報セクションのコードを使用してください。

アプリ開発者、AWS DevOps、 DevOps エンジニア
タスク説明必要なスキル

すべての AWS リソースをクリーンアップします。

このパターンで作成されたリソースをクリーンアップするには、以下のコマンドを実行します。

./uninstall.sh

これにより、 CloudFormation スタックを削除することで、このパターンで作成されたすべてのリソースがクリーンアップされます。

DevOps エンジニア

トラブルシューティング

問題ソリューション

npm レジストリが正しく設定されていません。

このソリューションのインストール中、スクリプトは npm install をインストールして、必要なパッケージをすべてダウンロードします。インストール中に「モジュールが見つかりません」というメッセージが表示された場合は、npm レジストリが正しく設定されていない可能性があります。以下のコマンドを実行して、現在のレジストリ設定を確認します。

npm config get registry

以下のコマンドを実行して、 https://registry.npmjs.org/ でレジストリを設定します。

npm config set registry https://registry.npmjs.org

SQS メッセージの配信を遅らせる。

トラブルシューティングの一環として、NTH ポッドへの SQS メッセージ配信を遅延させたい場合は、SQS 配信遅延パラメータを調整できます。詳細については、「Amazon SQS ディレイキュー」を参照してください。

関連リソース

追加情報

1. N 番目のポッド名を検出します。

kubectl get pods -n kube-system |grep aws-node-termination-handler aws-node-termination-handler-65445555-kbqc7 1/1 Running 0 26m kubectl get pods -n kube-system |grep aws-node-termination-handler aws-node-termination-handler-65445555-kbqc7 1/1 Running 0 26m

2. ログの確認 次のようなログの例があります。Auto Scaling グループのライフサイクルフック完了シグナルを送信する前に、ノードが封鎖され、排水されたことを示しています。

kubectl -n kube-system logs aws-node-termination-handler-65445555-kbqc7 022/07/17 20:20:43 INF Adding new event to the event store event={"AutoScalingGroupName":"eksctl-my-cluster-target-nodegroup-ng-10d99c89-NodeGroup-ZME36IGAP7O1","Description":"ASG Lifecycle Termination event received. Instance will be interrupted at 2022-07-17 20:20:42.702 +0000 UTC \n","EndTime":"0001-01-01T00:00:00Z","EventID":"asg-lifecycle-term-33383831316538382d353564362d343332362d613931352d383430666165636334333564","InProgress":false,"InstanceID":"i-0409f2a9d3085b80e","IsManaged":true,"Kind":"SQS_TERMINATE","NodeLabels":null,"NodeName":"ip-192-168-75-60.us-east-2.compute.internal","NodeProcessed":false,"Pods":null,"ProviderID":"aws:///us-east-2c/i-0409f2a9d3085b80e","StartTime":"2022-07-17T20:20:42.702Z","State":""} 2022/07/17 20:20:44 INF Requesting instance drain event-id=asg-lifecycle-term-33383831316538382d353564362d343332362d613931352d383430666165636334333564 instance-id=i-0409f2a9d3085b80e kind=SQS_TERMINATE node-name=ip-192-168-75-60.us-east-2.compute.internal provider-id=aws:///us-east-2c/i-0409f2a9d3085b80e 2022/07/17 20:20:44 INF Pods on node node_name=ip-192-168-75-60.us-east-2.compute.internal pod_names=["aws-node-qchsw","aws-node-termination-handler-65445555-kbqc7","kube-proxy-mz5x5"] 2022/07/17 20:20:44 INF Draining the node 2022/07/17 20:20:44 ??? WARNING: ignoring DaemonSet-managed Pods: kube-system/aws-node-qchsw, kube-system/kube-proxy-mz5x5 2022/07/17 20:20:44 INF Node successfully cordoned and drained node_name=ip-192-168-75-60.us-east-2.compute.internal reason="ASG Lifecycle Termination event received. Instance will be interrupted at 2022-07-17 20:20:42.702 +0000 UTC \n" 2022/07/17 20:20:44 INF Completed ASG Lifecycle Hook (NTH-K8S-TERM-HOOK) for instance i-0409f2a9d3085b80e