재시작으로 복구되지 않는 복제본이 있었습니다
8월 초 PostgreSQL 복제본에서 timeline 분기, 필요한 WAL 부재, pg_rewind 실패를 조사했습니다. 같은 데이터를 가진 Pod를 재시작해도 동일한 복구 실패가 반복되는 상태였습니다. CloudNativePG가 정상 primary에서 복제본을 다시 구성하도록 하는 절차를 Bash와 jq 스크립트로 만들었습니다.
복구 전에는 현재 primary를 Kubernetes의 Cluster status에서 다시 읽습니다. 기억하고 있는 Pod 번호나 과거 primary 이름을 사용하면 failover 이후 잘못된 대상을 고를 수 있습니다. 아래는 실제 스크립트의 읽기 전용 검사를 줄인 예제입니다.
set -euo pipefail
namespace=example
cluster=example-db
instance=example-db-3
cluster_json=$(kubectl get cluster.postgresql.cnpg.io "$cluster" \
-n "$namespace" -o json)
pod_json=$(kubectl get pod "$instance" -n "$namespace" -o json)
primary=$(jq -r '.status.currentPrimary // empty' <<<"$cluster_json")
role=$(jq -r '.metadata.labels["cnpg.io/instanceRole"] // empty' <<<"$pod_json")
owner=$(jq -r '.metadata.labels["cnpg.io/cluster"] // empty' <<<"$pod_json")
[[ -n "$primary" && "$owner" == "$cluster" ]]
[[ "$role" == "replica" && "$instance" != "$primary" ]]가상의 이름을 사용하는 이 코드는 대상 역할만 검사합니다. 운영 스크립트에는 Ready primary와 다른 Ready 복제본의 존재, 예상한 데이터 PVC인지, 로그에 WAL 또는 rewind 실패 증거가 있는지 확인하는 조건도 들어갑니다. 증거가 없으면 복제본 재생성 절차를 중단합니다.
백업이 끝나기 전에는 삭제 단계로 가지 않습니다
실제 실행 경로는 읽기 전용 preflight가 기본입니다. 변경을 진행하려면 승인 인자에 대상 복제본 이름을 정확히 지정해야 하고, 그 다음 Barman Cloud 플러그인으로 온디맨드 물리 백업을 생성합니다. Backup의 phase가 completed에 도달하지 않으면 대상 Pod와 PVC를 삭제하는 단계에 들어가지 않습니다.
순서는 역할 확인, 다른 정상 인스턴스 확인, 실패 로그 확인, 안전 백업 완료, 대상 복제본만 재생성, 복제 상태 확인입니다. 스크립트가 있다는 이유로 primary 데이터나 공유 볼륨까지 자동으로 정리하지 않습니다.
새 Pod 생성보다 복제 상태를 확인합니다
복구 뒤에는 새로운 Pod가 Ready인지와 primary에 streaming으로 연결되는지를 함께 확인합니다. 새 Pod UID와 PVC 연결도 대조해 단순히 기존 Pod를 다시 조회한 결과가 아닌지 확인합니다.
이번 구현의 핵심은 kubectl과 jq로 복구 조건을 실행 가능한 검사로 바꾼 점입니다. 백업 완료는 삭제 전 보호 조건이고, 복구 후 데이터베이스의 실제 조회와 복제 상태 확인은 별도 완료 조건입니다.