Kubernetes/Kubernetes Advanced

📌 [ReplicaSet 심화편 #7] ReplicaSet과 Anti-Affinity: 특정 노드 간 분산 배포 전략

ygtoken 2025. 3. 12. 12:40
728x90

 

1️⃣ 개요

 

쿠버네티스에서 ReplicaSet은 기본적으로 리소스가 충분한 노드에 자동으로 Pod를 배치합니다.

그러나 모든 Pod가 특정 노드에 집중되면, 해당 노드가 장애를 일으킬 경우 서비스 전체가 중단될 위험이 있습니다.

 

이를 해결하기 위해 Pod 간 분산 배포(Anti-Affinity) 전략을 활용하면, 동일한 애플리케이션의 Pod가 서로 다른 노드에 배포되도록 제한할 수 있습니다.

이번 글에서는 ReplicaSet과 Anti-Affinity를 활용한 분산 배포 전략을 설명하겠습니다. 🚀

 


2️⃣ Anti-Affinity란?

 

✅ Affinity vs Anti-Affinity

 

쿠버네티스에서는 Pod 배치 정책을 정의하는 Affinity(선호 배치)Anti-Affinity(분산 배치) 기능을 제공합니다.

 

📌 Affinity와 Anti-Affinity 비교

특징 Affinity (선호 배치) Anti-Affinity (분산 배치)
Pod 배치 방식 특정 노드에 우선 배치 동일한 애플리케이션의 Pod를 다른 노드에 배포
사용 목적 특정 노드에서 실행되도록 강제 한 노드에 Pod가 집중되지 않도록 설정
적용 방식 preferredDuringSchedulingIgnoredDuringExecution 사용 requiredDuringSchedulingIgnoredDuringExecution 사용

Anti-Affinity를 적용하면, 특정 애플리케이션의 모든 Pod가 하나의 노드에 집중되는 것을 방지할 수 있습니다.

 


3️⃣ Anti-Affinity 설정 방법

 

✅ 1. ReplicaSet에서 Anti-Affinity 적용

 

Anti-Affinity는 Pod 템플릿의 spec.affinity.podAntiAffinity 설정을 통해 적용할 수 있습니다.

 

📌 예제: 동일한 app=my-app 레이블을 가진 Pod가 같은 노드에 배포되지 않도록 설정

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - my-app
              topologyKey: "kubernetes.io/hostname"
      containers:
        - name: my-container
          image: nginx

 

📌 설정 설명

podAntiAffinity: 동일한 app=my-app 레이블을 가진 Pod가 같은 노드에 배포되지 않도록 설정

requiredDuringSchedulingIgnoredDuringExecution: 반드시 조건을 만족해야만 Pod가 스케줄링됨

topologyKey: "kubernetes.io/hostname": 노드(hostname) 단위로 분산 배치 적용

 


4️⃣ Anti-Affinity 활용 시 고려해야 할 점

 

✅ 1. preferredDuringSchedulingIgnoredDuringExecution을 사용할 수도 있음

requiredDuringSchedulingIgnoredDuringExecution을 사용하면 반드시 Pod가 다른 노드에 배포되어야 하므로, 노드가 부족할 경우 스케줄링이 실패할 수 있음

유연한 배포를 원한다면 preferredDuringSchedulingIgnoredDuringExecution을 사용하여 우선순위 배치를 적용할 수 있음

 

📌 예제: Anti-Affinity를 권장 설정으로 적용 (우선적으로 다른 노드에 배포하지만, 불가능할 경우 무시)

podAntiAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
            - key: app
              operator: In
              values:
                - my-app
        topologyKey: "kubernetes.io/hostname"

weight 값이 클수록 다른 노드에 배포하려는 우선순위가 높아집니다.

노드가 부족해도 스케줄링이 실패하지 않도록 유연한 분산 배포가 가능합니다.

 


✅ 2. 노드 수가 부족할 경우 배포 실패 가능성 존재

requiredDuringSchedulingIgnoredDuringExecution을 사용할 경우, 노드 수가 부족하면 Pod가 Pending 상태에서 멈출 수 있음

클러스터에 충분한 노드가 있는지 확인해야 하며, 필요하면 수동으로 노드를 추가해야 함

 

📌 현재 실행 중인 Pod 확인

kubectl get pods -o wide

 

📌 현재 사용 가능한 노드 확인

kubectl get nodes

클러스터 리소스를 충분히 확보한 후, Anti-Affinity를 적용하는 것이 중요합니다.

 


5️⃣ Anti-Affinity 적용 후 효과 검증

 

✅ 1. 모든 Pod가 다른 노드에 배포되었는지 확인

 

📌 ReplicaSet의 Pod 배포 상태 확인

kubectl get pods -o wide

 

📌 각 Pod가 배포된 노드 확인

kubectl get pods -o custom-columns="POD:metadata.name,NODE:spec.nodeName"

Pod가 동일한 노드에 배치되지 않고 분산되었는지 확인해야 합니다.

 


✅ 2. Anti-Affinity 설정 변경 후 재배포 테스트

 

Anti-Affinity 설정을 변경한 후 ReplicaSet을 다시 적용하면, 기존 Pod가 재배포됩니다.

 

📌 기존 ReplicaSet 삭제 (Pod도 삭제됨)

kubectl delete replicaset my-replicaset

 

📌 새로운 설정으로 ReplicaSet 재배포

kubectl apply -f replicaset.yaml

배포 후 kubectl get pods -o wide를 실행하여 Pod가 정상적으로 분산되었는지 확인합니다.

 


🔥 6️⃣ 결론

 

ReplicaSet은 기본적으로 리소스가 충분한 노드에 Pod를 배포하지만, 특정 노드에 집중될 수 있음

Anti-Affinity를 활용하면 동일한 애플리케이션의 Pod가 서로 다른 노드에 배포되도록 설정 가능

requiredDuringSchedulingIgnoredDuringExecution을 사용하면 강제적인 분산 배포가 가능하지만, 노드가 부족하면 스케줄링이 실패할 수 있음

preferredDuringSchedulingIgnoredDuringExecution을 사용하면 유연한 분산 배포가 가능

Anti-Affinity 적용 후 kubectl get pods -o wide를 활용하여 정상적으로 분산 배포되었는지 검증해야 함

728x90