매일 밤 내리고 아침에 올리는 운영을 하다가, 어느 날 다른 파드는 모두 올라왔는데 PostgreSQL 파드만 생기지 않는다. 오퍼레이터 파드는 정상이고 로그도 listening on port 8443 에서 더 나아가지 않는다. PostgresCluster 리소스를 보면 상태가 다음과 같다.
Database shutdown along with the following services: sas-crunchy-data-postgres-backrest-shared-repo
PVC 는 모두 Bound 이고 CRD 도 정상이다.
먼저 짚어야 할 것은 조작 대상이다. Crunchy PostgreSQL 은 오퍼레이터가 StatefulSet 을 만들고 관리한다. StatefulSet 이나 Deployment 의 replicas 를 직접 0 과 1 사이로 오가게 하는 방식으로 기동을 제어하면, 오퍼레이터가 자기 기대 상태로 되돌려 놓거나 반대로 두 쪽의 기대가 어긋나 아무도 파드를 만들지 않는 상태가 된다. 매일 이 방식으로 내렸다 올렸다면 어느 날 올라오지 않는 것은 시간 문제다.
기동·정지는 커스텀 리소스의 필드로 한다.
kubectl get postgrescluster -n <VIYA_NS>
kubectl get postgrescluster <NAME> -n <VIYA_NS> -o yaml | grep -n -A3 'shutdown\|paused'
두 필드를 헷갈리면 아무 일도 일어나지 않는다.
| 필드 | 뜻 |
|---|---|
spec.shutdown |
true 면 인스턴스를 모두 내린다. 상태가 Shutdown 으로 표시된다 |
spec.paused |
true 면 오퍼레이터가 이 리소스의 조정을 멈춘다. 파드는 그대로 둔다 |
상태가 Shutdown 이라면 되돌릴 필드는 shutdown 이다. paused: false 를 넣어도 내려간 인스턴스는 올라오지 않는다. 그리고 CRD 스키마에 없는 필드를 억지로 넣으려 하면 검증에서 거부된다 — 필드가 없다는 것은 "그 필드가 원인이 아니다" 는 신호로 읽는다.
kubectl patch postgrescluster <NAME> -n <VIYA_NS> --type=merge -p '{"spec":{"shutdown":false}}'
kubectl get postgrescluster <NAME> -n <VIYA_NS> -w
paused: true 가 남아 있으면 shutdown 을 바꿔도 오퍼레이터가 반응하지 않는다. 둘 다 확인한다.
kubectl patch postgrescluster <NAME> -n <VIYA_NS> --type=merge -p '{"spec":{"paused":false}}'
정지·기동을 자동화한다면 이 필드를 바꾸는 것이 정석이다. Viya 4 가 제공하는 정지·기동 스크립트도 같은 일을 한다.
필드를 바꿨는데도 StatefulSet 이 생기지 않으면 오퍼레이터 쪽을 본다.
kubectl logs -n <VIYA_NS> deploy/<PGO_DEPLOY> --tail=200
kubectl get events -n <VIYA_NS> --sort-by=.lastTimestamp | tail -30
오퍼레이터가 기동 직후 메시지만 남기고 조정 로그를 전혀 남기지 않는다면 감시 대상 네임스페이스 설정이나 RBAC 을 확인한다. 리더 선출 Lease 가 죽은 인스턴스 이름으로 남아 새 파드가 리더를 잡지 못하는 경우도 있다.
kubectl get lease -n <VIYA_NS>
정지·기동을 CronJob 으로 돌리는 구성에서 다음 오류를 만난다.
the server doesn't have a resource type "postgresclusters.postgres-operator.crunchydata.com"
CRD 는 있는데 Job 이 못 찾는 상황이므로 두 가지를 본다. 첫째, Job 의 ServiceAccount 에 해당 리소스에 대한 권한이 있는지 본다. 권한이 없으면 API 검색 결과에서 아예 빠져 "리소스 타입이 없다" 는 모양으로 나타난다.
kubectl auth can-i get postgresclusters \
--as=system:serviceaccount:<VIYA_NS>:<SA> -n <VIYA_NS>
둘째, 같은 Job 로그에 timeout 이 함께 찍혀 있다면 API 검색 자체가 시간 안에 끝나지 못한 것이다. 이 경우는 권한 문제가 아니라 API 서버 또는 확장 API 서비스가 느린 것이므로, APIService 중 Available=False 인 것이 없는지 확인한다.
kubectl get apiservice | grep -v 'True'
PostgresCluster 를 지우고 같은 매니페스트로 다시 만들면 PVC 가 남아 있는 한 데이터는 유지된다. 다만 이것은 조건부다. 지우기 전에 반드시 확인한다.
PVC 의 persistentVolumeReclaimPolicy 가 Delete 이면 PVC 가 함께 지워질 때 실제 볼륨도 사라진다. 오퍼레이터가 PVC 에 소유자 참조를 걸어 두었다면 커스텀 리소스를 지울 때 PVC 도 가비지 컬렉션된다.
kubectl get pvc -n <VIYA_NS> -l postgres-operator.crunchydata.com/cluster=<NAME>
kubectl get pv | grep <VIYA_NS>
kubectl get pvc <PVC> -n <VIYA_NS> -o jsonpath='{.metadata.ownerReferences}'
소유자 참조가 걸려 있으면 재배포 전에 해당 PV 의 회수 정책을 Retain 으로 바꿔 두거나, pgBackRest 백업에서 복구할 수 있는지 먼저 확인한다. 파드 재배포(kubectl delete pod)와 StatefulSet 재생성은 데이터에 영향이 없으므로 그 선에서 먼저 시도한다.
kubectl delete pod -n <VIYA_NS> -l postgres-operator.crunchydata.com/cluster=<NAME>