[kubernetes] Node Selector & Node Affinity

2025. 3. 14. 02:55·Kubernetes & EKS/k8s 공부 기록

Node Selector

간단한 예시로 시작하겠습니다. 3개의 노드가 있는 클러스터가 있으며 그 중 2개는 더 낮은 하드웨어 리소스를 가진 더 작은 노드입니다. 다른 하나는 더 높은 리소스로 구성된 더 큰 노드입니다. 다양한 종류의 워크로드가 클러스터에서 실행 중입니다. 더 큰 노드를 더 높은 리소스가 필요한 데이터 처리 워크로드를 전용으로 사용하려고 합니다.

 

기본 설정에서는 모든 파드는 모든 노드로 이동할 수 있습니다. 이 경우 데이터 처리 파드용 파드는 리소스가 부족한 노드에 배치되어서 죽을 수 있습니다. 이를 해결하기 위해, 파드가 특정 노드에서만 실행되도록 제한을 설정할 수 있습니다. 파드 definition 파일을 살펴봅니다. 이 파일에는 데이터 처리 이미지와 함께 파드를 생성하기 위한 간단한 정의가 있습니다.

apiVersion: v1
kind: Pod
metadata:
 name: myapp-pod
spec:
 containers:
 - name: data-processor
   image: data-processor
 nodeSelector:
  size: Large

 

이 파드가 더 큰 노드에서 실행되도록 제한하려면 spec 섹션에 nodeSelector 라는 새 속성을 추가합니다. size: Large 를 입력합니다. size와 large의 key-value쌍은 노드의 label 입니다. 스케줄러는 이 레이블을 사용하여 파드를 배치할 올바른 노드를 식별합니다. 이와 같이 Node Selector에서 레이블을 사용하려면 파드를 만들기 전에 먼저 노드에 레이블을 지정해야 합니다.

$ kubectl label nodes <node-name> <label-key>=<label-value>

**Example**
$ kubectl label nodes node-1 size=Large

 

Node Selector는 우리의 목적에 부합했지만 한계가 있습니다. 우리는 단일 레이블과 selector를 사용했습니다. 그러나 만약 요구 사항이 훨씬 더 복잡하다면 어떨까요? 예를 들어, "Large 노드 나 Medium 노드에 파드를 배치하는 것"과 같은 것, "Small이 아닌 노드에 파드를 배치하는 것"과 같은 것과 같은 상황입니다. Node Selector로는 이를 달성할 수 없습니다. 이를 위해 Node affinity 및 anti-affinity 기능이 나타났습니다.

 

Node Affinity

Node Affinity의 주요 기능은 파드가 특정한 노드에서 호스팅되는 것을 보장하는 것입니다. 

예를 들어 위와 같은 상황에서 대용량 데이터 처리 파드를 노드1에 배치되도록 하고 싶습니다. 이 작업은 Node Selector를 통해 간단하게 해결할 수 있습니다. 그러나 Node Selector는 "Large 노드 나 Medium 노드에 파드를 배치하는 것"과 같은 것, "Small이 아닌 노드에 파드를 배치하는 것"과 같은 것과 같은 advance expressions을 제공할 수 없습니다.

 

아래 pod definition file은 위에서 구현한 NodeSelector를 사용한 definition file과 동일한 내용입니다. 둘 다 큰 노드에 파드를 배치한다는 똑같은 일을 합니다.

apiVersion: v1
kind: Pod
metadata:
 name: myapp-pod
spec:
 containers:
 - name: data-processor
   image: data-processor
 affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: In
            values:
            - Large
            - Medium

 

 

`spec` 아래에 `affinity` 가 있고, 또 그 아래에 `nodeAffinity`가 있습니다. 그 아래엔 문장처럼 보이는 긴 필드 `requiredDuringSchedulingIgnoredDuringExecution`가 있습니다. 이 아래에 `nodeSelectorTerms`가 있고 여기에서 key-value 쌍을 지정합니다. key-value쌍을 더 자세히 보겠습니다.

  • - key: size
  • - operator: In
  • - values:
  • - Large
  • - Medium

위 key-value쌍은 size가 Large이거나 Medium인 노드에 파드를 배치(In)하라는 의미입니다. 만약 Small이 아닌 노드에 파드를 배치하기 원한다면, 아래와 같이 operator: NotIn 을 사용하면 됩니다.

apiVersion: v1
kind: Pod
metadata:
 name: myapp-pod
spec:
 containers:
 - name: data-processor
   image: data-processor
 affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: NotIn
            values:
            - Small

 

