간혹 한 노드에 같은 디플로이의 파드 2개가 같이 들어있는 경우가 있어서

알아보게 되었음



파드가 배포 되는 방식을 간단하게 보면

어떤 노드에 파드를 배치할 것인지(Node Affinity)

파드들을 어떻게 배치할 것인지(Pod Affinity, Anti-Affinity)

2가지 방식을 사용하는 것 같다.

 

Node affinity는 간단하게 어떤 노드들에 Pod들이 배치될 수 있는지 정해주는 옵션이다.

어떤 노드인지는, 노드에 할당된 label 값을 기준으로 선택하고

label이 있어야 하는지, 없어야 하는지에 따라

해당 label이 있는 노드에만 파드 배치 해당 label이 있는 노드를 피해서 파드 배치를 정할 수 있다.

 

Pod affinity는 어떤 파드들 끼리 모여있어야 한다고 정해주는 옵션이다.

노드와는 다르게 pod Anti Affinity 필드가 별도로 있다.

Pod Anti Affinity는 특정 파드들이 떨어져 있어야한다는 필드이다.

 


Node Affinity

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - antarctica-east1
            - antarctica-west1
            
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value

 

requiredDuringSchedulingIgnoredDuringExecution

조건을 필수로 적용하는 옵션이다.

파드가 배포될 노드에는

zone=antarctica-east1 또는

zone=antarctica-west1 이라는 label이 반드시 설정되어 있어야 한다

 

operator는 In, NotIn, Exist, DoesNotExist 가 있다.

In 특정 값이 포함되면 매칭 valus가 여러개의 경우 하나만 있으면 됨
NotIn 특정 값이 포함되지 않으면 매칭  
Exist 특정 라벨이 존재하면 매칭  
DoesNotExist 특정 라벨이 존재하지 않으면 매칭  

 

 

 

preferredDuringSchedulingIgnoredDuringExecution

선호 되는 조건이지만 꼭 지켜지지 않아도 되는 조건이다.

weight 필드 값으로 가중치를 부여

노드가 another-node-label-key=another-node-label-value의 label을 갖고 있으면 파드를 우선적으로 배치한다

 

 

아래와 같은 결과로 배치될 것이다.

 

zone=antarctica-east1 or anrarctica-west1을 만족하는 label을 갖고있는 노드여야 하고

another-node-label-key=another-node-label-value의 label을 갖고있는 노드에 파드를 우선적으로 배치하였다.

another-node-label-key=another-node-label-value의 label 만 있는 경우는

required 조건을 만족하지 않아 pod가 배포 되지 않는다.

 

 

만약 특정 조건의 노드를 피하고 싶다면 operator에 NotIn이나 DoesNotExist 연산자를 사용하면 된다.

 


 

 

Pod affinity , Pod AnitiAffinity

파드를 배포할때 특정 조건의 파드가 모여있을지 떨어져있을지를 결정하는 옵션이라고 보면 된다.

Node Affinity와 거의 유사하며 topologyKey라는 옵션에 배포될 노드에 관한 조건을 적는 부분이 추가된다.

 

특정 label을 가진 파드가 배포된 노드가 가진 label값을 기준으로 파드가 배포될지 아닐지 설정한다

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: blog
            operator: In
            values:
            - test1
        topologyKey: topology.kubernetes.io/os
      
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: blog
              operator: In
              values:
              - test2
          topologyKey: topology.kubernetes.io/hostname

 

 

Pod Affinity vs Anti-Affinity

 

podAffinity 파드가 특정 조건에따라 "모여"있게

podAntiAffinity 파드가 특정 조건에따라 "흩어져" 있게

 

spec 필드 아래 affinity 필드아래에서 위의 두 옵션을 적용하여 운영한다.

 

특정 조건을 만족하는 파드가 배포된 노드와

특정 조건이 같은 노드에 파드를 배포할지 말지 결정한다.

 


예를 들면 위의

PodAffinity에서는 특정조건을 만족하는 pod가 배포된 노드에 pod를 배포한다는 의미이다.

 

1. blog=test1 이라는 label을 갖는 pod

2. blog=test1 이라는 label을 갖는 pod가 배포된 노드의 OS

 

위의 두 조건을 만족하는 노드에 파드를 배치하겠다는 이야기이다.

 

required가 적용되고, 아무것도 없는 상황에서 첫 스크립트에 위와 같은 PodAffinity 옵션을 적용하면

파드가 생성되지 않는다.

preferred가 적용되면, 조건을 만족하지 않아도 생성이 된다.

 

 

 

반대로 Pod Anti Affinity에서는

 

위의 두 조건을 만족하는 노드에는 파드를 배치하지 않겠다는 이야기 이다.

만약 기준을 os로 했는데 모든 노드가 같은 os를 사용중이면 파드가 생성되지 않는다.

마찬가지로 preffered가 적용된 상황에서는 파드가 생성된다.


topologyKey

 

 

topologyKey는 노드에 할당된 값들을 사용하거나

정해진 값이 아닌 경우에는 노드의 label을 기준으로 동작한다.

 

topology.kubernetes.io/hostname

* node의 hostname

topology.kubernetes.io/region

* node의 region // ex) us-west-1

topology.kubernetes.io/zone

* node의 AZ 같은 가용지역 // ex) kr2, 1

topology.kubernetes.io/instance-type

* node의 instance type // ex) m5.large, SVR.VSVR.HIMEM.C002.M016.G003

topology.kubernetes.io/os

* node의 os 종류 // ex) linux, windows

topology.kubernetes.io/arch

* node의 시스템 아키텍쳐 // ex) amd64 , amd32

 

 

 


파드를 각 노드에 골고루 분배해야 하는 경우

파드를 각 노드에 공고루 분배해야하는 경우

 

모든 노드가 기준이므로 node Affinity 는 사용하지 않고

분배되어야 하므로 Pod AntiAffinity를 사용한다.

 

Pod AntiAffinity에서 topologyKey를 hostname으로 하여

노드가 겹치지 않게 한다.

 

만약 특정 zone이나 os를 갖는 노드 중에서 골고루 분배하고 싶으면

NodeAffinity를 사용하여 묶는다

 

 

+ Recent posts