Scheduling-Node Selectors-Node Affinity

2024. 12. 31. 14:19쿠버네티스/쿠버네티스

728x90
반응형

Node Selectors와 라벨링

상황 설명

  • 클러스터에는 총 3개의 노드가 있습니다:
    • 작은 노드 2개: 하드웨어 리소스가 적음.
    • 큰 노드 1개: 더 높은 리소스를 제공.
  • 다양한 워크로드가 클러스터에서 실행 중이며, 데이터 처리 워크로드는 더 많은 리소스를 요구하므로 큰 노드에서 실행되기를 원합니다.
  • 기본 설정에서는 모든 Pod이 임의의 노드에 배치될 수 있습니다. 예를 들어, Pod C가 작은 노드(노드 2 또는 3)에 배치될 수도 있습니다. 이는 원하는 결과가 아닙니다.

해결 방법

Pod이 특정 노드에서만 실행되도록 제한하려면 두 가지 방법이 있습니다:

  1. Node Selector (간단하고 쉬운 방법)
  2. Node Affinity/Anti-Affinity (더 복잡한 요구사항에 적합)

Node Selector 사용법

  1. Pod 정의 파일 수정
    • Pod 정의 파일의 spec 섹션에 nodeSelector 속성을 추가하여 특정 노드에서만 Pod이 실행되도록 설정합니다.
    • 예시:
spec:
  nodeSelector:
    size: large
  • 여기서 size=large는 라벨로, Kubernetes는 이를 기반으로 적절한 노드를 선택합니다.

노드에 어떻게 라벨 설정하나?

라벨(Label) 설정

  • Kubernetes는 노드에 설정된 라벨을 사용하여 Pod을 적절한 노드에 배치합니다.
  • 라벨은 키-값 형식으로 구성됩니다. 예: size=large.
  • 라벨 설정 명령어:
kubectl label nodes <노드명> <라벨>
# 큰 노드를 라벨링한다면
kubectl label nodes node1 size=large

Pod 생성

  • 라벨이 설정된 후, nodeSelector를 포함한 Pod 정의 파일을 사용하여 Pod을 생성하면 해당 Pod은 지정된 라벨 조건을 만족하는 노드(예: size=large)에 배치

Node Selector의 한계

Node Selector는 단순한 라벨 매칭만 지원하므로 복잡한 조건을 처리할 수 없습니다. 예를 들어:

  • "Pod을 큰(Large) 또는 중간(Medium) 노드에 배치"하거나,
  • "작은(Small) 노드를 제외한 모든 노드에 배치"와 같은 조건은 Node Selector로 구현할 수 없습니다.

이를 해결하기 위해 Kubernetes는 Node Affinity  Anti-Affinity 기능을 제공합니다. 이 기능들은 더 복잡한 요구사항을 처리


Node Affinity란?

  • Node Affinity는 Kubernetes에서 Pod이 특정 노드에 배치되도록 제어하는 기능입니다.
  • 기존 Node Selector보다 더 유연하며, 논리 연산자(In, NotIn, Exists 등)를 사용해 복잡한 조건을 설정할 수 있습니다.
  • 주로 다음과 같은 경우에 사용됩니다:
    • 특정 하드웨어(예: SSD, GPU)가 필요한 Pod 배치.
    • 고성능 컴퓨팅 작업을 특정 노드에 제한.
    • 특정 라벨 조건을 만족하는 노드에서만 실행.

Node Affinity 사용 방법

  1. Pod 정의 파일 수정
    • Node Affinity는 spec.affinity.nodeAffinity 섹션에 정의됩니다.
    • 주요 구성 요소:
      • requiredDuringSchedulingIgnoredDuringExecution: Pod이 반드시 조건을 만족하는 노드에만 배치됩니다. 조건을 만족하는 노드가 없으면 Pod은 스케줄되지 않습니다.
      • preferredDuringSchedulingIgnoredDuringExecution: 조건을 만족하는 노드를 선호하지만, 없으면 다른 노드에도 배치될 수 있습니다.
    예시 YAML:
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: In
            values:
            - large
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: size
            operator: NotIn
            values:
            - small

라벨(Label) 설정

  • Node Affinity는 노드의 라벨을 기반으로 동작합니다.
  • 라벨 추가 명령어:
kubectl label nodes <노드명> <라벨>
kubectl label nodes node1 size=large

Node Affinity의 동작 방식

1. 스케줄링 중 동작 (during scheduling)

  • Pod이 처음 생성될 때, Node Affinity 규칙이 적용되어 적합한 노드가 선택됩니다.
  • requiredDuringSchedulingIgnoredDuringExecution:
    • 조건을 만족하지 않는 노드가 있으면 Pod은 스케줄되지 않습니다.
  • preferredDuringSchedulingIgnoredDuringExecution:
    • 조건을 만족하는 노드를 우선적으로 선택하지만, 없으면 다른 노드에도 배치 가능합니다.

2. 실행 중 동작 (during execution)

  • Pod이 실행 중일 때 환경(예: 라벨 변경)이 바뀌더라도 현재 Node Affinity 규칙은 적용되지 않습니다.
  • 현재 사용 가능한 옵션(IgnoredDuringExecution)에서는 실행 중인 Pod은 영향을 받지 않습니다.
  • 향후 지원될 예정인 옵션(RequiredDuringExecution)에서는 규칙을 위반하는 경우 Pod이 종료되거나 재배치될 수 있습니다.

Node Affinity의 주요 연산자

  • In: 지정된 값 리스트 중 하나를 포함하는 경우 매칭.
  • NotIn: 지정된 값 리스트에 포함되지 않는 경우 매칭.
  • Exists: 특정 키가 존재하면 매칭(값은 필요 없음).
  • DoesNotExist: 특정 키가 존재하지 않으면 매칭.

