Summary
K3s 환경에서 PostgreSQL을 설치하는 과정을 정리했습니다.
애플리케이션 별로 PostgreSQL을 요구하는 경우가 있기 때문에 공동으로 사용할 수 있는 데이터베이스를 생성합니다.
yaml
PersistentVolumeClaim
PostgreSQL의 데이터를 저장하는 공간을 요청합니다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: core-infra
spec:
accessModes:
- ReadWriteOnce # 하나의 노드에서 읽기/쓰기 가능
storageClassName: local-path # local-path 스토리지 클래스 사용
resources:
requests:
storage: 50GiService
파드의 네트워크와 관련한 설정입니다.
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
namespace: core-infra
spec:
type: ClusterIP # 클러스터 내부에서만 접근 가능한 서비스
selector:
app: postgresql
ports:
- protocol: TCP
name: postgres
port: 5432
targetPort: 5432StatefulSet
데이터베이스는 안정적인 파드의 운영이 중요하므로 StatefulSet으로 생성합니다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: core-infra
labels:
app: postgresql
spec:
serviceName: "postgres-svc"
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
dev.quenary.tugtainer.protected: "true" # tugtainer 보호 라벨
spec:
containers:
- name: postgresql
image: postgres:17
args: # PostgreSQL 성능 최적화 및 안정성 향상을 위한 커스텀 설정
- "postgres"
- "-c"
- "shared_buffers=256MB"
- "-c"
- "effective_cache_size=1GB"
- "-c"
- "maintenance_work_mem=128MB"
- "-c"
- "checkpoint_completion_target=0.9"
- "-c"
- "wal_buffers=16MB"
- "-c"
- "default_statistics_target=100"
- "-c"
- "random_page_cost=1.1"
- "-c"
- "effective_io_concurrency=200"
- "-c"
- "work_mem=4MB"
- "-c"
- "min_wal_size=1GB"
- "-c"
- "max_wal_size=4GB"
- "-c"
- "max_worker_processes=4"
- "-c"
- "max_parallel_workers_per_gather=2"
- "-c"
- "max_parallel_workers=4"
- "-c"
- "max_parallel_maintenance_workers=2"
env: # 환경 변수 설정
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_PASSWORD
- name: TZ
value: "Asia/Seoul"
- name: LANG
value: "en_US.utf8"
- name: PGDATA
value: "/var/lib/postgresql/data/pgdata"
ports:
- containerPort: 5432
readinessProbe:
exec:
command: ["pg_isready", "-U", "postgres", "-d", "postgres"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 5
livenessProbe:
exec:
command: ["pg_isready", "-U", "postgres", "-d", "postgres"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 5
resources:
limits:
cpu: "2.0"
memory: "2Gi"
requests:
cpu: "1.0"
memory: "1Gi"
securityContext:
allowPrivilegeEscalation: false
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: dshm
mountPath: /dev/shm
volumes:
- name: postgres-data # PVC 볼륨 마운트
persistentVolumeClaim:
claimName: postgres-pvc
- name: dshm # PostgreSQL의 shared memory를 위한 emptyDir 볼륨
emptyDir:
medium: Memory
sizeLimit: 256Mi
Tip
각 yaml은 하나의 파일
postgres.yaml로 관리합니다.
Installation
Secret 생성
Secret은 .env 파일과 같은 역할입니다. 비밀번호, API 키와 같이 보이면 안되는 값을 미리 지정해서 생성합니다.
kubectl create secret generic postgres-secret --from-literal=POSTGRES_PASSWORD=<postgres-password> -n <name-space>Tip
PostgreSQL은 다른 서비스에서 DB를 사용해야할 수 있으므로
core-infraNamespace로 지정합니다.
postgres 생성
미리 만들어둔 postgres.yaml을 배포하여 DB를 구동합니다.
# postgres.yaml 배포
kubectl apply -f postgres.yaml
# Pod 실행 상태 확인
kubectl get pods -n core-infra -wSuccess
PostgreSQL의 설치가 완료되었습니다.