

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 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, Viyoma 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는 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 Management Console을 통한 EC2 인스턴스 종료

이벤트가 처리되지 않으면 애플리케이션 코드가 적절하게 중지되지 않을 수 있습니다. 또한 전체 가용성을 복구하는 데 시간이 더 오래 걸리거나 다운되는 노드에 실수로 작업을 예약할 수도 있습니다. `aws-node-termination-handler` (NTH)는 인스턴스 메타데이터 서비스(IMDS)또는 대기열 프로세서라는 두 가지 모드로 작동할 수 있습니다. 두 모드에 대한 자세한 내용은 [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 Management Console에서 사용할 수 있도록 지원되는 웹 브라우저. [지원되는 브라우저 목록](https://aws.amazon.com/premiumsupport/knowledge-center/browsers-management-console/)을 참조하세요.
+ AWS Cloud Development Kit(AWS CDK)가 [설치됨](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install).
+ `kubectl`, Kubernetes 명령줄 도구가 [설치됨](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).
+ 버전 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 이상

## 아키텍처
<a name="automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline-architecture"></a>

**대상 기술 스택  **
+ Virtual Private Cloud(VPC)
+ EKS 클러스터
+ Amazon Simple Queue Service(Amazon SQS)
+ IAM
+ Kubernetes

**대상 아키텍처**** **

다음 다이어그램은 노드 종료가 시작될 때의 엔드-투-엔드의 개괄적인 뷰를 보여줍니다.

![\[Auto Scaling 그룹을 사용한 VPC, 노드 종료 핸들러를 사용한 EKS 클러스터 및 SQS 대기열.\]](http://docs.aws.amazon.com/ko_kr/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 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 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)는 자체 Kubernetes 컨트롤 플레인이나 노드를 설치하거나 유지 관리할 필요 없이 AWS에서 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.com의 [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` - 필수 CI/CD 파이프라인 및 기타 필수 리소스를 생성하기 위해 AWS CDK 애플리케이션을 배포하는 데 사용되는 스크립트입니다.
+ `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>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>


| 작업 | 설명 | 필요한 기술 | 
| --- | --- | --- | 
| 파라미터를 설정합니다. | `config/config.json` 파일에서 다음과 같은 필수 파라미터를 설정합니다.[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/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>스크립트는 `config/config.json` 파일의 사용자 입력 파라미터를 기반으로 예제 코드, 파이프라인, CodeBuild 프로젝트가 포함된 CodeCommit 리포지토리를 생성하는 AWS CDK 애플리케이션을 배포합니다.이 스크립트는 sudo 명령으로 npm 패키지를 설치할 때 암호를 묻습니다. | 앱 개발자, AWS DevOps, DevOps 엔지니어 | 
| CI/CD 파이프라인을 검토합니다. | AWS Management Console을 열고 스택에 생성된 다음 리소스를 검토하세요.[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/patterns/automate-deployment-of-node-termination-handler-in-amazon-eks-by-using-a-ci-cd-pipeline.html)파이프라인이 성공적으로 실행되면 EKS 클러스터에 Helm 릴리스 `aws-node-termination-handler`(이)가 설치됩니다. 또한 클러스터의 `kube-system` 네임스페이스에서 `aws-node-termination-handler` 이름의 포드가 실행 중입니다. | 앱 개발자, 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/ko_kr/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>


| 작업 | 설명 | 필요한 기술 | 
| --- | --- | --- | 
| 모든 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>


| 문제 | Solution | 
| --- | --- | 
| npm 레지스트리가 올바르게 설정되지 않았습니다. | 이 솔루션을 설치하는 동안 스크립트는 npm install을 설치하여 필수 패키지를 모두 다운로드합니다. 설치 중에 “모듈을 찾을 수 없습니다”라는 메시지가 표시되면 npm 레지스트리가 올바르게 설정되지 않은 것일 수 있습니다. 현재 레지스트리 설정을 확인하려면 다음 명령을 실행합니다.<pre>npm config get registry</pre>`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 Cloud Development Kit](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 포드 이름을 찾습니다.

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