본문 바로가기

About/Kubernetes

[k8s] 파드 스케줄링 - Inter-Pod Affinity, Anti-Affinity(파드 어피니티와 안티 어피니티)

Inter-Pod Affinity, Anti-Affinity

Affinity(Inter-Pod Affinity) Anti-Affinity는 Deployment나 StatefulSet으로 파드를 배포했을 때 개별 파드 사이의 관계를 정의하는 용도로 사용합니다.

Affinity vs Anti-Affinity

Inter-Pod Affinity

Node Affinity가 node의 label을 기준으로 Pod가 배포될 node를 선택한다면, Inter-Pod Affinity 기존에 배포된 Pod를 기준으로 배포될 node를 결정합니다. 

서비스 A의 파드와 서비스의 B의 파드가 자주 통신한다고 했을 때, Affinity는 이런 상황에서 서비스 A와 서비스 B의 파드들을 같은 노드에 속하게 만들어 효율을 높입니다. 예를 들어 데이터베이스나 캐시 같은 서비스와 통신하는 앱 컨테이너를 같은 노드에 두어 네트워크 통신 비용을 줄이는 것이 있습니다. 

Anti-Pod Affinity

Inter-Pod Affinity 와는 반대로 특정 Pod와 함께 배포되는 것을 피하도록 배포될 node를 결정합니다.

Anti-Affinity를 사용하면 CPU나 네트워크 같은 하드웨어 자원을 많이 사용하는 앱 컨테이너가 있을 때 여러 노드로 파드를 분산시킬 수 있습니다. 안티 어피니티를 설정하지 않으면 디플로이먼트로 배포한 파드가 노드 하나에서만 실행되어 자원을 많이 소모할 수도 있습니다. 예를 들어 서비스를 운영하다가 트래픽이 많아졌다고 했을 때 Anti-Affinity가 설정되어 있지 않으면 파드 개수를 늘려도 이미 시스템 사용률이 높은 노드에 다시 같은 역할을 하는 파드가 생성될 수도 있습니다.

Inter-Pod AffinityAnti-Affinity를 사용하는 파드의 예시는 다음과 같습니다.

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: k8s.gcr.io/pause:2.0

Inter-Pod AffinityAnti-Affinity는 Node Affinity와 다르게 spec.template.spec.affinity의 하위 필드인 podAffinitypodAnitiAffinity로 설정합니다. . operator  필드 값으로는 In, NotIn, Exists, DoesNotExist를 사용할 수 있습니다. 이 외에도 설정 방법은 노드 어피니티의 설정 방법과 거의 같습니다. 다음 링크를 참고하세요. (https://kimjingo.tistory.com/144)

Inter-Pod AffinityAnti-Affinity는 Node Affinity와 마찬가지로 Hard Affinity와 Soft Affinity가 있습니다. requiredDuringSchedulingIgnoredDuringExecution 로 hard Affinit를, preferredDuringSchedulingIgnoredDuringExecution로 soft Affinity를 설정합니다. 

또한 topology 라는 필드가 있는데, 이는 노드의 레이블을 이용해 Inter-Pod AffinityAnti-Affinity를 설정할 수 있는 또 하나의 기준입니다. 쿠버네티스는 파드를 스케줄링할 때 파드의 레이블을 기준으로 파드를 실행할 노드를 찾고 topology 필드를 확인해서 해당 노드가 원하는 노드인지 확인합니다. 즉 클러스터의 모든 노드는 topology 와 매칭되는 적절한 레이블을 가지고 있어야 합니다. 
(예를 들어 클라우드 이용 시  topology 를 이용하여 원하는 zone에 파드가 생성 되었는 지 확인하도록 할 수 있습니다.)

labelSelectortopology 외에도 labelSelector 와 일치해야하는 네임스페이스 목록 namespaces 를 선택적으로 지정할 수 있습니다. 생략되어 있거나 비어있는 경우 Inter-Pod AffinityAnti-Affinity 가 정의되어 있는 파드의 네임스페이스가 기본 값입니다.


Inter-Pod AffinityAnti-Affinity에 대해 알아보았습니다.

사용 시 주의할 점으로는 Inter-Pod AffinityAnti-Affinity가 상당한 양의 프로세싱이 필요해 대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있어서, 수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 좋지 않습니다.