Container Orchestration/Kubernetes

Kubernetes Affinity 및 Scheduling 설정 가이드

Somaz 2024. 4. 19. 20:28
728x90
반응형

Overview

쿠버네티스에서는 파드를 어떤 노드에 배포할지를 다양한 방법으로 제어할 수 있다.


이 글에서는 대표적인 스케줄링 전략인 NodeSelector, Affinity, Taint & Toleration, Cordon & Drain을 상세하게 정리해본다.

 

 

 

 

📅 관련 글

2022.08.08 - [Container Orchestration/Kubernetes] - Kubernetes Ingress란? (클러스터 외부 트래픽 관리)

2023.04.14 - [Container Orchestration/Kubernetes] - Kubernetes Resources(쿠버네티스 리소스)

2023.04.17 - [Container Orchestration/Kubernetes] - Kubernetes API Server, Group / RBAC란?

2023.04.25 - [Container Orchestration/Kubernetes] - Kubernetes 플러그인 매니저 Krew란?

2023.05.08 - [Container Orchestration/Kubernetes] - Kubernetes Secret이란?

2023.05.09 - [Container Orchestration/Kubernetes] - Kuberntes Service Account란?

2023.05.23 - [Container Orchestration/Kubernetes] - Kubernetes Autoscaling & Karpenter

2023.05.26 - [AWS] - AWS IRSA(IAM Roles for Service Accounts)란?

2024.02.02 - [Container Orchestration/Kubernetes] - Kubernetes 클러스터 구축하기(kubespray 2024v.)

2024.02.02 - [Container Orchestration/Kubernetes] - Kubernetes Network

2024.04.15 - [Container Orchestration/Kubernetes] - Kubernetes Operator 및 Custom Resource Definitions(CRDs) 이해하기

2024.04.15 - [Container Orchestration/Kubernetes] - Kubernetes Volumes 및 StorageClass: CSI 드라이버 사용 가이드

2024.05.24 - [Trouble Shooting] - K8s Worker Node에 지정한 Pod 배치하기(Taint, Tolerations)

2024.11.26 - [Container Orchestration/Kubernetes] - Kubernetes Deployment Strategy

2024.12.03 - [Container Orchestration/Kubernetes] - Kubernetes Headless Service란?

2024.12.16 - [Container Orchestration/Kubernetes] - Kubernetes Operator(CRD, CR) 생성(With kubebuilder)

2025.01.14 - [Container Orchestration/Kubernetes] - Kubernetes IPVS vs iptables

 

 

 

 

 

 


 

 

 

 

Kubernetes Affinity and Scheduling

 

쿠버네티스에서는 다음과 같은 여러 메커니즘을 통해 클러스터 내에서 파드가 배포되는 위치를 제어할 수 있다.

  • 노드 셀렉터(NodeSelector)
  • 어피니티(Affinity)
  • 테인트 & 톨러레이션(Taints & Toleration)
  • 커든(Cordon)
  • 드레인(Drain)

 

 

노드 할당 및 스케줄링 방법

방법 설명
NodeSelector 단순한 Key-Value 기반 노드 선택
Affinity 보다 유연한 노드 및 파드 배치 정책
Taint & Toleration 특정 노드에 대한 제한 설정
Cordon & Drain 노드 유지보수 및 스케줄링 제어

 

 

 

 


 

 

 

 

1️⃣ 노드 셀렉터(NodeSelector)

  • 쿠버네티스에서 가장 간단한 스케줄링 제약 조건이다.
  • 파드 `.spec.nodeSelector` 필드에 Key-Value 쌍을 설정
  • 해당 레이블을 가진 노드에만 스케줄링

 

 

사용법

# 노드에 레이블 추가
kubectl label nodes <노드이름> disktype=ssd
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  nodeSelector:
    disktype: ssd

 

 

 

 


 

 

 

 

 

