Non-terminated Pods 섹션을 보면 이 노드 위에서 실행 중인 파드가 확인됩니다.
$ kubectl describe node -l type=OrdersMNG
Namespace Name
orders orders-5b97745747-mxg72 ← Orders API
orders orders-mysql-b9b997d9d ← MySQL (EBS PVC 사용 중)
kube-system aws-node, ebs-csi-node, kube-proxy ...
$ kubectl get pvc -n orders
NAME STATUS VOLUME CAPACITY STORAGECLASS
order-mysql-pvc Bound pvc-875d1ca7-e28b-421a-8a7e-2ae9d7480b9a 4Gi gp3
orders-mysql이 us-west-2a의 EBS 볼륨에 묶여 있습니다.
이 볼륨을 끊지 않고 마이그레이션하려면 green-mng도 동일한 AZ에 만들어야 합니다.
orders와 orders-mysql의 Deployment를 확인하면 nodeSelector와 toleration이 설정되어 있습니다.
cat ~/environment/eks-gitops-repo/apps/orders/deployment.yaml
spec:
nodeSelector:
type: OrdersMNG # 이 레이블이 있는 노드에만 스케줄링
tolerations:
- key: "dedicated"
operator: "Equal"
value: "OrdersApp"
effect: "NoSchedule" # 이 toleration이 있어야 dedicated taint 노드에 진입 가능
green-mng에 동일한 레이블과 Taint를 설정해야 orders 파드가 정상적으로 이동할 수 있습니다.
Step1. green-mng 생성
base.tf의 blue-mng 블록 아래에 green-mng을 추가합니다.
cluster_version을 명시하지 않아서 eks_managed_node_group_defaults의 값(1.31)을 자동으로 따릅니다.
green-mng = {
instance_types = ["m5.large", "m6a.large", "m6i.large"]
subnet_ids = [module.vpc.private_subnets[0]] # blue-mng과 동일한 AZ
min_size = 1
max_size = 2
desired_size = 1
update_config = {
max_unavailable_percentage = 35
}
labels = {
type = "OrdersMNG" # orders 파드가 이 노드로 스케줄링될 수 있도록
}
taints = [
{
key = "dedicated"
value = "OrdersApp"
effect = "NO_SCHEDULE"
}
]
# cluster_version 없음 → 1.31 자동 적용
}
blue-mng 코드와 비교했을 때 cluster_version = "1.30" 한 줄이 없는 것이 전부입니다.
이 차이 하나로 두 노드그룹의 K8s 버전이 달라집니다.
while true; do
kubectl get node -L eks.amazonaws.com/nodegroup
echo; date; sleep 1
done
업그레이드가 진행되는 동안 노드 상태 변화를 실시간으로 관찰합니다.
-L eks.amazonaws.com/nodegroup 옵션은 각 노드가 어느 노드그룹에 속하는지를 컬럼으로 추가해서 보여줍니다. 업그레이드 중 Scale Up 단계에서 새 노드가 추가되는 시점, 기존 노드가 SchedulingDisabled 상태로 바뀌는 시점, 그리고 최종적으로 기존 노드가 사라지고 새 노드만 남는 시점을 이 출력으로 확인할 수 있습니다.
'terraform apply -auto-approve' 명령으로 apply !
생성 완료 후 확인해봅시다.
$ kubectl get node -l type=OrdersMNG -o wide
NAME STATUS VERSION
ip-10-0-7-77.us-west-2.compute.internal Ready v1.30.14-eks-bbe087e # blue-mng
ip-10-0-0-159.us-west-2.compute.internal Ready v1.31.14-eks-bbe087e # green-mng (신규)
$ kubectl get node -l type=OrdersMNG -L topology.kubernetes.io/zone
NAME VERSION ZONE
ip-10-0-7-77.us-west-2.compute.internal v1.30.14-eks-bbe087e us-west-2a
ip-10-0-0-159.us-west-2.compute.internal v1.31.14-eks-bbe087e us-west-2a
두 노드 모두 us-west-2a입니다.
green-mng 노드가 orders-mysql의 EBS 볼륨에 접근할 수 있는 조건이 갖춰졌습니다.
ArgoCD Application에 ignoreDifferences로 replicas가 무시되도록 설정되어 있다면 직접 올립니다.
kubectl scale deploy -n orders orders --replicas 2
kubectl get pod -n orders -o wide
orders 파드 하나가 green-mng 노드에 떠 있는 것을 확인합니다.
이제 ALLOWED DISRUPTIONS가 1이 되어 drain이 진행될 수 있습니다.
Step3. blue-mng 삭제 및 마이그레이션
삭제 과정을 실시간으로 모니터링합니다.
while true; do
kubectl get node -l type=OrdersMNG
echo
kubectl get pod -n orders -l app.kubernetes.io/component=service -o wide
echo
kubectl get pdb -n orders
echo; date
done
base.tf에서 blue-mng 블록을 제거하고 apply합니다.
cd ~/environment/terraform/
terraform apply -auto-approve # 약 10분 소요
EKS가 blue-mng 노드에 대해 자동으로 처리하는 순서는 이벤트 로그로 확인할 수 있습니다.
$ kubectl get events --sort-by='.lastTimestamp' --watch
Normal NodeNotSchedulable node/ip-10-0-7-77... Node status is now: NodeNotSchedulable
Normal NodeNotReady node/ip-10-0-7-77... Node status is now: NodeNotReady
Normal DeletingNode node/ip-10-0-7-77... Deleting node because it does not exist in the cloud provider
Normal RemovingNode node/ip-10-0-7-77... Removing Node from Controller
Cordon → drain → 종료 순서로 진행됩니다. drain 시점에 blue-mng에 있던 orders 파드가 축출되고,
nodeSelector와 toleration 조건을 만족하는 green-mng 노드로 재스케줄링됩니다.
Migration 결과 확인
$ kubectl get node -l type=OrdersMNG
NAME STATUS VERSION
ip-10-0-0-159.us-west-2.compute.internal Ready v1.31.14-eks-bbe087e
type=OrdersMNG 노드가 green-mng의 v1.31 노드 하나만 남았습니다.
kubectl get pods -n orders -o wide
orders와 orders-mysql 파드 모두 green-mng 노드에서 실행 중인 것을 확인합니다.