본문으로 건너뛰기

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는 시작하지 않는다
    flowchart TD
  RUN["정상 running"] -->|fence on| SD["fast shutdown<br/>→ immediate"]
  SD --> FEN["fenced 상태"]
  FEN -->|Pod 조사| INV["데이터 변경 없이<br/>파일시스템 점검"]
  FEN -->|fence off| RES["postgres 재기동"]
  RES --> RUN

  classDef node fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  class RUN,SD,FEN,INV,RES node
  

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만 남음)
  • primary fencing은 failover 없이 쓰기를 막으므로 최후의 수단
  • annotation cnpg.io/fencedInstances(JSON 배열, "*"=전체) 또는 cnpg fencing on/off
  • 해제하면 인스턴스 매니저가 postgres를 재기동

다음 절(11.4)에서는 데이터를 지키면서 클러스터를 통째로 재우는 hibernation을 본다.