11.3 Fencing
Fencing은 인스턴스에서 postgres 프로세스만 확실히 멈추고, Pod는 그대로 살려 두는 기능입니다. 오작동하는 인스턴스를 디버깅하거나, 계속 재시작만 반복하는 Pod를 붙잡아 두고 파일시스템을 들여다볼 때 씁니다. 핵심은 "데이터를 건드리지 않고" 안을 살핀다는 데 있습니다. postgres가 죽어 있으니 그 사이 데이터 파일이 바뀔 일이 없고, Pod는 살아 있으니 안에 들어가 로그·데이터 디렉토리를 조사할 수 있습니다.
fence하면 무슨 일이 일어나는가
fence 절차는 switchover와 같은 방식으로 postgres를 내립니다. 먼저 .spec.switchoverDelay 시간만큼 fast shutdown을 시도하고, 시간이 지나면 immediate shutdown으로 강제 종료합니다. 그 뒤 인스턴스는 다음 상태가 됩니다.
- Pod는 계속 떠 있지만 Ready로 표시되지 않습니다
- 설정 파일·인증서는 계속 조정(reconcile)됩니다
- 메트릭 수집은 멈춥니다. 단
cnpg_collector_fencing_on메트릭만 1로 남아 fence 상태임을 알립니다 - 이 상태에서 Pod를 삭제하면, Pod는 다시 만들어지되 postgres는 시작하지 않습니다
primary를 fence할 때의 위험
primary 인스턴스를 fence하면 postmaster는 내려가지만 failover는 일어나지 않습니다. 즉 새 primary가 승격되지 않은 채 쓰기 경로가 통째로 막혀 애플리케이션이 멈춥니다. primary fencing은 정말 불가피할 때만 합니다. 대개는 문제 있는 replica를 대상으로 씁니다.
방법 1: annotation
cnpg.io/fencedInstances annotation에 대상 인스턴스 이름을 JSON 배열로 넣습니다.
# 인스턴스 하나 fence
kubectl annotate cluster cluster-example --overwrite \
cnpg.io/fencedInstances='["cluster-example-1"]'
# 여러 인스턴스
kubectl annotate cluster cluster-example --overwrite \
cnpg.io/fencedInstances='["cluster-example-1","cluster-example-2"]'
# 클러스터 전체 (와일드카드)
kubectl annotate cluster cluster-example --overwrite \
cnpg.io/fencedInstances='["*"]'
fence를 풀 때는 annotation을 빈 배열로 두거나 아예 지웁니다.
# 빈 배열로
kubectl annotate cluster cluster-example --overwrite \
cnpg.io/fencedInstances='[]'
# annotation 제거
kubectl annotate cluster cluster-example cnpg.io/fencedInstances-
와일드카드 "*"는 클러스터 전체를 한 번에 fence합니다. 클러스터를 완전히 멈추되 데이터는 그대로 두고 싶을 때 씁니다.
방법 2: cnpg 플러그인
플러그인의 fencing 서브커맨드가 위 annotation 조작을 감쌉니다. 손으로 JSON을 쓰지 않아도 되어 더 안전합니다.
# 인스턴스 1번 fence
kubectl cnpg fencing on cluster-example 1
# 클러스터 전체 fence
kubectl cnpg fencing on cluster-example "*"
# 인스턴스 1번 fence 해제
kubectl cnpg fencing off cluster-example 1
# 클러스터 전체 해제
kubectl cnpg fencing off cluster-example "*"
fence된 인스턴스 조사
fence 상태에서는 postgres가 멈춰 있으므로, Pod에 들어가 데이터 디렉토리나 로그를 자유롭게 살펴볼 수 있습니다.
kubectl exec -ti cluster-example-1 -c postgres -- bash
# 컨테이너 안에서 파일시스템·로그 조사
조사가 끝나면 fence를 풀어 postgres를 다시 올립니다. 해제하면 인스턴스 매니저가 postgres를 재기동하고, replica였다면 다시 primary를 따라잡기 시작합니다.
정리
fencing은 postgres만 멈추고 Pod는 살려 두어, 데이터를 바꾸지 않고 문제 인스턴스를 조사하게 해 줍니다. fence된 Pod는 Ready로 표시되지 않고 메트릭도 멈추며, cnpg_collector_fencing_on만 1로 남습니다. 조작은 cnpg.io/fencedInstances annotation(JSON 배열, "*"는 전체)이나 cnpg fencing on/off로 하고, 해제하면 인스턴스 매니저가 postgres를 다시 올립니다. 다만 primary를 fence하면 failover 없이 쓰기 경로가 막히므로 최후의 수단으로만 씁니다.