PgWeb
PgWeb은 웹 브라우저에서 PostgreSQL 데이터베이스를 탐색하고 SQL을 실행할 수 있는 경량 관리 UI입니다. Lumie 인프라에서는 앱 클러스터(lumie-db 네임스페이스)의 lumie 데이터베이스에 연결되며, 공개 인그레스 없이 Teleport Web App 터널로만 접근할 수 있습니다.
개요
주요 사양
| 항목 | 값 |
|---|---|
| 이미지 | sosedoff/pgweb:0.17.0 |
| 네임스페이스 | lumie-db |
| 포트 | 8081 (컨테이너), 80 (서비스) |
| 접근 방법 | Teleport Web App 터널 (공개 인그레스 없음) |
| 연결 대상 | lumie-db-rw.lumie-db.svc:5432/lumie |
| 헬름 차트 | bjw-s/app-template v3.6.1 |
| 배포 방식 | ArgoCD (자동 동기화) |
아키텍처
설치 및 구성
Helm Values
PgWeb은 bjw-s/app-template 차트를 사용합니다.
controllers:
main:
replicas: 1
annotations:
reloader.stakater.com/auto: "true"
containers:
main:
image:
repository: zot.lumie-infra.com/sosedoff/pgweb
tag: "0.17.0"
args:
- "--bind=0.0.0.0"
- "--listen=8081"
env:
PGWEB_DATABASE_URL:
valueFrom:
secretKeyRef:
name: pgweb-db-secrets
key: database-url
resources:
requests:
cpu: 15m
memory: 100Mi
limits:
memory: 100Mi
probes:
liveness:
enabled: true
custom: true
spec:
tcpSocket:
port: 8081
initialDelaySeconds: 10
periodSeconds: 10
readiness:
enabled: true
custom: true
spec:
tcpSocket:
port: 8081
initialDelaySeconds: 5
periodSeconds: 5
pod:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: pgweb
topologyKey: kubernetes.io/hostname
service:
main:
controller: main
ports:
http:
port: 80
targetPort: 8081
ingress:
main:
enabled: false
주요 설정 설명
시작 인수
--bind=0.0.0.0 # 모든 네트워크 인터페이스에서 수신 대기
--listen=8081 # 리슨 포트
헬스 프로브
TCP 소켓 방식으로 프로세스가 포트 8081에서 수신 중인지 확인합니다.
| 프로브 | 방식 | 초기 대기 | 주기 |
|---|---|---|---|
| Liveness | tcpSocket:8081 | 10초 | 10초 |
| Readiness | tcpSocket:8081 | 5초 | 5초 |
Pod 안티 어피니티
preferredDuringSchedulingIgnoredDuringExecution으로 PgWeb Pod를 서로 다른 노드에 분산 배치합니다. required가 아닌 preferred이므로 노드 수가 부족해도 스케줄링이 차단되지 않습니다.
Reloader 통합
annotations:
reloader.stakater.com/auto: "true"
pgweb-db-secrets Secret이 갱신되면 Reloader가 자동으로 Deployment를 재시작하여 새 연결 정보를 반영합니다.
시크릿 관리
데이터베이스 연결 URL은 Vault Operator Secret(VSO)을 통해 자동으로 프로비저닝됩니다.
VaultStaticSecret (common-values.yaml)
common:
name: pgweb
vaultStaticSecrets:
- name: pgweb-db-vss
path: infrastructure/postgresql
destination:
name: pgweb-db-secrets
transformation:
templates:
database-url: >-
postgresql://{{ .Secrets.POSTGRES_USER }}:{{ .Secrets.POSTGRES_PASSWORD }}@lumie-db-rw.lumie-db.svc:5432/lumie
- Vault 경로
secret/infrastructure/postgresql에서POSTGRES_USER,POSTGRES_PASSWORD를 읽어 PostgreSQL 연결 URL을 조합합니다. - 생성된 Secret 이름:
pgweb-db-secrets(키:database-url) - 연결 대상:
lumie-db-rw.lumie-db.svc:5432/lumie(Primary Read/Write 엔드포인트)
ArgoCD 배포
Application 구성
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: pgweb
namespace: argocd
spec:
project: default
sources:
- repoURL: https://bjw-s-labs.github.io/helm-charts
chart: app-template
targetRevision: 3.6.1
helm:
valueFiles:
- $values/storage/pgweb/helm-values.yaml
- repoURL: https://github.com/Lumie-Edu/lumie-infra.git
targetRevision: main
ref: values
path: charts/common
helm:
valueFiles:
- $values/storage/pgweb/common-values.yaml
destination:
server: https://kubernetes.default.svc
namespace: lumie-db
syncPolicy:
automated:
prune: true
selfHeal: true
두 개의 소스를 사용합니다.
| 소스 | 역할 |
|---|---|
bjw-s/app-template | PgWeb Deployment, Service 생성 |
lumie-infra/charts/common | VaultStaticSecret 등 공통 리소스 생성 |
리소스 구성도
storage/pgweb/
├── argocd.yaml # ArgoCD Application 정의
├── helm-values.yaml # app-template 차트 값 (컨테이너, 서비스, 프로브)
└── common-values.yaml # 공통 차트 값 (VaultStaticSecret)
접근 방법
PgWeb은 공개 인그레스가 없습니다. Teleport Web App 터널을 통해서만 접근할 수 있습니다.
# Teleport CLI를 통한 포트 포워드 (개발/디버깅 용도)
kubectl port-forward -n lumie-db svc/pgweb 8081:80
# 이후 브라우저에서 접속
# http://localhost:8081
운영 가이드
Pod 상태 확인
# Pod 상태 조회
kubectl get pods -n lumie-db -l app.kubernetes.io/name=pgweb
# 상세 정보 확인
kubectl describe pod -n lumie-db -l app.kubernetes.io/name=pgweb
시크릿 확인
# pgweb-db-secrets 존재 여부 확인
kubectl get secret pgweb-db-secrets -n lumie-db
# database-url 값 확인 (base64 디코딩)
kubectl get secret pgweb-db-secrets -n lumie-db \
-o jsonpath='{.data.database-url}' | base64 -d
로그 확인
# 컨테이너 로그 조회
kubectl logs -n lumie-db -l app.kubernetes.io/name=pgweb
# 실시간 로그 스트리밍
kubectl logs -n lumie-db -l app.kubernetes.io/name=pgweb -f
재시작
# Deployment 재시작 (시크릿 갱신 후 수동 적용 시)
kubectl rollout restart deployment/pgweb -n lumie-db
# 롤아웃 상태 확인
kubectl rollout status deployment/pgweb -n lumie-db
문제 해결
Pod가 CrashLoopBackOff 상태
# 로그에서 연결 오류 확인
kubectl logs -n lumie-db -l app.kubernetes.io/name=pgweb --previous
# database-url Secret이 올바르게 생성됐는지 확인
kubectl get secret pgweb-db-secrets -n lumie-db
kubectl describe vaultstaticsecret pgweb-db-vss -n lumie-db
데이터베이스 연결 실패
lumie-db-rw.lumie-db.svc:5432서비스가 정상인지 확인합니다.pgweb-db-secrets의database-url값이 올바른 사용자명/비밀번호를 포함하는지 확인합니다.lumie-db네임스페이스의 NetworkPolicy가lumie-db네임스페이스에서의 접근을 허용하는지 확인합니다.
# lumie-db 클러스터 서비스 상태 확인
kubectl get svc -n lumie-db | grep lumie-db-rw
# 네트워크 정책 확인
kubectl get networkpolicy -n lumie-db
kubectl get networkpolicy -n infra-db