Patroni 계열 오퍼레이터가 관리하는 Pod 는 몇 초마다 자기 역할을 판단하고 그 결과를 로그로 남긴다. 자주 보이는 세 줄의 뜻은 다음과 같다.
| 로그 | 뜻 |
|---|---|
no action. I am a secondary and following a leader |
정상. 나는 복제본이고 리더를 따라가는 중이다 |
no action. I am the leader with the lock |
정상. 나는 리더이고 리더 잠금을 쥐고 있다 |
following a different leader because I am not allowed to promote |
승격 조건을 만족하지 못해 다른 노드를 따른다 |
I am a secondary and following a leader 는 오류가 아니다. 이 줄만 보고 "승격이 안 된다" 고 판단하면 안 된다. 리더가 이미 있는지부터 확인한다.
kubectl exec -it pg-0 -- patronictl list
kubectl get endpoints -l application=patroni
kubectl get lease -A | grep -i pg
전체 노드가 replica 이고 리더가 없다면 그때가 진짜 문제다.
리더 선출은 분산 합의 저장소(DCS)에서 이뤄진다. 오퍼레이터에 따라 etcd, Consul, Kubernetes 의 Endpoints 또는 ConfigMap 을 쓴다. 이 저장소에 접근하지 못하면 아무도 리더가 되지 못한다.
# 오퍼레이터 로그에 리더 관련 기록이 아예 없다면 감시 자체가 안 되는 것이다
kubectl logs deploy/postgres-operator --tail=200
# 각 Pod 의 Patroni 상태
kubectl exec -it pg-0 -- curl -s localhost:8008/patroni | head -40
cluster initialized 라고만 떠 있고 더 진행되지 않는 상태는 다음 중 하나인 경우가 많다.
오퍼레이터가 변경을 놓친 상태라면 커스텀 리소스를 다시 적용해 조정 루프를 깨운다.
kubectl apply -f postgres-cluster.yaml
kubectl annotate postgresql pg --overwrite reconcile-ts="$(date +%s)"
이 방법으로 I am the leader with the lock 이 나오면 조정 루프가 멈춰 있었던 것이다. 재발하면 오퍼레이터 Pod 의 재시작 이력과 리소스 제한(OOMKilled 여부)을 본다.
kubectl get pod -l name=postgres-operator -o wide
kubectl describe pod <operator-pod> | sed -n '/Last State/,/Ready/p'
kubectl scale 로 강제로 다시 띄워 fully initialized for cluster 가 나왔다면 증상은 사라졌지만 원인은 남아 있다. 조정 루프가 왜 멈췄는지, DCS 가 왜 응답하지 않았는지를 기록으로 남기지 않으면 같은 상황이 반복된다.
특히 StatefulSet 를 스케일 다운했다가 올리는 조작은 PVC 와 역할 상태가 어긋날 위험이 있다. 복제본을 지우기 전에 어느 Pod 가 최신 LSN 을 갖고 있는지 확인한다.
SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn();