PersistentVolume, PersistentVolumeClaim에 대해 소개는 나중에 하겠다.
우선 생성 방법만 알아보자!
https://d-life93.tistory.com/458와 https://www.sumologickorea.com/blog/kubernetes-deploy-postgres/를 참고했습니다.
Secret 생성
kubernetest의 secret을 이용해 postgres password를 관리할 것이기 때문에 먼저 password가 될 평문을 encoding 해준다.
- 아래의 password가 비밀번호이며 기본적으로 쿠버네티스로 시크릿 키를 사용할 경우 자동 디코딩 된다.
echo -n password | base64
결과는

이렇게 나온다.
vi secret.yml 하고 data 아래 password에 encoding된 값을 적어준다. 여기서 password는 나중에 사용할 key값이 된다.
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret-config
type: Opaque
data:
password: cGFzc3dvcmQ=
kubectl apply -f secret.yml 으로 secret을 생성시켜준다.

추가적으로 secret 생성을 CLI로 하는 방법이 있다.
https://118k.tistory.com/1095 참고
pv, pvc 생성
마찬가지로 vi db-pv.yml을 해주고 (pv와 pvc를 동시에 만들 것이라 중간에 ---으로 구역을 나눠줘야한다.)
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
--- # <- --- 이거 꼭 필요
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
kubectl apply -f db-pv.yml으로 pv와 pvc를 만들어준다.

Postgresql Deployment와 Service 생성
vi postgresql.yml을 하고 (deployment와 service를 동시에 만들 것이라 중간에 ---으로 구역을 나눠줘야한다.)
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
volumes:
- name: postgres-pv-storage
persistentVolumeClaim:
claimName: postgres-pv-claim
containers:
- name: postgres
image: postgres:15
imagePullPolicy: IfNotPresent # Always면 image가 있어도 계속 pull 받음
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: company
- name: POSTGRES_USER
value: company
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef: # password 같이 중요한 값이 아니라면 configMapKeyRef를 사용할 수 있다.
name: postgres-secret-config # secret에서 가져올 것이니, secret name을 적어준다.
key: password # secret 속 가져올 data의 key 값을 적어준다.
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-pv-storage
--- # <- --- 이거 필수
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
spec:
selector:
app: postgres
type: ClusterIP # NodePort도 가능
ports:
- port: 5432
kubectl apply -f postgresql.yml 으로 postgresql의 deployment와 service를 만들어준다.
Secret과 같이 kubernetes에서 제공해주는 configMap이 존재한다. 비밀번호같이 중요한 정보는 Secret에 encoding 형태로 저장해 보안을 지키고 port나 host 등 노출돼도 덜 위험한 정보는 configMap에 저장한다.
아래와 같은 형식으로 정의하며 적용법은 Secret과 동일하다.
사용은 secretKeyRef 대신 configMapKeyRef을 사용하면 된다.
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
data:
port: "5432"
database: "company"
user: "company"
또한 추가로 필요한 postgresql의 env에 들어갈 설정(ex. POSTGRES_DB, POSTGRES_USER)은 아래에 들어가 골라서 사용하면 된다.
https://hub.docker.com/_/postgres/
application의 Deployment와 Service 생성
먼저 Dockerfile은 아래와 같다.
FROM openjdk:17
ARG JAR_FILE=build/libs/*-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "-Dspring.datasource.url=${DATASOURCE_URL}", "-Dspring.datasource.username=${POSTGRES_USERNAME}", "-Dspring.datasource.password=${POSTGRES_PASSWORD}", "/app.jar"]
그래서 deployment와 service는
vi company.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: company
labels:
app: company
spec:
replicas: 2
selector:
matchLabels:
app: company
template:
metadata:
labels:
app: company
spec:
containers:
- name: company
image: govl6113/company:0.0.3
ports:
- containerPort: 8080
env:
- name: DATASOURCE_URL
value: "jdbc:postgresql://postgres:5432/company" # port 앞에 postgres의 service이름이나 clusterIP를 적어주면 된다.
- name: POSTGRES_USERNAME
value: company
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret-config
key: password
--- # 이거 필수
apiVersion: v1
kind: Service
metadata:
name: company
spec:
selector:
app: company
ports:
- name: tcp
port: 80
protocol: TCP
targetPort: 8080
kubectl apply -f company.yml으로 application의 deployment와 service를 만들어준다.
