Search

NTH

Node Termination Handler(NTH)는 AWS EKS 클러스터에서 EC2 인스턴스가 종료되거나 중단될 때 Kubernetes 클러스터의 안정성과 가용성을 유지하기 위해 사용된다.
NTH는 노드를 코든(cordon)하고 드레이닝(drain)하여 Pod를 안전하게 다른 노드로 이동시키는 역할을 한다.

NTH의 역할과 필요성

1.
EC2 인스턴스 종료 감지
NTH는 EC2 인스턴스가 종료되거나 중단될 때 이를 감지한다. 이는 Spot 인스턴스가 종료되거나 Auto Scaling 그룹의 인스턴스가 종료될 때 발생할 수 있다.
2.
노드 코든(Cordon)
목적: 노드를 코든하면 해당 노드에 새로운 Pod가 스케줄링되지 않도록 한다. 이는 노드가 종료되기 전에 새로운 작업이 해당 노드에 배치되지 않도록 하여, 종료 과정에서의 혼란을 최소화한다.
과정: NTH는 노드를 코든하여 새로운 Pod가 해당 노드에 배치되지 않도록 한다.
3.
노드 드레이닝(Drain)
목적: 노드를 드레이닝하면 해당 노드에서 실행 중인 모든 Pod를 안전하게 다른 노드로 이동시킨다. 이는 서비스 중단을 방지하고, 데이터 무결성을 유지하는 데 중요하다.
과정: NTH는 노드를 드레이닝하여 DaemonSet에 의해 관리되지 않는 모든 Pod를 다른 노드로 이동시킨다

NTH가 필요한 이유

1.
서비스 가용성 유지
EC2 인스턴스가 종료되거나 중단될 때, 해당 인스턴스에서 실행 중인 Pod가 다른 노드로 안전하게 이동하여 서비스 중단을 방지한다.
2.
데이터 무결성 유지
상태 저장 애플리케이션의 경우, 데이터를 안전하게 이동시키기 위해 드레이닝 과정을 거친다. 이를 통해 데이터 손실을 방지할 수 있다.
3.
자동화된 관리
NTH는 EC2 인스턴스 종료 이벤트를 자동으로 처리하여, 관리자의 개입 없이도 클러스터의 안정성 유지

예시 상황

1.
Spot 인스턴스 종료:
AWS는 Spot 인스턴스를 언제든지 회수할 수 있다. 이때 NTH는 Spot 인스턴스 종료 이벤트를 감지하고, 해당 인스턴스에서 실행 중인 Pod를 다른 노드로 이동시킨다.
2.
Auto Scaling 그룹 인스턴스 종료:
Auto Scaling 그룹의 인스턴스가 종료될 때, NTH는 이를 감지하고, 해당 인스턴스에서 실행 중인 Pod를 다른 노드로 이동시킨다.

NTH 생성

ENV
EKS_CLUSTER_NAME="<Cluster Name>" STACK_NAME="<STACK Name>" AUTO_SCALING_GROUP_NAME=$(aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[*].AutoScalingGroupName' --output text)
Shell
복사
CloudFormation template
curl -LO https://raw.githubusercontent.com/aws/aws-node-termination-handler/main/docs/cfn-template.yaml
Shell
복사
CloudFormation 스택 배포
aws cloudformation deploy \ --template-file ./cfn-template.yaml \ --stack-name $STACK_NAME
Shell
복사
Auto Scaling 그룹에 라이프사이클 훅 추가
aws autoscaling put-lifecycle-hook \ --lifecycle-hook-name=k8s-hook \ --auto-scaling-group-name=$AUTO_SCALING_GROUP_NAME \ --lifecycle-transition=autoscaling:EC2_INSTANCE_TERMINATING \ --default-result=CONTINUE \ --heartbeat-timeout=300
Shell
복사
Auto Scaling 그룹에 태그 추가
aws autoscaling create-or-update-tags \ --tags ResourceId=$AUTO_SCALING_GROUP_NAME,ResourceType=auto-scaling-group,Key=aws-node-termination-handler/managed,Value=,PropagateAtLaunch=true
Shell
복사
IAM
cat <<\EOF> nth-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:CompleteLifecycleAction", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeTags", "ec2:DescribeInstances", "sqs:DeleteMessage", "sqs:ReceiveMessage" ], "Resource": "*" } ] } EOF POLICY_ARN=$(aws iam create-policy --policy-name nth-policy --policy-document file://nth-policy.json --query 'Policy.Arn' --output text)
Shell
복사
IAM OIDC
eksctl utils associate-iam-oidc-provider --cluster $EKS_CLUSTER_NAME --approve
Shell
복사
IAM Account
eksctl create iamserviceaccount \ --cluster $EKS_CLUSTER_NAME \ --name aws-node-termination-handler \ --namespace kube-system \ --attach-policy-arn $POLICY_ARN \ --role-name AWS_NTH_Role \ --approve
Shell
복사
GET SQS QUEUE
QUEUE_URL=$(aws cloudformation describe-stacks --stack-name $STACK_NAME --query "Stacks[0].Outputs[?OutputKey=='QueueURL'].OutputValue" --output text)
Shell
복사
NTH Install by Helm
helm repo add eks https://aws.github.io/eks-charts helm install aws-node-termination-handler eks/aws-node-termination-handler \ --namespace kube-system \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-node-termination-handler \ --set enableSqsTerminationDraining=true \ --set queueURL=$QUEUE_URL
Shell
복사
TEST NTH
INSTANCE_ID=$(aws ec2 describe-instances --filters "Name=tag:aws:autoscaling:groupName,Values=$AUTO_SCALING_GROUP_NAME" --query "Reservations[0].Instances[0].InstanceId" --output text) aws ec2 terminate-instances --instance-ids $INSTANCE_ID # Log Check kubectl logs -l app.kubernetes.io/name=aws-node-termination-handler -n kube-system -f kubectl get pods -A # Check ASG aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $AUTO_SCALING_GROUP_NAME --query 'AutoScalingGroups[0].Instances'
Shell
복사