2️⃣ 어피니티(Affinity)

  • 노드 셀렉터보다 고급이며, 특정 파드 배치에 대한 규칙을 설정한다.
  • 주요 유형: 노드 어피니티(Node Affinity) 및 파드 어피니티(Pod Affinity).
  • 노드 어피니티
    • `requiredDuringSchedulingIgnoredDuringExecution` 또는 `preferredDuringSchedulingIgnoredDuringExecution`으로 설정할 수 있다.
  • 조건을 더 세밀하게 설정 가능
  • Hard (필수)와 Soft (선호) 조건 지원
유형 설명
Node Affinity 특정 노드 조건을 만족하는 노드에 스케줄링
Pod Affinity 특정 파드가 있는 노드에 함께 배포
Pod Anti Affinity 특정 파드가 있는 노드를 피해서 배포

 

 

 

Node Affinity 예제

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: nginx
    image: nginx
  • requiredDuringSchedulingIgnoredDuringExecution
    • 파드가 스케줄링될 때 반드시 충족해야 하는 요구사항을 정의한다. 규칙을 만족하는 노드에만 파드가 스케줄될 수 있다.
    • 특정 노드에 파드를 배치해야 할 때 사용한다. 예를 들어, 특정 라벨이 있는 노드에만 파드를 배치하고 싶은 경우 이 규칙을 사용할 수 있다.
    • 만약 이 규칙을 만족하는 노드가 없다면, 파드는 스케줄되지 않는다.

 

  • preferredDuringSchedulingIgnoredDuringExecution
    • 스케줄러에게 파드가 스케줄링될 때 선호되는(하지만 필수는 아닌) 요구사항을 알린다. 스케줄러는 이 규칙을 가능한 한 충족시키려고 시도하지만, 규칙을 만족하는 노드가 없어도 파드는 다른 노드에 스케줄될 수 있다.
    • 파드의 배치에 더 유연성을 제공하고자 할 때 사용한다. 예를 들어, 특정 노드에 파드를 선호적으로 배치하고 싶지만, 그러한 노드가 없거나 사용할 수 없는 경우 다른 노드에도 배치될 수 있도록 하고 싶을 때 사용할 수 있다.
    • 이 규칙을 만족하는 노드가 있으면 그 노드에 파드가 우선적으로 스케줄되지만, 만족하는 노드가 없어도 파드는 스케줄될 수 있다.

 

  • 요약하자면, `requiredDuringSchedulingIgnoredDuringExecution`은 파드의 스케줄링에 있어서 반드시 충족해야 하는 엄격한 요구사항을 정의하는 반면, `preferredDuringSchedulingIgnoredDuringExecution`은 선호되는 조건을 정의하지만, 이 조건이 충족되지 않더라도 파드가 스케줄될 수 있도록 유연성을 제공한다.

 

  • 노드 안티-어피니티
    • 특정 노드의 속성이나 라벨을 기반으로 하여 파드를 해당 노드로부터 멀리 배치하고자 할 때 사용한다.
    • 노드 안티-어피니티는 노드 어피니티와 유사하게 작동하지만, 반대의 목적을 가지고 있다.
    • 이 예제에서 `requiredDuringSchedulingIgnoredDuringExecution`은 disktype이 hdd가 아닌 노드에 파드를 배치하도록 요구한다. 즉, SSD 또는 다른 유형의 디스크를 사용하는 노드에만 파드가 배치될 수 있다. 또한, `preferredDuringSchedulingIgnoredDuringExecution` 설정은 cpu가 high가 아닌 노드를 선호하지만, 이는 필수 조건이 아다. weight는 이 선호도의 중요성을 나타낸다.
apiVersion: v1
 kind: Pod
 metadata:
   name: mypod
 spec:
   affinity:
     nodeAffinity:
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
           - key: disktype
             operator: NotIn
             values:
             - hdd
       preferredDuringSchedulingIgnoredDuringExecution:
       - weight: 1
         preference:
           matchExpressions:
           - key: cpu
             operator: NotIn
             values:
             - high
   containers:
   - name: mycontainer
     image: myimage

 

 

 

 

