

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

# CI/CD パイプラインを使用して Amazon EKS へのノード終了ハンドラーのデプロイを自動化する
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline"></a>

*Amazon Web Services、Sandip Gangapadhyay、Sandeep Gawande、Viyoma Sachdeva、Pragtideep Singh、John Vargas*

## 概要
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-summary"></a>

**注意**: AWS CodeCommit の新規のお客様への提供は終了しています。AWS CodeCommit の既存のお客様は、引き続きサービスをご利用いただけます。[詳細はこちら](https://aws.amazon.com/blogs/devops/how-to-migrate-your-aws-codecommit-repository-to-another-git-provider/)

Amazon Web Services (AWS) クラウドでは、オープンソースプロジェクトの「[AWS Node Termination Handler](https://github.com/aws/aws-node-termination-handler)」を使用して、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのシャットダウンを正常に処理できます。AWS Node Termination Handler は、EC2 インスタンスが使用できなくなる原因となるイベントに Kubernetes コントロールプレーンが適切に対応できるようにするのに役立ちます。下記のイベントには、次が含まれます。
+ 「[EC2 インスタンスの定期メンテナンス](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html)」
+ 「[Amazon EC2 スポットインスタンスの中断](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html)」 
+ 「[Auto Scaling グループのスケールイン](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html#as-lifecycle-scale-in)」
+ アベイラビリティーゾーン間の 「[Auto Scaling グループのリバランシング](https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-benefits.html#AutoScalingBehavior.InstanceUsage)」
+ API または AWS マネジメントコンソールによる EC2 インスタンスの終了

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

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

**注記**  
[EKS マネージドノードグループ](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)を使用している場合は、`aws-node-termination-handler` は必要ありません。

## 前提条件と制限事項
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント。
+ AWS マネジメントコンソールでの使用がサポートされているウェブブラウザ。「[サポートされるブラウザのリスト](https://aws.amazon.com/premiumsupport/knowledge-center/browsers-management-console/)」を参照してください。
+ 「[インストール済み](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install)」の AWS Cloud Development Kit (AWS CDK)
+ `kubectl`、Kubernetes コマンドラインツールが 「[インストール](https://kubernetes.io/docs/tasks/tools/)」されています。
+ `eksctl`、Amazon Elastic Kubernetes Service (Amazon EKS) の AWS コマンドラインインターフェイス (AWS CLI) が「[インストール](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html)」されています。
+ バージョン 1.20 以降の稼動中の EKS クラスター
+ EKS クラスターに接続されているセルフマネージド型ノードグループ。自己管理型ノードグループで Amazon EKS クラスターを作成するには、以下のコマンドを実行します。

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

  `eksctl` の詳細については、「[eksctl のドキュメント](https://eksctl.io/usage/creating-and-managing-clusters/)」を参照してください。
+ クラスターAWS Identity and Access Management (IAM) OpenID Connect (OIDC) プロバイダー 詳細について、「[クラスターの IAM プロバイダーを作成する](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)」を参照してください。

**制限事項**
+ Amazon EKS サービスをサポートする AWS リージョンを使用する必要があります。

**製品バージョン**
+ Kubernetes バージョン 1.20 以降　
+ `eksctl` バージョン 0.107.0 以降
+ AWS CDK バージョン 2.27.0 またはそれ以降

## アーキテクチャ
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-architecture"></a>

**ターゲットテクノロジースタック**
+ 仮想プライベートクラウド (VPC)
+ EKS クラスター
+ Amazon Simple Queue Service (Amazon SQS)
+ IAM
+ Kubernetes

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

次のダイアグラム表は、ノード終了が開始されたときのエンドツーエンドステップのハイレベルビューです。

![Auto Scaling グループを持つ VPC、ノード終了ハンドラーを持つ EKS クラスター、SQS キュー。](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/970dfb73-9526-4942-a974-e8eef6416596/images/9e0125ae-d55b-49dd-ae70-ccaedf03832a.png)


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

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

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

1. NTH ポッドは新しいメッセージを受信し、以下を実行します。
   + 新しいポッドがノード上で実行されないように、ノードをコード化します。
   + ノードをドレインし、既存のポッドを退避させます。
   + ライフサイクルフックシグナルを Auto Scaling グループに送信して、ノードを終了できるようにします。

**自動化とスケール**
+ コードは AWS CloudFormation のネストスタックによって支えられた AWS CDK によって管理およびデプロイされます。
+ 「[Amazon EKS コントロールプレーン](https://docs.aws.amazon.com/eks/latest/userguide/disaster-recovery-resiliency.html)」は、複数のアベイラビリティーゾーンで実行され、高可用性を保証します。
+ 「[自動スケーリング](https://docs.aws.amazon.com/eks/latest/userguide/autoscaling.html)」については、Amazon EKS は Kubernetes「[クラスター](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)」オートスケーラーと「[Karpenter](https://karpenter.sh/)」をサポートしています。

## ツール
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-tools"></a>

**AWS サービス**
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html) は、AWS クラウドインフラストラクチャをコードで定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。
+ [AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) はフルマネージドの構築サービスです。ソースコードのコンパイル、ユニットテストの実行、すぐにデプロイできるアーティファクトの生成を行います。
+ [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) は、独自のソースコントロールシステムを管理しなくても、Git リポジトリを非公開で保存および管理できるバージョン管理サービスです。
+ [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) は、ソフトウェアリリースのさまざまな段階を迅速にモデル化および設定し、ソフトウェアの変更を継続的にリリースするために必要なステップを自動化するのに役立ちます。
+ 「[Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)」は、AWS で Kubernetes を実行する際に役立ち、独自の Kubernetes コントロールプレーンまたはノードをインストールまたは維持する必要はありません。
+ 「[Amazon EC2 Auto Scaling](https://docs.aws.amazon.com/autoscaling/ec2/userguide/what-is-amazon-ec2-auto-scaling.html)」は、定義した条件に従って、Amazon EC2 インスタンスを自動的に追加または削除できるように、アプリケーションの可用性を維持するのに役立ちます。
+ 「[Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html)」は、分散したソフトウェアシステムとコンポーネントの統合と切り離しを支援し、セキュアで耐久性があり、利用可能なホスト型キューを提供します。

その他のツール
+ 「[kubectl](https://kubernetes.io/docs/reference/kubectl/kubectl/)」は、 Kubernetes クラスターに対してコマンドを実行するための Kubernetes コマンドラインツールです。kubectl を使用して、アプリケーションのデプロイ、クラスターリソースの検査と管理、ログの表示を行うことができます。

**コード**

このパターンのコードは、GitHub 内の「[deploy-nth-to-eks](https://github.com/aws-samples/deploy-nth-to-eks)」リポジトリで利用できます。コードリポジトリには、以下のファイルとフォルダが含まれます。
+ `nth folder` — ノード終了ハンドラー用の AWS CloudFormation テンプレートをスキャンしてデプロイするためのHelm チャート、値ファイル、スクリプト。
+ `config/config.json` — アプリケーションの設定パラメータファイル。このファイルには、CDK のデプロイに必要なすべてのパラメーターが含まれています。
+ `cdk` — AWS CDK のソースコード。
+ `setup.sh` — AWS CDK アプリケーションをデプロイして必要な CI/CD パイプラインとその他の必要なリソースを作成するために使用されるスクリプト。
+ `uninstall.sh` — リソースをクリーンアップするために使用されるスクリプト。

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

## ベストプラクティス
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-best-practices"></a>

AWS ノード終了ハンドラーを自動化する際のベストプラクティスについては、以下を参照してください。
+ [ EKS ベストプラクティスガイド](https://aws.github.io/aws-eks-best-practices/)
+ 「[ノード終了ハンドラー-設定](https://github.com/aws/aws-node-termination-handler/tree/main/config/helm/aws-node-termination-handler)」

## エピック
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-epics"></a>

### 環境をセットアップします。
<a name="set-up-your-environment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リポジトリを変更します。 | SSH (セキュアシェル) を使用してリポジトリをクローンするには、以下のコマンドを実行します。<pre>git clone git@github.com:aws-samples/deploy-nth-to-eks.git</pre><br />HTTPSを使用して、リポジトリを複製して、以下のコマンドを実行します。<pre>git clone https://github.com/aws-samples/deploy-nth-to-eks.git</pre><br />リポジトリを複製すると、`deploy-nth-to-eks` という名前のフォルダーが作成されます。<br />そのディレクトリに変更します。<pre>cd deploy-nth-to-eks</pre> | アプリ開発者、AWS DevOps、DevOps エンジニア | 
| kubeconfig ファイルを設定します。 | ターミナルで AWS 認証情報を設定し、クラスターロールを引き受ける権限があることを確認します。次の例のコードを使用できます。<pre>aws eks update-kubeconfig --name <Cluster_Name> --region <region>--role-arn <Role_ARN></pre> | AWS DevOps、DevOps エンジニア、App 開発者 | 

### CI/CD パイプラインをデプロイする
<a name="deploy-the-ci-cd-pipeline"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| パラメータをセットアップします。 | `config/config.json` ファイルで、以下の必須パラメータを設定します。[See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html) | アプリ開発者、AWS DevOps、DevOps エンジニア | 
| NTH をデプロイする CI/CD パイプラインを作成します。 | setup.sh スクリプトを実行します。<pre>./setup.sh</pre><br />このスクリプトは、`config/config.json` ファイル内のユーザー入力パラメータに基づいてサンプルコード、パイプライン、および CodeBuild プロジェクトを含む CodeCommit リポジトリを作成する AWS CDK アプリケーションをデプロイします。<br />このスクリプトは sudo コマンドで npm パッケージをインストールする際にパスワードを要求します。 | アプリ開発者、AWS DevOps、DevOps エンジニア | 
| CI/CD パイプラインを確認します。 | AWS マネジメントコンソールを開き、スタックに作成された以下のリソースを確認します。[See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html)<br />パイプラインが正常に実行された後、Helm release `aws-node-termination-handler` が EKS クラスターにインストールされます。また、`aws-node-termination-handler` という名前のポッドがクラスターの `kube-system` 名前空間で実行されています。 | アプリ開発者、AWS DevOps、DevOps エンジニア | 

### NTH デプロイをテスト
<a name="test-nth-deployment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Auto Scaling グループのスケールインイベントをシミュレートします。 | 自動スケーリングスケールインイベントをシミュレートするには、以下を実行します。[See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html) |  | 
| ログを見直します。 | スケールインイベント中、NTH ポッドは対応するワーカーノード (スケールインイベントの一部として終了する EC2 インスタンス) をコードオンしてドレインします。ログを確認するには、*追加情報*セクションのコードを使用してください。 | アプリ開発者、AWS DevOps、DevOps エンジニア | 

### クリーンアップ
<a name="clean-up"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| すべての AWS リソースをクリーンアップします。 | このパターンで作成されたリソースをクリーンアップするには、以下のコマンドを実行します。<pre>./uninstall.sh</pre><br />これにより、CloudFormation スタックが削除され、このパターンで作成されたすべてのリソースがクリーンアップされます。 | DevOps エンジニア | 

## トラブルシューティング
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-troubleshooting"></a>


| 問題 | ソリューション | 
| --- | --- | 
| npm レジストリが正しく設定されていません。 | このソリューションのインストール中、スクリプトは npm install をインストールして、必要なパッケージをすべてダウンロードします。インストール中に「モジュールが見つかりません」というメッセージが表示された場合は、npm レジストリが正しく設定されていない可能性があります。以下のコマンドを実行して、現在のレジストリ設定を確認します。<pre>npm config get registry</pre><br />以下のコマンドを実行して、 `https://registry.npmjs.org/` でレジストリを設定します。<pre>npm config set registry https://registry.npmjs.org</pre> | 
| SQS メッセージの配信を遅らせる。 | トラブルシューティングの一環として、NTH ポッドへの SQS メッセージ配信を遅延させたい場合は、SQS 配信遅延パラメータを調整できます。詳細については、「[Amazon SQS ディレイキュー](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html)」を参照してください。 | 

## 関連リソース
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-resources"></a>
+ 「[AWS ノード終了ハンドラーのソースコード](https://github.com/aws/aws-node-termination-handler)」
+ 「[EC2 ワークショップ](https://ec2spotworkshops.com/using_ec2_spot_instances_with_eks/070_selfmanagednodegroupswithspot/deployhandler.html)」
+ [AWS CodePipeline](https://aws.amazon.com/codepipeline/)
+ [Amazon Elastic Kubernetes Service (Amazon EKS)](https://aws.amazon.com/eks/)
+ 「[AWS クラウド開発キット](https://aws.amazon.com/cdk/)」
+ [AWS CloudFormation](https://aws.amazon.com/cloudformation/)

## 追加情報
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-additional"></a>

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
```