만약 우리가 노드의 레이블을 Large와 Medium만 설정하고 Small은 레이블을 설정하지 않았다면, 레이블이 존재하는 노드에만 파드를 배치함으로써 파드를 Large노드나 Medium노드에 배치할 수 있을 것입니다. 이럴 때는 operator: Exists를 사용하면 됩니다.

apiVersion: v1
kind: Pod
metadata:
 name: myapp-pod
spec:
 containers:
 - name: data-processor
   image: data-processor
 affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: Exists

 

그런데 만약, NodeAffinity와 Node가 일치하지 않는다면 어떻게 될까요? 예를 들어, Large 노드에 파드를 배치하라고 했는데 Large라는 레이블이 붙은 노드가 없는 경우나, 파드가 이미 배치되어 있는데 누군가 노드의 레이블을 변경하는 경우입니다. 이 때 파드가 노드에 계속 남아 있을까요? 이러한 것들에 대한 설명은 긴 문장 같이 생긴 NodeAffinity Type이 해줍니다. NodeAffinity Type은 Node Affinity와 관련된 스케쥴러의 동작을 정의합니다.

 

현재 Available Node Affinity Type은 두 가지 입니다. 그리고 추가적으로 Planned Node Affinity Type이 하나 더 있습니다.

  • Available
    • requiredDuringSchedulingIgnoredDuringExecution
    • preferredDuringSchedulingIgnoredDuringExecution
  • Planned
    • requiredDuringSchedulingRequiredDuringExecution

파드의 라이프사이클에는 Node Affinity에 대해 두 가지 상태가 있습니다. DuringScheduling과 DuringExecution입니다.

  • DuringScheduling: 파드가 처음 생성될 때 Node Affinity 규칙을 따라 배치됨.
    • Required: 조건을 만족하는 노드가 없으면 파드가 예약되지 않음.
    • Preferred: 조건을 만족하는 노드가 없으면 무시하고 다른 노드에 배치됨.
  • DuringExecution: 파드 실행 중 노드의 레이블이 변경될 경우 영향을 받음.
    • 기본적으로 Node Affinity 변경이 있어도 파드는 계속 실행됨.
  • Planned Node Affinity Type:
    • RequiredDuringExecution을 사용하면 조건을 충족하지 않는 노드에서 파드를 강제로 종료함.

'Kubernetes & EKS > k8s 공부 기록' 카테고리의 다른 글

[kubernetes] EKS 파드 스케줄링: podAntiAffinity  (0) 2025.03.31
[kubernetes] Taint and Tolerance  (0) 2025.03.31
[kubernetes] Resource Requirements and Limits  (0) 2025.03.14
[kubernetes] Pod 헬스 체크 (Probe)  (0) 2025.03.14
[kubernetes] RollingUpdate 와 PodDisruptionBudget(PDB)  (1) 2025.03.08
'Kubernetes & EKS/k8s 공부 기록' 카테고리의 다른 글
  • [kubernetes] Taint and Tolerance
  • [kubernetes] Resource Requirements and Limits
  • [kubernetes] Pod 헬스 체크 (Probe)
  • [kubernetes] RollingUpdate 와 PodDisruptionBudget(PDB)
Hyukops
Hyukops
안녕하세요
  • Hyukops
    Hyukops 님의 Tech Blog
    Hyukops
    • 분류 전체보기 (141)
      • Introduction (1)
      • Kubernetes & EKS (43)
        • k8s in action (9)
        • k8s 공부 기록 (17)
        • k8s 운영 가이드 (10)
        • k8s 운영 특이사항 (7)
      • Service Mesh (29)
        • Istio 공부 기록 (20)
        • Istio 운영 특이사항 (9)
      • CICD (10)
        • argoCD 공부 기록 (6)
        • argoCD 운영 특이사항 (4)
      • Logging & Monitoring (5)
        • Prometheus 운영 특이사항 (0)
        • fluent bit 운영 특이사항 (5)
      • Infrastructure as Code (8)
        • terraform 공부 기록 (3)
        • terraform 운영 특이사항 (5)
      • AWS (40)
        • aws 공부 기록 (29)
        • 솔루션 사례 & 문제 해결 (11)
      • Database (5)
        • postgreSQL (5)
  • 태그

    Istio
    PostgreSQL
    kubernetes
    Database
    fluentbit
    canary
    Logging
    MSK
    fluent bit
    argocd
    k8s in action
    aws saa
    prometheus
    AWS
    Terraform
    eks
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Hyukops
[kubernetes] Node Selector & Node Affinity
상단으로

티스토리툴바