mirror of
https://github.com/cna-bootcamp/phonebill.git
synced 2025-12-06 16:16:23 +00:00
17 KiB
17 KiB
Bill-Inquiry 서비스 개발환경 데이터베이스 설치 계획서
1. 개요
1.1 설치 목적
- Bill-Inquiry 서비스 전용 PostgreSQL 14 데이터베이스 개발환경 구축
- 요금조회 기능을 위한 독립적인 데이터베이스 환경 제공
- Kubernetes StatefulSet을 통한 안정적인 데이터 지속성 보장
1.2 설치 환경
- 플랫폼: Azure Kubernetes Service (AKS)
- 환경: 개발환경 (Development)
- 네임스페이스: phonebill-dev
- 클러스터: phonebill-dev-aks (2 노드, Standard_B2s)
1.3 참조 문서
- 물리아키텍처 설계서: design/backend/physical/physical-architecture-dev.md
- 데이터 설계 종합: design/backend/database/data-design-summary.md
- Bill-Inquiry 데이터 설계서: design/backend/database/bill-inquiry.md
- 스키마 파일: design/backend/database/bill-inquiry-schema.psql
2. 데이터베이스 구성 정보
2.1 기본 정보
| 항목 | 값 | 설명 |
|---|---|---|
| 데이터베이스명 | bill_inquiry_db | Bill-Inquiry 서비스 전용 DB |
| DBMS | PostgreSQL 14 | 안정화된 PostgreSQL 14 버전 |
| 컨테이너 이미지 | bitnami/postgresql:14 | Bitnami 공식 이미지 |
| 문자셋 | UTF8 | 한글 지원을 위한 UTF8 |
| 타임존 | Asia/Seoul | 한국 표준시 |
| 초기 사용자 | postgres | 관리자 계정 |
| 초기 비밀번호 | Hi5Jessica! | 개발환경용 고정 비밀번호 |
2.2 스키마 구성
| 스키마 | 용도 | 테이블 수 |
|---|---|---|
| public | 비즈니스 테이블 | 5개 |
| cache | 캐시 데이터 (Redis 보조용) | 포함됨 |
| audit | 감사 및 이력 | 포함됨 |
2.3 주요 테이블
| 테이블명 | 용도 | 예상 데이터량 |
|---|---|---|
| customer_info | 고객정보 임시 캐시 | 소규모 |
| bill_inquiry_history | 요금조회 요청 이력 | 중간규모 |
| kos_inquiry_history | KOS 연동 이력 | 중간규모 |
| bill_info_cache | 요금정보 캐시 | 소규모 |
| system_config | 시스템 설정 | 소규모 |
3. 리소스 할당 계획
3.1 컴퓨팅 리소스
| 리소스 유형 | 요청량 | 제한량 | 설명 |
|---|---|---|---|
| CPU | 500m | 1000m | 개발환경 최적화 |
| Memory | 1Gi | 2Gi | 기본 워크로드 대응 |
| Storage | 20Gi | - | 개발 데이터 충분 용량 |
3.2 스토리지 구성
| 설정 항목 | 값 | 설명 |
|---|---|---|
| 스토리지 클래스 | managed-standard | Azure Disk Standard HDD |
| 볼륨 타입 | PersistentVolumeClaim | 데이터 지속성 보장 |
| 마운트 경로 | /bitnami/postgresql | 표준 데이터 디렉토리 |
| 백업 방식 | Azure Disk Snapshot | 일일 자동 백업 |
3.3 네트워크 구성
| 설정 항목 | 값 | 설명 |
|---|---|---|
| Service 타입 | ClusterIP | 클러스터 내부 접근 |
| 내부 포트 | 5432 | PostgreSQL 표준 포트 |
| Service 이름 | postgresql-bill-inquiry | 서비스 디스커버리용 |
| DNS 주소 | postgresql-bill-inquiry.phonebill-dev.svc.cluster.local | 내부 접근 주소 |
4. PostgreSQL 설정
4.1 성능 최적화 설정
| 설정 항목 | 값 | 설명 |
|---|---|---|
| max_connections | 100 | 개발환경 충분한 연결 수 |
| shared_buffers | 256MB | 메모리의 25% 할당 |
| effective_cache_size | 1GB | 총 메모리의 75% |
| work_mem | 4MB | 작업 메모리 |
| maintenance_work_mem | 64MB | 유지보수 작업 메모리 |
4.2 로그 설정
| 설정 항목 | 값 | 설명 |
|---|---|---|
| log_destination | stderr | 표준 에러로 로그 출력 |
| log_min_duration_statement | 1000ms | 1초 이상 쿼리 로그 |
| log_statement | none | 개발환경용 최소 로깅 |
| log_connections | on | 연결 로그 활성화 |
4.3 보안 설정
| 설정 항목 | 값 | 설명 |
|---|---|---|
| 비밀번호 암호화 | BCrypt | 안전한 비밀번호 저장 |
| SSL 모드 | require | TLS 암호화 통신 |
| 접근 제어 | md5 | 비밀번호 기반 인증 |
| 외부 접근 | 제한 | 클러스터 내부만 허용 |
5. Kubernetes 매니페스트
5.1 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: postgresql-bill-inquiry-config
namespace: phonebill-dev
data:
POSTGRES_DB: "bill_inquiry_db"
POSTGRES_USER: "postgres"
POSTGRESQL_MAX_CONNECTIONS: "100"
POSTGRESQL_SHARED_BUFFERS: "256MB"
POSTGRESQL_EFFECTIVE_CACHE_SIZE: "1GB"
POSTGRESQL_WORK_MEM: "4MB"
POSTGRESQL_MAINTENANCE_WORK_MEM: "64MB"
POSTGRESQL_LOG_MIN_DURATION_STATEMENT: "1000"
5.2 Secret
apiVersion: v1
kind: Secret
metadata:
name: postgresql-bill-inquiry-secret
namespace: phonebill-dev
type: Opaque
data:
postgres-password: SGk1SmVzc2ljYSE= # Hi5Jessica!
5.3 PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgresql-bill-inquiry-pvc
namespace: phonebill-dev
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-standard
resources:
requests:
storage: 20Gi
5.4 StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-bill-inquiry
namespace: phonebill-dev
labels:
app: postgresql-bill-inquiry
tier: database
spec:
serviceName: postgresql-bill-inquiry
replicas: 1
selector:
matchLabels:
app: postgresql-bill-inquiry
template:
metadata:
labels:
app: postgresql-bill-inquiry
tier: database
spec:
containers:
- name: postgresql
image: bitnami/postgresql:14
imagePullPolicy: IfNotPresent
env:
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRES_DB
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgresql-bill-inquiry-secret
key: postgres-password
- name: POSTGRESQL_MAX_CONNECTIONS
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_MAX_CONNECTIONS
- name: POSTGRESQL_SHARED_BUFFERS
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_SHARED_BUFFERS
- name: POSTGRESQL_EFFECTIVE_CACHE_SIZE
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_EFFECTIVE_CACHE_SIZE
- name: POSTGRESQL_WORK_MEM
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_WORK_MEM
- name: POSTGRESQL_MAINTENANCE_WORK_MEM
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_MAINTENANCE_WORK_MEM
- name: POSTGRESQL_LOG_MIN_DURATION_STATEMENT
valueFrom:
configMapKeyRef:
name: postgresql-bill-inquiry-config
key: POSTGRESQL_LOG_MIN_DURATION_STATEMENT
ports:
- name: postgresql
containerPort: 5432
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
volumeMounts:
- name: postgresql-data
mountPath: /bitnami/postgresql
livenessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U postgres -h 127.0.0.1 -p 5432
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
readinessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U postgres -h 127.0.0.1 -p 5432
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
volumes:
- name: postgresql-data
persistentVolumeClaim:
claimName: postgresql-bill-inquiry-pvc
5.5 Service
apiVersion: v1
kind: Service
metadata:
name: postgresql-bill-inquiry
namespace: phonebill-dev
labels:
app: postgresql-bill-inquiry
tier: database
spec:
type: ClusterIP
ports:
- name: postgresql
port: 5432
targetPort: 5432
protocol: TCP
selector:
app: postgresql-bill-inquiry
6. 스키마 초기화
6.1 초기화 Job
apiVersion: batch/v1
kind: Job
metadata:
name: bill-inquiry-db-init
namespace: phonebill-dev
spec:
template:
spec:
containers:
- name: db-init
image: bitnami/postgresql:14
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgresql-bill-inquiry-secret
key: postgres-password
command: ["/bin/bash"]
args:
- -c
- |
echo "스키마 초기화 시작..."
# 연결 대기
until pg_isready -h postgresql-bill-inquiry -p 5432 -U postgres; do
echo "PostgreSQL 서버 대기 중..."
sleep 2
done
echo "스키마 생성 중..."
psql -h postgresql-bill-inquiry -U postgres -d bill_inquiry_db << 'EOF'
-- 타임존 설정
SET timezone = 'Asia/Seoul';
-- 확장 모듈 활성화
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements";
-- 테이블 생성 (bill-inquiry-schema.psql 내용)
-- 고객정보 테이블 생성
CREATE TABLE IF NOT EXISTS customer_info (
customer_id VARCHAR(50) NOT NULL,
line_number VARCHAR(20) NOT NULL,
customer_name VARCHAR(100),
status VARCHAR(10) NOT NULL DEFAULT 'ACTIVE',
operator_code VARCHAR(10) NOT NULL,
cached_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_customer_info PRIMARY KEY (customer_id),
CONSTRAINT uk_customer_info_line UNIQUE (line_number),
CONSTRAINT ck_customer_info_status CHECK (status IN ('ACTIVE', 'INACTIVE'))
);
-- 기타 테이블들은 전체 스키마 파일에서 가져와 적용
-- 기본 시스템 설정 데이터 삽입
INSERT INTO system_config (config_key, config_value, description, config_type) VALUES
('bill.cache.ttl.hours', '4', '요금정보 캐시 TTL (시간)', 'INTEGER'),
('kos.connection.timeout.ms', '30000', 'KOS 연결 타임아웃 (밀리초)', 'INTEGER'),
('kos.retry.max.attempts', '3', 'KOS 최대 재시도 횟수', 'INTEGER')
ON CONFLICT (config_key) DO NOTHING;
SELECT 'Bill-Inquiry Database 초기화 완료' AS result;
EOF
echo "스키마 초기화 완료"
volumeMounts:
- name: schema-script
mountPath: /scripts
volumes:
- name: schema-script
configMap:
name: bill-inquiry-schema-script
restartPolicy: OnFailure
6.2 스키마 스크립트 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: bill-inquiry-schema-script
namespace: phonebill-dev
data:
init-schema.sql: |
-- bill-inquiry-schema.psql 파일의 전체 내용을 여기에 포함
7. 설치 절차
7.1 사전 준비
-
AKS 클러스터 확인
kubectl config current-context kubectl get nodes -
네임스페이스 생성
kubectl create namespace phonebill-dev kubectl config set-context --current --namespace=phonebill-dev -
스토리지 클래스 확인
kubectl get storageclass
7.2 설치 순서
-
ConfigMap 및 Secret 생성
kubectl apply -f postgresql-bill-inquiry-config.yaml kubectl apply -f postgresql-bill-inquiry-secret.yaml -
PersistentVolumeClaim 생성
kubectl apply -f postgresql-bill-inquiry-pvc.yaml kubectl get pvc -
StatefulSet 배포
kubectl apply -f postgresql-bill-inquiry-statefulset.yaml kubectl get statefulset kubectl get pods -w -
Service 생성
kubectl apply -f postgresql-bill-inquiry-service.yaml kubectl get service -
스키마 초기화
kubectl apply -f bill-inquiry-schema-configmap.yaml kubectl apply -f bill-inquiry-db-init-job.yaml kubectl logs -f job/bill-inquiry-db-init
7.3 설치 검증
-
Pod 상태 확인
kubectl get pods -l app=postgresql-bill-inquiry kubectl describe pod postgresql-bill-inquiry-0 -
데이터베이스 접속 테스트
kubectl exec -it postgresql-bill-inquiry-0 -- psql -U postgres -d bill_inquiry_db -
테이블 생성 확인
\dt SELECT COUNT(*) FROM system_config; SELECT config_key, config_value FROM system_config LIMIT 5; -
서비스 연결 테스트
kubectl run test-client --rm -it --image=postgres:14 --restart=Never -- psql -h postgresql-bill-inquiry.phonebill-dev.svc.cluster.local -U postgres -d bill_inquiry_db
8. 모니터링 및 관리
8.1 모니터링 메트릭
| 메트릭 | 임계값 | 설명 |
|---|---|---|
| CPU 사용률 | < 80% | 정상 동작 범위 |
| Memory 사용률 | < 85% | 메모리 부족 방지 |
| Disk 사용률 | < 80% | 스토리지 여유공간 |
| Connection 수 | < 80 | 최대 연결 수 100의 80% |
| 평균 응답시간 | < 100ms | 쿼리 성능 모니터링 |
8.2 로그 관리
# PostgreSQL 로그 확인
kubectl logs postgresql-bill-inquiry-0
# 실시간 로그 모니터링
kubectl logs -f postgresql-bill-inquiry-0
# 로그 검색
kubectl logs postgresql-bill-inquiry-0 | grep ERROR
8.3 백업 및 복구
-
수동 백업
kubectl exec postgresql-bill-inquiry-0 -- pg_dump -U postgres bill_inquiry_db > bill_inquiry_backup_$(date +%Y%m%d).sql -
Azure Disk Snapshot
# PVC에 바인딩된 Disk 확인 kubectl get pv # Azure CLI로 스냅샷 생성 az snapshot create \ --resource-group phonebill-dev-rg \ --name bill-inquiry-db-snapshot-$(date +%Y%m%d) \ --source {DISK_ID}
9. 트러블슈팅
9.1 일반적인 문제
| 문제 | 원인 | 해결방안 |
|---|---|---|
| Pod Pending | 리소스 부족 | 노드 리소스 확인, requests 조정 |
| Connection Failed | Service 설정 오류 | Service 및 Endpoint 확인 |
| Init 실패 | 스키마 오류 | 스키마 파일 문법 검사 |
| 성능 저하 | 설정 부적절 | PostgreSQL 튜닝 적용 |
9.2 문제 해결 절차
# 1. Pod 상태 확인
kubectl get pods -l app=postgresql-bill-inquiry
kubectl describe pod postgresql-bill-inquiry-0
# 2. 로그 확인
kubectl logs postgresql-bill-inquiry-0 --tail=100
# 3. 서비스 확인
kubectl get service postgresql-bill-inquiry
kubectl get endpoints postgresql-bill-inquiry
# 4. PVC 상태 확인
kubectl get pvc postgresql-bill-inquiry-pvc
kubectl describe pvc postgresql-bill-inquiry-pvc
# 5. ConfigMap/Secret 확인
kubectl get configmap postgresql-bill-inquiry-config -o yaml
kubectl get secret postgresql-bill-inquiry-secret -o yaml
10. 보안 고려사항
10.1 접근 제어
- Network Policy: 클러스터 내부 접근만 허용
- RBAC: 최소 권한 원칙 적용
- Secret 관리: 비밀번호 암호화 저장
10.2 데이터 보호
- 암호화: 전송 구간 TLS 적용
- 백업 암호화: 백업 데이터 암호화
- 접근 로그: 모든 접근 기록 유지
11. 운영 가이드
11.1 정기 작업
- 주간: 백업 상태 확인 및 복구 테스트
- 월간: 성능 메트릭 분석 및 튜닝
- 분기: 보안 패치 및 업그레이드 검토
11.2 비상 대응
-
서비스 중단 시
- Pod 재시작:
kubectl rollout restart statefulset/postgresql-bill-inquiry - 백업으로부터 복구
- 새로운 PVC 생성 후 데이터 이전
- Pod 재시작:
-
성능 문제 시
- 리소스 확장: CPU/Memory limits 증가
- 설정 튜닝: PostgreSQL 파라미터 최적화
- 인덱스 재구성: 슬로우 쿼리 최적화
12. 비용 최적화
12.1 리소스 최적화
- Storage: Standard HDD 사용으로 비용 절약
- CPU/Memory: 개발환경 최적화된 사이징
- 백업: Azure Disk Snapshot 활용으로 저비용
12.2 예상 비용 (월간)
| 항목 | 비용 (USD) | 설명 |
|---|---|---|
| Storage (20GB Standard) | $2 | Azure Disk Standard HDD |
| 컴퓨팅 리소스 | $0 | AKS 노드 내 리소스 활용 |
| 백업 스토리지 | $1 | Snapshot 저장 비용 |
| 총 비용 | $3 | 월간 예상 비용 |
작성일: 2025-09-08
작성자: 백엔더 (이개발)
검토자: 아키텍트 (김기획), 데옵스 (최운영)
승인자: 기획자 (김기획)