본문 바로가기
INFRA/Operation

쿠버네티스 이론STEP12 Scheduling 2 Affinity & AntiAffinity

by BTC_뚜벅이 2022. 10. 4.

ABTCEFG♪  안녕하세요, 여러분!

BTC_뚜벅이입니다.

지난 주 taint와 toleration에 대해 알아보았는데요.
이번 주엔 Affinity와 AntiAffinity에 대해 알아보도록 할게요.

 

1. Affinity와 AntiAffinity란?


특정 Node나 Pod와의 거리를 조절하는데 사용합니다.
특정 Pod나 Node끼리 가까이 스케줄링 하고 싶은 경우 Affinity를, 멀리 스케줄링 하고 싶은 경우 AntiAffinity를 사용합니다.

 

1-1. NodeAffinity

Pod가 특정 Node에 할당되길 원할 때 사용합니다.
nodeSlector와의 차이점은 옵션을 사용해서 소프트하게 조절이 가능합니다.
여기서 말하는 옵션이란 라벨 선택을 강제하거나(requiredDuringSchedulingIgnoredDuringExecution) 

유연하게 선호하거나(preferredDuringSchedulingIgnoredDuringExecution)
operator로 In, NotIn, Exists, DoesNotExist를 사용할 수 있습니다.

 

1-2. PodAffinity


matchExpressions가 매칭되는 Pod가 동일한 노드에서 실행하고 싶을 때 사용합니다.

Pod가 아닌 Deployment 리소스를 사용해야 PodAffinity를 쓰는 의미가 있습니다.


1-3. PodAntiAffinity


Pod끼리 서로 다른 노드에 스케줄링하고 싶을 때 PodAntiAffinity를 사용합니다.
Deployment 리소스를 사용하는것이 좋으며 특정 노드에 하나씩 두어야하는 경우 사용합니다.

 

2. 실습

실습을 위해 임의로 5개의 worker node로 단일 클러스터 생성함

 

2-1. NodeAffinity

 

kubectl label node node2 disktype=ssd
kubectl get nodes --show-labels

# node-affinity.yaml

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  containers:
  - name: nginx
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd

kubectl apply -f node-affinity.yaml
kubectl get pods -o wide |grep node-affinity

node affinity로 특정 node에 pod가 올라가도록 만들어줄 수 있습니다.

 

node2에 disktype=ssd 추가

 

pod가 node2에 올라간 것 확인

 

2-2. PodAffinity

 

kubectl label node node3 app=affinity

# pod-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-affinity
spec:
  selector:
    matchLabels:
      app: affinity
  replicas: 2
  template:
    metadata:
      labels:
        app: affinity
    spec:
      containers:
      - name: nginx
        image: nginx
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - affinity
            topologyKey: "kubernets.io/hostname"

kubectl apply -f pod-affinity.yaml
kubectl get pods -o wide |grep pod-affinity

pod affinity로 동일한 node에 pod가 올라갈 수 있도록 설정합니다.

 

node3에 app=affinity 추가

 

pod가 node3에만 올라간 것 확인

 

2-3. PodAntiAffinity

 

kubectl label node node1 app=antiaffinity

# pod-antiaffinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-antiaffinity
spec:
  selector:
    matchLabels:
      app: antiaffinity
  replicas: 5
  template:
    metadata:
      labels:
        app: antiaffinity
    spec:
      containers:
      - name: nginx
        image: nginx
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - antiaffinity
            topologyKey: "kubernets.io/hostname"
          
kubectl apply -f pod-antiaffinity.yaml
kubectl get pods -o wide |grep pod-antiaffinity

# node 수를 초과하는 anti affinity pod 배포하기

kubectl edit deployments.apps pod-antiaffinity # spec.replicas 값 8로 수정
kubectl get pods -o wide --sort-by=.spec.nodeName |grep pod-antiaffinity

app = antiaffinity라는 라벨을 가진 pod들이 서로 다른 노드에 스케줄링할 수 있습니다.

 

5개의 pod가 서로 다른 node에 하나씩 올라간 것을 확인

 

spec.replicas 5 -> 8로 수정

 

8개의 pod 중 3개의 node에 2개씩 배포

 

오늘 쿠버네티스의 기능인 Affinity와 AntiAffinity을 알아보았는데요. 
평소에 자주 사용하는 기능은 아니지만 아래의 경우에서 빛을 발휘합니다.

1) 서비스와 모니터링 app을 배치

2) 웹 서버와 캐시 서버를 배치

3) 트래픽이 급증

4) 노드나 pod에 문제 발생

 

쿠버네티스의 Scheduling 기능을 잘 알아두시면 정말 유용하겠죠??

댓글