Pod Anti-Affinity로 같은 노드의 중복 배치 피하기
복제본이 여러 개 있어도 같은 노드에 모여 있으면 그 노드의 장애에 함께 영향을 받을 수 있습니다. Cassandra StatefulSet을 서로 다른 노드에 배치하기 위해 Pod Anti-Affinity를 설정했던 메모입니다.
레이블과 분리 단위
Pod Anti-Affinity는 특정 레이블을 가진 Pod와 같은 범위에 배치하지 않도록 조건을 지정합니다. 어떤 Pod를 볼지는 labelSelector, 어느 범위를 같은 위치로 볼지는 topologyKey로 정합니다.
원래 설정은 app: cassandra 레이블을 가진 Pod를 kubernetes.io/hostname 기준으로 나누는 방식이었습니다. 이 예시의 분리 단위는 노드입니다. 랙이나 가용 영역 단위로 분리하려면 그에 맞는 노드 레이블과 정책이 별도로 필요합니다.
필수 분리 조건
다음은 StatefulSet의 .spec.template.spec 아래에 넣는 설정 일부입니다. 전체 StatefulSet 매니페스트는 아닙니다.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cassandra
topologyKey: kubernetes.io/hostname이 조건은 기본적으로 같은 네임스페이스의 대상 Pod를 기준으로 평가합니다. Pod 템플릿에 실제로 app: cassandra 레이블이 있는지도 맞춰야 합니다.
조건을 만족할 노드가 부족하면 새 Pod는 Pending 상태로 남을 수 있습니다. 복제본 수만 늘리기 전에 노드 수와 자원, Taint 등 다른 배치 조건을 함께 확인해야 합니다.
실행 중인 Pod에 대한 범위
IgnoredDuringExecution은 실행 이후 레이블이나 배치 조건이 바뀌었다고 이 규칙만으로 기존 Pod를 자동 퇴거시키지 않는다는 뜻입니다. 설정을 바꿨다고 이미 모여 있는 Pod가 즉시 재배치되는 것도 아닙니다.
새 Pod의 배치 결과와 기존 Pod의 위치를 함께 확인해야 합니다.
kubectl get pods -n example -l app=cassandra -o wide
kubectl describe pod cassandra-1 -n example선호 조건과의 차이
preferredDuringSchedulingIgnoredDuringExecution은 가능하면 분리해 배치하도록 점수를 주는 방식입니다. 필수 조건을 만족하지 못했을 때 자동으로 선호 조건으로 전환하는 설정은 아닙니다.
두 방식을 함께 적어도 required 조건은 여전히 충족해야 합니다. 분리 보장과 배치 가능성 중 무엇을 우선할지 워크로드에 맞춰 선택해야 합니다.
Pod를 다른 노드에 두는 것만으로 데이터 복제나 저장소의 장애 대응까지 완성되지는 않습니다. 데이터베이스 자체의 복제와 쿼럼, 볼륨의 배치도 함께 확인해야 합니다.