pgcat HA 승격 (Step 0): replicas=2 + podAntiAffinity + PDB

This commit is contained in:
heimdall
2026-04-15 17:21:13 +09:00
parent ad230522be
commit a7ecd4b982
2 changed files with 79 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
---
date: 2026-04-15
topic: pgcat HA 승격 (Step 0)
areas:
- infra/postgresql-ha.md
tags: [history, pgcat, patroni, postgresql, ha]
---
Patroni multi-host 마이그레이션 Step 0 — pgcat 자체를 HA로 승격. 이후 Step 1에서 pgcat 를 Patroni REST API aware 로 전환할 때, pgcat 자체가 새 SPoF 가 되지 않도록 선행.
## 변경 내용
### helm-charts (`kaffa/helm-charts`)
- `charts/app` v0.3.0 → **v0.5.0**
- `templates/deployment.yaml`: `affinity`, `topologySpreadConstraints` 블록 지원 추가
- `templates/pdb.yaml` 신규 — `podDisruptionBudget.minAvailable` / `maxUnavailable` 지원
- `values/pgcat.yaml`:
- `replicaCount: 2`
- `affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution` (`app=pgcat`, `topologyKey: kubernetes.io/hostname`)
- `podDisruptionBudget.minAvailable: 1`
Commit: `421baef` (`pgcat HA: replicas=2, podAntiAffinity(hostname), PDB minAvailable=1`)
### ArgoCD
`pgcat` Application 은 `syncPolicy.automated { prune: true, selfHeal: true }` 설정. git push 직후 `argocd.argoproj.io/refresh=hard` annotate 로 즉시 sync 트리거.
## 롤아웃 관찰
- 시작: pgcat-545b8878b9-n45h8 (kr2) 단독 Running
- 중간: 구 RS + 신 RS surge 상태 (최대 4 pod), `maxSurge=25%` / `maxUnavailable=25%` 기본 strategy 동작
- 종료 (~55초): pgcat-549446cd6b-4hnk2 (**kr1**) + pgcat-549446cd6b-9rhk4 (**hp2**) 2/2 Running
- PDB `pgcat`: `minAvailable=1`, `AllowedDisruptions=1` — 정상
### 노드 분산 검증
```
pgcat-549446cd6b-4hnk2 2/2 Running incus-kr1 10.42.1.107
pgcat-549446cd6b-9rhk4 2/2 Running incus-hp2 10.42.2.175
```
kr1 + hp2 — 서로 다른 노드. PodAntiAffinity 동작 확인.
### 서비스 Endpoints
```
pgcat 10.42.1.107:6432,10.42.2.175:6432
```
두 replica 모두 Service 뒤에 등록.
## 다운스트림 영향
rollout 중 NocoDB/n8n 로그 tail. 결과:
- NocoDB: 단일 `Connection Error: Connection ended unexpectedly` 1회 — pod 재시작 없음, 45h 업타임 유지. knex/pg 자동 재연결 동작.
- n8n: 에러 없음.
## 롤백 경로
- `values/pgcat.yaml` 에서 `replicaCount: 2``1`, `affinity`/`podDisruptionBudget` 블록 제거
- 또는 chart 측: 구 버전 (v0.3.0) 으로 `targetRevision` 지정 불가능 (단일 리포지토리 path) — 필요 시 역커밋
## 후속 작업
- Step 1: pgcat `pgcat.toml``use_patroni_api = true` + `patroni_api_port = 8008` 추가, 각 pool `shards.0.servers` 를 Patroni 3노드 IP (`10.100.2.5`, `10.100.3.185`, `10.100.1.83`) 로 교체. 관련 Outline 문서: `07497dd8-c8f7-4027-bb27-7d2cf10623a0`

View File

@@ -121,6 +121,18 @@ NocoDB, n8n 등 K3s 내부 애플리케이션은 **pgcat**(연결 풀링)을 통
nocodb/n8n → pgcat (db.svc.cluster.local:6432) → HAProxy 192.168.9.1:5432 → Patroni Leader nocodb/n8n → pgcat (db.svc.cluster.local:6432) → HAProxy 192.168.9.1:5432 → Patroni Leader
``` ```
### pgcat HA 구성
`db/pgcat` Deployment는 **2 replica**, 서로 다른 K3s 노드에 강제 분산.
- `replicaCount: 2` (Helm values `values/pgcat.yaml`)
- `podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution` (topologyKey `kubernetes.io/hostname`)
- `PodDisruptionBudget` `minAvailable: 1` — 최소 1개 pod 유지 보장
- `Service` ClusterIP 로 두 endpoint 모두 등록 — 클라이언트 요청은 kube-proxy 라운드로빈
- 노드 장애 또는 롤아웃 시 나머지 replica가 트래픽 흡수. NocoDB는 일시적 `Connection ended unexpectedly` 후 자동 재연결 (drop 1회, 재시작 없음)
`ghcr.io/postgresml/pgcat:latest`. app chart 템플릿은 `affinity` / `topologySpreadConstraints` / `podDisruptionBudget` 옵션 지원 (v0.5.0+).
`db/pgcat-config` ConfigMap의 각 풀의 `shards.0.servers`**HAProxy 단일 백엔드만 가리켜야 함**: `db/pgcat-config` ConfigMap의 각 풀의 `shards.0.servers`**HAProxy 단일 백엔드만 가리켜야 함**:
```toml ```toml