본문으로 건너뛰기

2.3 인스턴스 매니저

앞 절에서 Operator가 Pod를 만든다고 했습니다. 그런데 Pod 안에서 postgres 프로세스를 실제로 띄우고 지키는 것은 Operator가 아닙니다. 각 Pod 안에는 인스턴스 매니저(instance manager)라는 프로세스가 PID 1로 떠 있고, 이 프로세스가 postgres(postmaster)의 부모가 되어 생애 전체를 관리합니다. 외부 HA 도구(Patroni, repmgr 등) 없이 failover가 가능한 것은 이 인스턴스 매니저가 그 역할을 대신하기 때문입니다.

Pod 안의 구조​

인스턴스 매니저는 두 방향을 봅니다. 아래로는 postmaster를 기동하고 관리하며, 위로는 kubelet의 probe 요청에 응답하고 Kubernetes API와 통신해 클러스터 전체 상태를 파악합니다. .spec.instances가 3이면 이런 Pod가 3개 생기고, 그중 하나만 primary로 동작합니다.

세 가지 probe​

CloudNativePG 인스턴스 probe 상태 전이

Kubernetes는 컨테이너 건강 상태를 probe로 확인합니다. 인스턴스 매니저는 세 종류의 probe에 대한 응답을 담당합니다.

startup​

startup probe는 postgres가 완전히 기동을 마쳤는지 확인합니다. 기본값은 pg_isready입니다. 이 probe가 통과하기 전에는 liveness·readiness 검사가 비활성 상태이며, startup이 실패하면 컨테이너를 종료하고 재시작합니다.

  • .spec.startDelay — 기동 허용 최대 시간, 기본 3600초
  • .spec.probes.startup.type — pg_isready(기본)·query·streaming
  • maximumLag — streaming 타입일 때 허용 복제 지연(바이트). 기동 시점에만 검사

liveness​

liveness probe는 startup 통과 후 시작되며, 인스턴스 매니저가 정상 동작하는지 봅니다. 실패하면 Kubernetes가 컨테이너를 종료하고 재시작합니다.

  • .spec.livenessProbeTimeout — 기본 30초

1.27부터 primary 전용 격리 검사(isolation check)가 추가됐습니다. 인스턴스 매니저가 (1) Kubernetes API에 닿지 못하고 (2) 다른 어떤 인스턴스에도 REST API로 닿지 못하면 liveness 실패를 보고합니다. 즉 네트워크에서 고립된 primary를 스스로 내려 스플릿 브레인을 막습니다. .spec.probes.liveness.isolationCheck.enabled로 켜고 끄며 기본값은 켜짐입니다.

readiness​

readiness probe도 startup 통과 후 시작되며, postgres가 트래픽을 받을 준비가 됐는지 봅니다. 실패하면 Pod가 unready로 표시되어 서비스 트래픽에서 빠지고, failover 시 승격 후보에서도 제외됩니다.

  • 기본 failureThreshold 3, periodSeconds 10, timeoutSeconds 5
  • type·maximumLag 커스터마이즈 가능. startup과 달리 maximumLag를 상시 검사
경고

readiness의 streaming + maximumLag는 신중히 써야 합니다. 지연이 큰 replica가 계속 unready로 빠지면 승격 후보와 synchronous 대상에서 제외되고, 읽기 서비스가 흔들리며, 최악의 경우 승격할 후보가 없어 failover가 지연되고 클러스터가 멈출 수 있습니다. PostgreSQL 복제에 익숙하지 않다면 기본값을 쓰는 편이 안전합니다.

종료 시퀀스​

Pod가 삭제되거나 노드가 drain되면 kubelet이 인스턴스 매니저에 종료 신호를 보냅니다. 인스턴스 매니저는 postgres를 곧바로 죽이지 않고 단계적으로 내립니다.

CHECKPOINT + smart shutdown​

CHECKPOINT를 한 번 실행한 뒤 smart shutdown을 겁니다. 새 연결을 막되 기존 연결은 끝날 때까지 기다립니다. 이 단계는 .spec.smartShutdownTimeout(기본 180초)까지 지속됩니다.

fast shutdown​

아직 살아 있으면 fast shutdown으로 전환합니다. 기존 연결을 끊고 즉시 종료하되, WAL을 아카이빙·전송 중이면 .spec.stopDelay(기본 1800초)의 남은 시간만큼 마무리를 기다린 뒤 강제 종료합니다.

switchover 시의 종료​

계획된 switchover에서는 종료가 다르게 동작합니다. 기존 primary의 인스턴스 매니저는 CHECKPOINT 후 곧바로 fast shutdown을 걸어, 새 primary 승격 전에 데이터가 후임에게 넘어가도록 합니다. 이때 graceful shutdown과 WAL 아카이빙에 허용하는 시간이 .spec.switchoverDelay(기본 3600초)입니다.

일반 종료와 계획 전환의 종료 순서

경고

switchoverDelay는 RPO·RTO의 균형점을 결정합니다. 값이 작으면 전환이 빠르지만(RTO 유리) 미처 넘기지 못한 데이터가 손실될 위험이 있고(RPO 불리), 크면 손실 위험은 줄지만 전환 동안 primary가 오래 멈춥니다. 또한 primary Pod를 직접 삭제하는 것은 피해야 합니다. 데이터 손실과 백업 정합성 훼손으로 이어질 수 있으므로, primary를 내릴 때는 항상 switchover를 먼저 실행합니다.

디스크가 가득 찼을 때​

인스턴스 매니저는 다음 WAL 세그먼트를 쓸 공간이 남았는지 확인해 스토리지 고갈을 감지합니다. 디스크가 가득 찬 상황에서는 failover를 트리거하지 않습니다. 다른 Pod로 옮겨 봐야 같은 문제가 반복될 뿐이고, 사람이 원인을 해결하도록 두는 편이 낫기 때문입니다. 보통은 PVC 크기를 늘리고 Cluster 리소스의 스토리지 크기를 맞춰 갱신하면, Pod가 재시작하며 정상으로 돌아옵니다.

정리​

  • 각 Pod의 PID 1은 인스턴스 매니저입니다. postmaster의 부모로서 생애 전체를 관리하고, 외부 HA 도구(Patroni·repmgr) 없이 failover가 가능한 것도 이 프로세스 덕분입니다.
  • probe는 startup(기동 확인) → liveness(생존·격리) → readiness(트래픽 준비) 순으로 동작합니다. 종료는 CHECKPOINT → smart → fast 단계를 밟되, switchover에서는 곧바로 fast로 전환해 데이터 이관을 앞세웁니다.
  • 디스크 풀은 예외입니다. failover를 트리거하지 않고, 사람이 PVC를 늘려 원인을 풀 때까지 기다립니다.