본문 바로가기

Kubernetes

k8s + Postgresql PersistentVolume 생성

PersistentVolume, PersistentVolumeClaim에 대해 소개는 나중에 하겠다. 

우선 생성 방법만 알아보자!

https://d-life93.tistory.com/458https://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 생성 확인

추가적으로 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를 만들어준다. 

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를 만들어준다. 

모든 Pod, service 생성 확인