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
복사