

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 CI/CD 管道在 Amazon EKS 中自動化節點終止處理常式的部署
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline"></a>

*Sandip Gangapadhyay、Sandeep Gawande、Vyoma Sachdeva、Pragtideep Singh 和 John Vargas，Amazon Web Services*

## 總結
<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)，正常處理 Kubernetes 內的 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體關閉。AWS Node Termination Handler 有助於確保 Kubernetes 控制平面適當回應可能導致 EC2 執行個體無法使用的事件。這類事件包括下列項目：
+ [EC2 執行個體排程維護](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html)
+ [Amazon EC2 Spot 執行個體中斷](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) 或佇列處理器。如需這兩種模式的詳細資訊，請參閱[讀我檔案](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 管理主控台使用的 Web 瀏覽器。請參閱[支援的瀏覽器清單](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 雲端開發套件 (AWS CDK)。
+ `kubectl`已安裝 Kubernetes 命令列工具[https://kubernetes.io/docs/tasks/tools/](https://kubernetes.io/docs/tasks/tools/)。
+ `eksctl`已安裝適用於 Amazon Elastic Kubernetes Service (Amazon EKS) 的 AWS Command Line Interface (AWS CLI)[https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html](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 OIDC 提供者](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 版或更新版本

## Architecture
<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

**目標架構******

下圖顯示節點終止開始時end-to-end步驟的高階檢視。

![\[具有 Auto Scaling 群組的 VPC、具有 Node Termination Handler 的 EKS 叢集，以及 SQS 佇列。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/970dfb73-9526-4942-a974-e8eef6416596/images/9e0125ae-d55b-49dd-ae70-ccaedf03832a.png)


圖表中顯示的工作流程包含下列高階步驟：

1. 自動擴展 EC2 執行個體終止事件會傳送至 SQS 佇列。

1. NTH Pod 會監控 SQS 佇列中的新訊息。

1. NTH Pod 會收到新訊息並執行下列動作：
   + 繫結節點，讓新的 Pod 不會在節點上執行。
   + 耗盡節點，以清空現有的 Pod
   + 將生命週期掛鉤訊號傳送至 Auto Scaling 群組，以便終止節點。

**自動化和擴展**
+ 程式碼由 AWS CDK 管理和部署，並由 AWS CloudFormation 巢狀堆疊提供支援。
+ [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 [Cluster Autoscaler](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 雲端開發套件 (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 來部署應用程式、檢查和管理叢集資源，以及檢視日誌。

**Code**

此模式的程式碼可在 GitHub.com 的 [deploy-nth-to-eks](https://github.com/aws-samples/deploy-nth-to-eks) 儲存庫中取得。 GitHub.com. 程式碼儲存庫包含下列檔案和資料夾。
+ `nth folder` – 用於掃描和部署節點終止處理常式之 AWS CloudFormation 範本的 Helm Chart、值檔案和指令碼。
+ `config/config.json` – 應用程式的組態參數檔案。此檔案包含部署 CDK 所需的所有參數。
+ `cdk` – AWS CDK 原始碼。
+ `setup.sh` – 用來部署 AWS CDK 應用程式的指令碼，用來建立必要的 CI/CD 管道和其他必要的資源。
+ `uninstall.sh` – 用來清除資源的指令碼。

若要使用範例程式碼，請遵循 *Epics* 區段中的指示。

## 最佳實務
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-best-practices"></a>

如需自動化 AWS Node Termination Handler 時的最佳實務，請參閱下列各項：
+ [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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 複製儲存庫。 | 若要使用 SSH （安全殼層） 複製儲存庫，請執行下列命令。<pre>git clone git@github.com:aws-samples/deploy-nth-to-eks.git</pre>若要使用 HTTPS 複製儲存庫，請執行下列命令。<pre>git clone https://github.com/aws-samples/deploy-nth-to-eks.git</pre>複製儲存庫會建立名為 的資料夾`deploy-nth-to-eks`。變更為該目錄。<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 工程師、應用程式開發人員 | 

### 部署 CI/CD 管道
<a name="deploy-the-ci-cd-pipeline"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 設定參數。 | 在 `config/config.json`檔案中，設定下列必要參數。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html) | 應用程式開發人員、AWS DevOps、DevOps 工程師 | 
| 建立 CI/CD 管道以部署 NTH。 | 執行 setup.sh 指令碼。<pre>./setup.sh</pre>指令碼將部署 AWS CDK 應用程式，該應用程式將根據`config/config.json`檔案中的使用者輸入參數，使用範例程式碼、管道和 CodeBuild 專案來建立 CodeCommit 儲存庫。此指令碼會在使用 sudo 命令安裝 npm 套件時要求密碼。 | 應用程式開發人員、AWS DevOps、DevOps 工程師 | 
| 檢閱 CI/CD 管道。 | 開啟 AWS 管理主控台，並檢閱在堆疊中建立的下列資源。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html)管道成功執行後，Helm Release `aws-node-termination-handler` 會安裝在 EKS 叢集中。此外，名為 的 Pod `aws-node-termination-handler` 正在叢集的`kube-system`命名空間中執行。 | 應用程式開發人員、AWS DevOps、DevOps 工程師 | 

### 測試 NTH 部署
<a name="test-nth-deployment"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 模擬 Auto Scaling 群組縮減事件。 | 若要模擬自動擴展縮減事件，請執行下列動作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html) |  | 
| 檢閱日誌。 | 在縮減事件期間，NTH Pod 會封鎖並耗盡對應的工作者節點 （將在縮減事件中終止的 EC2 執行個體）。若要檢查日誌，請使用*其他資訊*區段中的程式碼。 | 應用程式開發人員、AWS DevOps、DevOps 工程師 | 

### 清除
<a name="clean-up"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 清除所有 AWS 資源。 | 若要清除此模式建立的資源，請執行下列命令。<pre>./uninstall.sh</pre>這將透過刪除 CloudFormation 堆疊來清除在此模式中建立的所有資源。 | DevOps 工程師 | 

## 疑難排解
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| npm 登錄檔設定不正確。 | 在此解決方案的安裝期間，指令碼會安裝 npm 安裝以下載所有必要的套件。如果在安裝期間，您看到一則訊息，指出「找不到模組」npm 登錄檔可能設定不正確。若要查看目前的登錄設定，請執行下列命令。<pre>npm config get registry</pre>若要使用 設定登錄檔`https://registry.npmjs.org/`，請執行下列命令。<pre>npm config set registry https://registry.npmjs.org</pre> | 
| 延遲 SQS 訊息傳遞。 | 在疑難排解過程中，如果您想要延遲 SQS 訊息交付至 NTH Pod，您可以調整 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. 尋找 NTH Pod 名稱。

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