← 아티클 목록

쿠버네티스 Pod Affinity·안티어피니티로 배치 제어하기

2027-08-16#kubernetes#affinity#스케줄링

스케줄러는 기본적으로 파드를 알아서 배치합니다. 하지만 "캐시 파드는 웹 파드와 같은 노드에 붙여라" 또는 "DB 복제본 3개는 서로 다른 노드에 흩어라" 같은 요구가 생기면 직접 제어해야 합니다. 이때 쓰는 게 **Pod Affinity(같이 두기)**와 **Pod Anti-Affinity(떨어뜨리기)**입니다. 노드 라벨이 아니라 다른 파드의 위치를 기준으로 스케줄링한다는 점이 핵심입니다.

required vs preferred

종류의미충족 못 하면
requiredDuringScheduling...반드시 만족파드가 Pending 상태로 대기
preferredDuringScheduling...가능하면 만족무시하고 그냥 배치

required는 강제라 조건을 못 채우면 영영 안 뜹니다. preferred는 점수 가중치(weight)일 뿐이라 안전합니다. 운영에서 대부분의 분산 요구는 preferred로 충분합니다.

같이 두기 — Affinity

캐시를 웹 파드와 같은 노드에 두는 예시입니다.

YAML
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: web
          topologyKey: kubernetes.io/hostname

topologyKey가 핵심입니다. kubernetes.io/hostname이면 "같은 노드", topology.kubernetes.io/zone이면 "같은 가용영역"을 기준으로 묶습니다.

떨어뜨리기 — Anti-Affinity

DB 복제본이 서로 다른 노드에 흩어지게 합니다. 한 노드가 죽어도 전부 같이 죽지 않게요.

YAML
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          podAffinityTerm:
            labelSelector:
              matchLabels:
                app: db
            topologyKey: kubernetes.io/hostname

labelSelector가 자기 자신과 같은 라벨(app: db)을 가리킨다는 점에 주의하세요. "나와 같은 라벨의 파드가 있는 노드는 피해라"는 뜻입니다.

흔한 함정 — 파드가 Pending

required 안티어피니티로 "노드당 1개"를 강제했는데 노드 수보다 replicas가 많으면, 남는 파드는 갈 곳이 없어 Pending에 빠집니다.

Kubernetes
kubectl describe pod <pod>
# Events: 0/3 nodes are available: 3 node(s) didn't match pod anti-affinity rules.

이럴 땐 replicas를 노드 수 이하로 줄이거나, requiredpreferred로 바꿔 강제를 풉니다.

체크리스트

Kubernetes
kubectl get pods -o wide               # 의도대로 모였는지/흩어졌는지
kubectl describe pod <pod>             # Pending 사유 확인
kubectl get nodes -L topology.kubernetes.io/zone   # zone 라벨 확인

topologyKey로 쓰는 라벨이 노드에 실제로 붙어 있는지 먼저 확인하는 게 디버깅의 출발점입니다.


affinity 규칙을 직접 걸고 파드가 어디로 가는지 관찰하는 실습은 쿠버네티스 트랙에서 해볼 수 있습니다 — 회원가입 없이 무료로.