6.8 KiB
date, topic, areas, tags
| date | topic | areas | tags | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 2026-04-16 | pgpool-II PoC (n8n 전용 전환) |
|
|
n8n 이 Patroni failover 와 etcd 순단에 풀 좀비로 취약 — pgcat 의 클라이언트-측 연결 관리로는 해소 불가. pgpool-II streaming_replication 모드 PoC 로 n8n 만 전환, 검증 결과 양쪽 시나리오에서 무에러 또는 <2초 자가복구 달성.
전환 경로
- 전환 전: n8n → pgcat.db.svc:6432 → OpenWrt HAProxy 192.168.9.1:5432 → Patroni leader
- 전환 후: n8n → pgpool.db.svc:9999 → Patroni 3노드 직결
NocoDB·Outline 은 pgcat 유지. 7일 관측 후 확대 여부 판단.
이미지 선택
- kappa 원 스펙:
pgpool/pgpool:4.6.3 (공식)— 존재하지 않음.pgpool/pgpool리포지토리 최대 태그 4.4.3 (2024 이후 방치), 이후 버전은bitnamilegacy/pgpool에만 존재 - 1차 시도: Bitnami 4.6.3 — env 기반 설정 자동화가 scram-sha-256 패스워드를 pgpool 내부 포맷으로 재해시해서 백엔드 인증 실패. 디버깅 폐기 (kappa 지시)
- 2차 채택:
pgpool/pgpool:4.4.3(공식) + 최소 ConfigMap 마운트
최종 설정 (helm-charts/pgpool/)
ArgoCD 관리 대상. kaffa/helm-charts 리포 pgpool/ 디렉토리 raw manifest. Application 매니페스트 kubectl apply 로 1회 부트스트랩.
핵심 구성
pgpool.conf (~30 라인):
listen_addresses = '*'
port = 9999
backend_clustering_mode = 'streaming_replication'
backend_hostname0 = '10.100.2.5' # postgres-1
backend_port0 = 5432
backend_weight0 = 1
backend_flag0 = 'ALLOW_TO_FAILOVER'
# ... backend1=postgres-2, backend2=postgres-3 동일 패턴
sr_check_user = 'sr_check'
sr_check_password = '<plaintext>'
sr_check_database = 'postgres'
sr_check_period = 10
health_check_user = 'sr_check'
health_check_password = '<plaintext>'
health_check_period = 10
health_check_timeout = 5
failover_on_backend_error = off # Patroni 가 promotion 수행
failover_command = ''
follow_primary_command = ''
use_watchdog = off
enable_pool_hba = on
allow_clear_text_frontend_auth = on
load_balance_mode = off # 모든 쿼리 primary
num_init_children = 32
max_pool = 4
connection_cache = on
pool_hba.conf:
local all all trust
host all all 0.0.0.0/0 password
host all all ::/0 password
인증 설계 핵심
Postgres 가 cluster-wide password_encryption = scram-sha-256 이라 모든 역할 비밀번호는 SCRAM 해시로 저장. pgpool 이 백엔드에 scram-sha-256 auth 하려면 plaintext 필요.
pool_passwd미사용 — pgpool 이 plaintext 엔트리를 자동 md5 로 변환하면 backend SCRAM 거절되어failed to authenticate with backend using SCRAM발생allow_clear_text_frontend_auth=on+ pool_hbapassword메소드 → 클라이언트가 plaintext 로 전송 → pgpool 이 그 값을 backend SCRAM challenge-response 에 그대로 사용- K8s Service 내부 트래픽이므로 clear-text 는 클러스터 내 허용
- 장기: pgpool PGPOOLKEYFILE + AES 암호화 password 도입 검토 (Bitnami 가 하는 방식)
Secret 처리
pgpool-secrets K8s Secret (수동 kubectl create, git 미추적):
sr_check_password— 16-byte hex 랜덤n8n_password—n8n(pgcat 와 동일)
entrypoint.sh 가 env 에서 sed 로 pgpool.conf.tmpl 의 __SR_CHECK_PASSWORD__ 를 치환하여 emptyDir 에 pgpool.conf 렌더. 정규 운영 승격 시 ExternalSecret + Vault 로 이관.
Patroni 에 sr_check role 생성
CREATE ROLE sr_check WITH LOGIN REPLICATION PASSWORD '<hex>';
GRANT pg_monitor TO sr_check;
postgres-2(당시 leader) 에서 실행, async streaming 으로 postgres-1/postgres-3 에 자동 전파. pg_hba 는 host all all 0.0.0.0/0 md5 이미 설정되어 있어 추가 변경 불필요.
검증 시나리오
1. Patroni switchover (postgres-3 → postgres-2)
T0 T1(+4.0s) T1+2s
switchover → done new primary 라우팅 확립
- n8n 로그:
failed to create a backend 2 connection× 1 →Database connection recovered - pgpool
SHOW POOL_NODES:last_status_change가 switchover 시점에 갱신,role=primary가 새 노드로 이동 - n8n.inouter.com 200 유지
- 자동 복구 ~2초
비교: 같은 시나리오 pgcat 에서는 client 측 pg 풀이 idle 소켓 재사용으로 좀비 → pod restart 필요 (2026-04-15 19:53 UTC 사고 1038 에러).
2. mbp etcd 60초 stop
T0 T+30s 중간 쓰기 T+60s T+70s
mbp stop → SELECT OK, write OK → mbp start → 확인: 계속 쓰기 OK
- n8n 에러 0건, HTTP 200 유지
- pgpool 이 backend Patroni 자체를 직접 봄 — etcd 쿼럼은 2노드(NAS + jp1) 로 유지되어 Patroni leader 변경 없음, pgpool 경로 영향 없음
비교: pgcat 경로에서는 mbp etcd 56초 다운 시 n8n Database connection timed out 캐스케이드 → 503 → pod restart 필수 (오늘 오후 인시던트).
배포 아티팩트
- helm-charts 디렉토리:
pgpool/—configmap.yaml,deployment.yaml,service.yaml,pdb.yaml - ArgoCD Application:
pgpool(namespaceargocd, source pathpgpool, selfHeal + prune) - K8s 리소스: namespace
db(pgcat 와 공존)
롤백
n8n ConfigMap n8n-app-config 에서 DB_POSTGRESDB_HOST 를 pgpool.db.svc.cluster.local:9999 에서 pgcat.db.svc.cluster.local:6432 로 되돌리고 rollout restart. 소요 시간 ~30초.
7일 관측 계획 (만료 2026-04-23)
- 자연 Patroni failover 발생 시 n8n 에러 창 <5초 유지 여부
- pgpool
SHOW STATS/SHOW POOL_NODES주간 샘플링 - n8n 일별 DB 에러 카운트 (목표 <10/day 비-failover 시)
- pgpool 리소스 사용량 (num_init_children=32 × max_pool=4 = 최대 128 backend connections per pod × 2 pod = 256 total. 현재 n8n 평균 idle 수준 확인 필요)
긍정 관측이면 NocoDB → pgpool, Outline → pgpool 단계 전환. 부정이면 pgpool 해체 + pgcat 복귀.
참조
- helm-charts commit 시리즈: a6f5991(초기) → e1dcd6d(bitnami 전환) → 213babb(scram) → 13dfae1(port 수정) → d3dde47(detach_false_primary) → bc6faae(공식 이미지 피봇) → 74ca477(pool_passwd 제거) → 9bc3a24(clear-text auth, 최종)
- 선행 조사: n8n 풀 좀비
230ec530-b8a6-406c-9165-35c9eb2d8282 - pgcat 후속: TCP keepalive
129fbf50-e69b-47fd-ad55-3f5ff9066caf - retry_timeout 상향 → mbp etcd hiccup 시 n8n 503 사고 (오늘 오후) → pgpool PoC 의 직접 동기
미해결 / Syn 공유
pgpool/pgpool4.4.3 이후 방치 — pgpool 공식 이미지의 미래 불확실. 대안: Bitnami legacy 계속 사용하거나 우리가 커스텀 빌드- plaintext pool_passwd 우회 — scram-sha-256 백엔드 + pgpool 백엔드 auth 에 권고 방식은 AES 암호화. 1주 관측 후 하드닝 필요