Apply a label color=blue to node node01

  • kubectl label node node01 color=blue

Create a new deployment named blue with the nginx image and 3 replicas.

  • kubectl create deployment blue --image=nginx --replicas=3

Which nodes can the pods for the blue deployment be placed on?

kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
blue-6dc9b889f5-chx2z   1/1     Running   0          42s   172.17.0.4   controlplane   <none>           <none>
blue-6dc9b889f5-hl7b2   1/1     Running   0          42s   172.17.1.3   node01         <none>           <none>
blue-6dc9b889f5-njg8m   1/1     Running   0          42s   172.17.1.2   node01         <none>           <none>

 

Set Node Affinity to the deployment to place the pods on node01 only.

  • kubectl edit deployment blue(디플로이먼트이름) 
affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: color
            operator: In
            values:
            - blue

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

 

Assign Pods to Nodes using Node Affinity

This page shows how to assign a Kubernetes Pod to a particular node using Node Affinity in a Kubernetes cluster. Before you begin You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.

kubernetes.io

편집 tip

v를 눌러 visual모드에서 원하는 부분 아래그림처럼 선택한 후 ' shift+.'을하면 왼쪽으로 한칸씩 들어감

 

Create a new deployment named red with the nginx image and 2 replicas, and ensure it gets placed on the controlplane node only.

 

Use the label key - node-role.kubernetes.io/control-plane - which is already set on the controlplane node.

kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: red
  name: red
spec:
  replicas: 2
  selector:
    matchLabels:
      app: red
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: red
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
kubectl create deployment red --image=nginx --replicas=2 --dry-run=client -o yaml > red.yaml
###
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: red
  name: red
spec:
  replicas: 2
  selector:
    matchLabels:
      app: red
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: red
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-role.kubernetes.io/control-plane
                operator: Exists
                values:
status: {}

kubectl create -f red.yaml

Taints and Tolerations VS Node Affinity

문제 정의

  • 목표:
    • 파란색 Pod은 파란색 노드에, 빨간색 Pod은 빨간색 노드에, 초록색 Pod은 초록색 노드에 배치.
    • 다른 팀의 Pod이 우리의 노드에 배치되지 않도록 방지.
    • 우리의 Pod이 다른 팀의 노드에 배치되지 않도록 방지.

Taints와 Tolerations으로 해결

  1. Taints 추가
    • 각 노드에 색상별로 taint를 추가합니다.
kubectl taint nodes blue-node color=blue:NoSchedule
kubectl taint nodes red-node color=red:NoSchedule
kubectl taint nodes green-node color=green:NoSchedule

Tolerations 추가

  • 각 Pod에 해당 색상의 toleration을 추가합니다.
tolerations:
- key: "color"
  operator: "Equal"
  value: "blue"
  effect: "NoSchedule"
  • 이 설정으로 특정 색상의 Pod만 해당 색상의 taint가 있는 노드에서 실행될 수 있습니다.
  • 단, 반듯이 해당 생삭의 노드에 실행되는 건 아님.
  1. 결과
    • 파란색 Pod은 파란색 노드에서 실행되고, 빨간색과 초록색도 동일하게 배치됩니다.
    • 그러나 Taints와 Tolerations만 사용하면 다른 Pod이 taint가 없는 노드에 배치될 가능성이 있습니다. 예를 들어, 빨간색 Pod이 taints가 없는 다른 팀의 노드로 이동할 수 있습니다.

Node Affinity로 해결

  1. 라벨 추가
    • 각 노드에 색상별 라벨을 추가합니다.
kubectl label nodes blue-node color=blue
kubectl label nodes red-node color=red
kubectl label nodes green-node color=green

Node Affinity 설정

  • 각 Pod에 Node Affinity 규칙을 추가하여 특정 라벨을 가진 노드에서만 실행되도록 설정합니다.
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: color
          operator: In
          values:
          - blue
  • 이 설정으로 파란색 Pod은 color=blue 라벨이 있는 노드에서만 실행됩니다.

결과

  • Node Affinity는 특정 Pod이 지정된 라벨 조건을 만족하는 노드에서만 실행되도록 보장합니다.
  • 그러나 Node Affinity만 사용하면 다른 팀의 Pod도 해당 라벨 조건을 만족하는 우리의 노드에 배치될 수 있습니다.

Taints & Tolerations + Node Affinity 결합

  1. Taints와 Tolerations
    • 각 노드에 taint를 추가하여 다른 팀의 Pod이 우리의 노드로 스케줄링되지 않도록 방지합니다.
    • 우리의 Pod에는 해당 taint를 허용하는 toleration을 추가합니다.
  2. Node Affinity
    • 우리의 Pod에는 Node Affinity 규칙을 추가하여 지정된 라벨 조건을 만족하는 특정 노드에서만 실행되도록 보장합니다.
  3. 결과
    • Taints와 Tolerations는 다른 팀의 Pod이 우리의 노드로 들어오는 것을 막고,
    • Node Affinity는 우리의 Pod이 다른 팀의 노드로 이동하지 않도록 보장합니다.
    • 이 조합으로 완벽하게 격리된 환경을 구축할 수 있습니다.

요약

  • Taints와 Tolerations: 특정 Pod만 지정된 노드에서 실행되도록 제한하며, 다른 팀의 Pod 접근을 차단.
  • Node Affinity: 특정 라벨 조건을 만족하는 노드에서만 우리의 Pod이 실행되도록 보장.
  • 두 기능을 조합하면 다중 테넌트 환경에서도 완벽히 격리된 클러스터 운영 가능.
반응형

'쿠버네티스 > 쿠버네티스' 카테고리의 다른 글