107. 노드 어피니티 (Node Affinity) - K8s 스케줄링의 강력한 유도와 강제
⚠️ 이 문서는 어제 배운 '테인트(Taint)'가 방주인(노드) 입장에서 "아무나 오지 마!"라고 발로 차서 쫓아내는(Repel) 소극적인 방어 기법이었다면, 이번엔 반대로 세입자(파드) 입장에서 **"나는 무조건 1,000만 원짜리 GPU가 달린 노드 아니면 절대 이사 안 갈 거야!" 또는 "CPU가 좀 구려도 SSD 달린 방이면 좋겠어~"라고 자신의 조건과 취향(라벨)을 깐깐하게 내세워, 스케줄러가 파드를 특정한 꿀방(노드)으로 밀어 넣도록(Attract) 멱살 잡고 끌고 가는 능동적인 짝짓기 기술인 '노드 어피니티(Node Affinity)'**를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 파드(세입자)가 원하는 노드(집)의 스펙 조건을 적어내는 '부동산 중개소 매물 요청서'다. K8s 스케줄러는 이 요청서를 읽고 노드 몸통에 붙어있는 라벨(Label)과 1:1 대조하여 찰떡같은 짝을 찾아준다.
- 가치: 딥러닝 AI 파드를 깡통 CPU 서버가 아니라 반드시 GPU 가속기가 꽂힌 워커 노드에만 뜨게 만들거나, 유럽(EU) 고객의 결제 데이터 파드는 반드시 법률에 따라 '프랑크푸르트 리전'에 있는 노드에만 배포되게 하는 물리적/지리적 배치의 절대적 통제력을 제공한다.
- 기술 체계: "이 조건 안 맞추면 나 그냥 길바닥에서 굶어 죽을래!(Pending)"라고 땡깡을 부리는 **강제 조건(
Required)**과, "GPU 방이 없으면 어쩔 수 없지, 걍 남는 방 아무 데나 구겨 넣어줘"라고 융통성을 발휘하는 선호 조건(Preferred) 두 가지 모드로 정교하게 작동한다.
Ⅰ. Taint와의 차이점: 방어(밀어내기) vs 유도(끌어당기기)
쫓아내는 것과 원하는 곳을 찾아가는 것은 완전히 다른 마법이다.
- 노드 셀렉터 (NodeSelector)의 낡은 멍청함:
- 쿠버네티스 초창기에는
nodeSelector라는 아주 단순한 기능만 있었다. - 파드에
disk: ssd라고 적어놓으면, 스케줄러는 무조건disk=ssd라벨이 붙은 노드만 찾아서 쑤셔 넣었다. - 치명적 단점: 만약 클러스터에 SSD 노드가 1개도 없으면? 이 파드는 융통성 없이 평생 허공에 둥둥 떠서(Pending) 에러를 뿜으며 자살해 버린다. ("SSD 없으면 그냥 HDD 방에라도 넣어주지..." 하는 타협이 아예 불가능했다.)
- 쿠버네티스 초창기에는
- 노드 어피니티 (Node Affinity)의 진화 (Attraction):
nodeSelector의 무식함을 개조한 진화 버전이다. "끌어당김(Affinity, 친화력)"이라는 이름처럼, 파드가 노드를 찾아갈 때 'OR 조건', '크다/작다 조건', '타협 가능 조건' 등 아주 유연하고 복잡한 수학적 짝짓기를 가능하게 해준다.
- Taint(밀어내기)와의 비교:
- 어제 배운 Taint는 "내 방에 냄새를 뿌릴 테니 오지 마!"(입구 컷)다. 방어적이다.
- Node Affinity는 파드가 "나는 저기 강남뷰 보이는 방으로만 갈래!"(자석처럼 끌어당김)다. 능동적이다.
- 실무에서는 대국민 DB 서버를 격리하기 위해 이 두 개를 동시에 쓴다. 노드에 Taint(아무나 오지마)를 뿌리고, DB 파드에 Toleration(방독면)과 Affinity(난 저 방만 갈래)를 듀얼로 발라버리면, 불순물 파드는 0%로 차단되고 DB 파드만 100% 저 꿀방으로 직행하는 완벽한 진공 무균실 배치가 완성된다.
📢 섹션 요약 비유: 부동산에 집을 구하러 갑니다. Taint는 집주인이 문 앞에 "애완동물 키우는 사람, 흡연자 절대 사절!"이라고 방어막을 쳐둔 것입니다(밀어내기). Node Affinity는 세입자(파드)가 중개사에게 "저는 무조건 남향이고 베란다 있는 방(Label)만 보여주세요!"라고 강력한 취향을 요구하여 그 방으로 직진하는 것입니다(끌어당기기). 둘 다 섞어 쓰면 "담배 안 피우고(Toleration 통과), 남향 방을 원하는(Affinity)" 완벽한 VIP 세입자를 특정 펜트하우스에 핀셋으로 꽂아 넣을 수 있는 정밀 건축술이 됩니다.
Ⅱ. 어피니티의 두 가지 강도: 목숨 걸기 vs 융통성 부리기
"이 조건 안 맞으면 죽을래" vs "없으면 아쉬운 대로 살게."
- 강제 조건 (Required):
requiredDuringSchedulingIgnoredDuringExecution- 영어 이름이 미친 듯이 길지만 뜻은 단순하다. "스케줄링할 때 이 조건 안 맞으면 나 절대 안 들어가!(Required)"
- 사용 예시:
key: "zone", operator: "In", values: ["us-east-1"] - 유럽 개인정보법 때문에 이 고객 데이터 파드는 반드시 유럽(EU) 노드에만 떠야 한다. 만약 클러스터에 EU 라벨이 붙은 노드가 다 죽고 없다면? 차라리 파드를 허공에 띄워 500 에러(Pending)를 낼지언정, 절대로 불법인 미국(US) 노드로는 도망가지 않고 죽음을 택하는 깡패 같은 강제 룰이다.
- 선호 조건 (Preferred):
preferredDuringSchedulingIgnoredDuringExecution- **"스케줄링할 때 내 조건 맞춰주면 제일 고맙고(Preferred), 방이 없으면 어쩔 수 없지... 걍 빈방 아무 데나 대충 넣어줘."**라는 아주 착하고 융통성 있는 룰이다.
- 사용 예시: 딥러닝 모델의 보조 계산 파드. "GPU 방(
gpu=true)에 들어가면 속도가 빠르니까 1순위로 가고 싶어. 근데 GPU 방이 만실(Full)이면 그냥 CPU 방에라도 들어가서 느리게라도 굴러갈게." - 가중치 (Weight): Preferred는 여러 조건을 걸어놓고 점수(1~100)를 매길 수 있다. "SSD 방이면 100점! 서울 리전이면 50점!" K8s 스케줄러는 노드들의 점수를 쫙 더해보고 가장 점수가 높은 1등 방에 파드를 사뿐히 던져준다.
📢 섹션 요약 비유: 소개팅(스케줄링)에 나갑니다. **Required(강제)**는 "나는 무조건 키 180cm 이상 아니면 평생 혼자 살고 독신으로 늙어 죽을 거야!(Pending)"라는 타협 불가의 똥고집입니다. 조건 안 맞으면 매칭이 파탄 납니다. **Preferred(선호)**는 "키 180cm 이상(가중치 100점)이면 너무 좋고, 돈 많으면(가중치 80점) 더 좋지. 근데 둘 다 없으면 그냥 숨만 붙어있는 아무나 소개시켜 줘, 혼자 죽긴 싫어(일반 노드 배정)"라는 눈물겨운 융통성입니다. 서비스가 절대 뻗으면 안 될 때는 융통성(Preferred)을 쓰는 게 인프라 생존에 유리합니다.
Ⅲ. 뒤에 붙은 마법의 꼬리표: IgnoredDuringExecution
방에 들어온 뒤에 방주인이 스펙을 바꾸면 쫓겨날 것인가?
- 저 긴 영어 이름의 뒷부분의 의미:
- 두 규칙 모두 이름 끝에 **
IgnoredDuringExecution(실행 도중에는 무시함)**이라는 긴 꼬리표가 붙어있다.
- 두 규칙 모두 이름 끝에 **
- 런타임(Runtime) 시의 라벨 변경 상황:
- 아까 "무조건 SSD 방(Required)!"을 외치고 1번 노드(SSD)에 파드가 예쁘게 입주했다. 1달 동안 장사를 잘하고 있었다.
- 그런데 오늘 새벽 관리자가 미쳐서 1번 노드의 몸통에 붙어있던 라벨을
disk=ssd에서disk=hdd로 강제로 뜯어고쳐 버렸다(라벨 변경). - 파드의 뇌구조: "어? 내 입주 계약(Required)은 SSD인데 이 방이 HDD로 바뀌었네? 나 당장 방 빼고 짐 싸서 나갈까(Evict)?"
- K8s의 안정성 철학 (무시하고 그냥 살아라):
- K8s의 대답은 "아니, 그냥 살아! (Ignored)" 다.
- 쿠버네티스는 런타임에 서비스가 덜컹거리고 파드가 죽는 것을 극도로 혐오한다.
- 방에 **'처음 입주(Scheduling)'**할 때만 깐깐하게 조건을 따질 뿐, 일단 짐 풀고 실행(Execution)이 시작된 후에는 방주인이 인테리어를 어떻게 바꾸든 멱살 잡고 쫓아내지 않고 무시(Ignored)해 버리는 거룩한 세입자 보호법이다. (참고로 "바뀌면 즉시 방 빼고 쫓겨나라!"는 깐깐한 옵션인
RequiredDuringExecution도 K8s 스펙에 설계는 되어있으나, 아직 미구현 상태로 미래를 위해 이름만 남겨둔 상태다.)
📢 섹션 요약 비유: 부동산 전세 계약입니다. IgnoredDuringExecution은 "입주하는 첫날(Scheduling)엔 무조건 에어컨 있는 방인지 확인하고 도장을 찍습니다. 하지만 1년 뒤 집주인이 몰래 에어컨을 떼가버렸어도(라벨 변경), 저는 귀찮아서 이사(재배포) 안 가고 전세 기간 끝날 때까지 땀 뻘뻘 흘리며 그냥 참고 버팁니다(Ignored)"라는 세입자 보호 생존 철학입니다. 중간에 파드가 강제로 죽으면 고객 결제가 튕기는 서버 에러가 나기 때문에, K8s는 웬만하면 살고 있는 놈의 엉덩이를 걷어차지 않는 보수적인 가용성 우선주의를 따릅니다.