Pod Affinity 예제

  • 파드 어피니티
    • 다른 파드의 레이블을 기준으로 규칙을 설정하는 데 사용된다.
    • 역시 하드 어피니티와 소프트 어피니티 규칙을 정의할 수 있다.
    • 다른 파드와 가깝게 배치되기를 원할 때 사용한다.
    • `requiredDuringSchedulingIgnoredDuringExecution` 예제에서, mypod는 `app=database` 레이블을 가진 다른 파드와 같은 호스트(kubernetes.io/hostname)에 배치되어야 한다.
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - database
        topologyKey: "kubernetes.io/hostname"
    containers:
    - name: mycontainer
      image: myimage

 

 

 

 

 

 

Pod Anti Affinity 예제

  • 파드 안티-어피니티
    • 파드를 특정 레이블을 가진 다른 파드로부터 멀리 배치하고자 할 때 사용한다.
    • `requiredDuringSchedulingIgnoredDuringExecution` 예제에서, mypod는 `app=webserver` 레이블을 가진 다른 파드와는 다른 호스트(kubernetes.io/hostname)에 배치되어야 한다.
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - webserver
        topologyKey: "kubernetes.io/hostname"
    containers:
    - name: mycontainer
      image: myimage

 

 

 

 

Affinity의 Operator 정리

Operator 의미
In 지정 값과 일치하는 경우
NotIn 지정 값과 일치하지 않는 경우
Exists 키가 존재하는 경우
DoesNotExist 키가 존재하지 않는 경우
Gt 지정 값보다 큰 경우 (숫자)
Lt 지정 값보다 작은 경우 (숫자)

 

 

 

 

 

 


 

 

 

 

 

 

3️⃣ 테인트 & 톨러레이션(Taints & Toleration)

  • Taint: 노드에 설정하는 제한 조건
  • Toleration: 파드에 설정해 Taint를 무시하고 배포 허용

 

Taint 추가

kubectl taint nodes <노드이름> key=value:NoSchedule

 

 

Toleration 설정 예제

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"

 

 

Taint 효과 정리

효과 설명
NoSchedule 해당 노드에 파드 스케줄링 금지
PreferNoSchedule 가능하면 스케줄링 금지, 불가피하면 허용
NoExecute 기존 파드도 퇴출 (즉시 영향)

 

 

 

 


 

 

 

 

 

4️⃣ 커든(Cordon) &드레인(Drain)

 

✅ 개념

명령 설명
cordon 해당 노드로 신규 파드 스케줄링 금지
uncordon cordon 해제
drain 노드에서 기존 파드를 퇴출 및 재스케줄링

 

 

 

사용법

# 노드 cordon (스케줄링 금지)
kubectl cordon <노드이름>

# 노드 uncordon (해제)
kubectl uncordon <노드이름>

# 노드 drain (파드 퇴출 및 재스케줄링)
kubectl drain <노드이름> --ignore-daemonsets --delete-emptydir-data

 

 

 

 


 

 

 

 

 

전체 비교 요약

방법 목적 주요 필드 특징
NodeSelector 특정 노드 지정 nodeSelector 단순 Key-Value 매칭
Node Affinity 조건부 노드 지정 affinity.nodeAffinity 복잡 조건 가능
Pod Affinity 특정 파드 옆에 배치 affinity.podAffinity 파드간 위치 제어
Pod Anti Affinity 특정 파드 피해서 배치 affinity.podAntiAffinity 파드간 충돌 방지
Taint & Toleration 특정 노드 제한 tolerations Taint와 매칭되는 파드만 허용
Cordon & Drain 노드 유지보수 cordon, drain 스케줄링 차단/퇴출

 

 

 

 


 

 

 

 

 

마무리

  • 쿠버네티스의 파드 스케줄링 전략은 단순히 "아무데나 배포"하는 것이 아니라, 다양한 상황을 고려해 유연하고 전략적으로 설정할 수 있다.
  • 실제 운영 환경에서는 하드웨어 성능, 네트워크 존, 파드 간 의존성 등을 고려해 어피니티, 안티 어피니티, 테인트 & 톨러레이션을 적극 활용해야 한다.
  • 스케줄링을 잘 설정하는 것만으로도 클러스터 안정성과 성능을 크게 높일 수 있으니, 꼭 숙지하고 현업에서 활용해보자!

 

 

 

 

 

 


Reference

 

공식문서: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/

공식문서: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/

 

728x90
반응형