이번 글에서는 Kubernetes(minikube)에 PostgreSQL을 설치하고 간단하게 실행하는 방법에 대해 살펴보도록 하겠습니다. PostgreSQL과 같은 DB의 경우 물리적인 저장소가 필요하기 때문에, PV(Persistance Volume)과 PVC(Persistance Volume Claim)을 생성해줘야 합니다.
DB 관련된 폴더를 생성하고 pv와 pvc 관련된 yaml 파일을 생성합니다.
$ sudo mkdir -p ./postgres
$ vi postgres/pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "~/ml-pipeline/postgres"
$ vi postgres/pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl apply -f postgres/pv.yml
$ kubectl apply -f postgres/pvc.yml
다음은 저번 글에서 추가한 helm repository 중 하나인 bitnami에서 postgres를 설치해줍니다. 앞서 생성한 pvc를 비롯하여 username과 password도 옵션을 지정할 수 있습니다. 정상적으로 설치되었다면 pods 목록에 뜨게 됩니다.
$ helm install postgres bitnami/postgresql \
--set primary.persistence.existingClaim=postgres-pvc \
--set volumePermissions.enabled=true \
--set global.postgresql.auth.postgresPassword=admin \
--set global.postgresql.auth.username=test \
--set global.postgresql.auth.password=test \
--set global.postgresql.auth.database=testdb
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
postgres-postgresql-0 0/1 Running 0 13s
저는 namespace를 따로 지정하지 않았기 때문에 default로 설정되었지만, 만약 PostgreSQL을 설치할 때 namespace를 따로 지정하였다면 pvc.yml을 작성할 때에도 namespace를 동일하게 지정해줘야 합니다. 한성님의 블로그에 따르면, pvc는 namespace object이기 때문에 namespace에 디펜던시가 걸리지만, pv는 cluster role과 비슷하게 cluster에서 공용으로 사용할 수 있는 개체라고 합니다.
PostgreSQL이 설치된 pod의 log는 다음과 같이 pod의 name을 통해 확인이 가능합니다.
$ kubectl logs postgres-postgresql-0
Defaulted container "postgresql" out of: postgresql, init-chmod-data (init)
postgresql 01:20:59.29 INFO ==>
postgresql 01:20:59.29 INFO ==> Welcome to the Bitnami postgresql container
postgresql 01:20:59.30 INFO ==> Subscribe to project updates by watching https://github.com/bitnami/containers
postgresql 01:20:59.30 INFO ==> Submit issues and feature requests at https://github.com/bitnami/containers/issues
postgresql 01:20:59.30 INFO ==>
postgresql 01:20:59.32 INFO ==> ** Starting PostgreSQL setup **
postgresql 01:20:59.33 INFO ==> Validating settings in POSTGRESQL_* env vars..
postgresql 01:20:59.33 INFO ==> Loading custom pre-init scripts...
postgresql 01:20:59.34 INFO ==> Initializing PostgreSQL database...
postgresql 01:20:59.36 INFO ==> pg_hba.conf file not detected. Generating it...
postgresql 01:20:59.36 INFO ==> Generating local authentication configuration
postgresql 01:21:02.02 INFO ==> Starting PostgreSQL in background...
postgresql 01:21:02.21 INFO ==> Changing password of postgres
postgresql 01:21:02.23 INFO ==> Creating user test
postgresql 01:21:02.25 INFO ==> Granting access to "test" to the database "testdb"
postgresql 01:21:02.27 INFO ==> Setting ownership for the 'public' schema database "testdb" to "test"
postgresql 01:21:02.30 INFO ==> Configuring replication parameters
postgresql 01:21:02.33 INFO ==> Configuring synchronous_replication
postgresql 01:21:02.33 INFO ==> Configuring fsync
postgresql 01:21:02.36 INFO ==> Stopping PostgreSQL...
waiting for server to shut down.... done
server stopped
postgresql 01:21:03.07 INFO ==> Loading custom scripts...
postgresql 01:21:03.08 INFO ==> Enabling remote connections
postgresql 01:21:03.08 INFO ==> ** PostgreSQL setup finished! **
postgresql 01:21:03.10 INFO ==> ** Starting PostgreSQL **
2023-11-15 01:21:03.121 GMT [1] LOG: pgaudit extension initialized
2023-11-15 01:21:03.131 GMT [1] LOG: starting PostgreSQL 16.1 on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2023-11-15 01:21:03.132 GMT [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2023-11-15 01:21:03.132 GMT [1] LOG: listening on IPv6 address "::", port 5432
2023-11-15 01:21:03.141 GMT [1] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2023-11-15 01:21:03.151 GMT [150] LOG: database system was shut down at 2023-11-15 01:21:03 GMT
2023-11-15 01:21:03.163 GMT [1] LOG: database system is ready to accept connections
설치가 정상적으로 완료되었기 때문에, 해당 pod에 접속하여 psql을 실행해보도록 하겠습니다. line 1의 코드를 실행하면 pod에 접속하여 코드를 실행할 수 있게 됩니다. 접속한 이후, line 10의 psql 코드로 'select 1'을 실행하게 되면, 결과가 정상적으로 출력되는 것을 확인할 수 있습니다. line 11의 password는 위에서 helm으로 PostgreSQL을 설치할 때 설정한 password를 입력하면 됩니다.
$ kubectl exec -it postgres-postgresql-0 -- /opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash
Defaulted container "postgresql" out of: postgresql, init-chmod-data (init)
postgresql 01:36:02.90 INFO ==>
postgresql 01:36:02.90 INFO ==> Welcome to the Bitnami postgresql container
postgresql 01:36:02.90 INFO ==> Subscribe to project updates by watching https://github.com/bitnami/containers
postgresql 01:36:02.90 INFO ==> Submit issues and feature requests at https://github.com/bitnami/containers/issues
postgresql 01:36:02.90 INFO ==>
postgres@postgres-postgresql-0:/$ psql -h 127.0.0.1 -p 5432 -U test -d testdb -c "select 1"
Password for user test:
?column?
----------
1
(1 row)
마지막으로 minikube에서 PostgreSQL을 설치하면서 겪은 문제들을 공유하고자 합니다.
1. 우선 PostgreSQL은 stable이 아닌 bitnami repository로 설치해야합니다.대부분의 helm 예제에서 stable repository만 추가하였기 때문에, stable로 PostgreSQL을 설치를 진행하려고 했습니다. 하지만 다음과 같은 긴 메시지가 뜨며 bitnami로 설치를 진행하라고 알려주었습니다. line 16~25를 보면, 해당 내용을 확인할 수 있습니다.
$ helm install postgres stable/postgresql \
--set primary.persistence.existingClaim=postgres-pvc \
--set volumePermissions.enabled=true \
--set global.postgresql.auth.postgresPassword=admin \
--set global.postgresql.auth.username=test \
--set global.postgresql.auth.password=test \
--set global.postgresql.auth.database=testdb
WARNING: This chart is deprecated
NAME: postgres
LAST DEPLOYED: Tue Nov 14 17:45:51 2023
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
This Helm chart is deprecated
Given the `stable` deprecation timeline (https://github.com/helm/charts#deprecation-timeline), the Bitnami maintained Helm chart is now located at bitnami/charts (https://github.com/bitnami/charts/).
The Bitnami repository is already included in the Hubs and we will continue providing the same cadence of updates, support, etc that we've been keeping here these years. Installation instructions are very similar, just adding the _bitnami_ repo and using it during the installation (`bitnami/<chart>` instead of `stable/<chart>`)
```bash
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install my-release bitnami/<chart> # Helm 3
$ helm install --name my-release bitnami/<chart> # Helm 2
```
To update an exisiting _stable_ deployment with a chart hosted in the bitnami repository you can execute
```bash
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm upgrade my-release bitnami/<chart>
```
...
2. 두 번째는 설치한 PostgreSQL과 pv, pvc도 같이 삭제하려고 하였는데, pv를 삭제하는 과정에서 무한로딩이 발생하는 문제를 겪었습니다. 무한로딩 코드의 실행을 취소하고 pv의 목록을 확인하면, 완전히 삭제되지 않고 상태가 terminating인 것을 볼 수 있습니다. (PostgreSQL의 pod를 삭제하기 위해서는 kubectl delete <pod-name> 명령어를 사용하는 것이 아닌 helm uninstall 명령어를 사용해야 합니다.)
$ helm uninstall postgres
release "postgres" uninstalled
$ kubectl delete pvc --all
persistentvolumeclaim "data-my-release-postgresql-0" deleted
persistentvolumeclaim "postgres-pvc" deleted
$ kubectl delete pv --all
persistentvolume "postgres-pv" deleted
persistentvolume "pvc-189c4ca7-786d-416a-b4ed-f64dd8f1554d" deleted
persistentvolume "pvc-bd8dc60e-a2b1-4cc4-b743-b60c108614ed" deleted
(loading...)
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-189c4ca7-786d-416a-b4ed-f64dd8f1554d 8Gi RWO Delete Terminating db/data-postgres-postgresql-0 standard 15h
이러한 문제는 다음과 같은 코드를 통해 해결이 가능합니다. pv_name에 저는 pvc-189c4ca7-786d-416a-b4ed-f64dd8f1554d를 입력하였고, 다시 pv의 목록을 확인하면 완전히 삭제된 것을 확인할 수 있습니다.
$ kubectl patch pv <pv_name> -p '{"metadata": {"finalizers": null}}'
$ kubectl get pv
No resources found
Kubernetes 기초를 공부하면서 진행한 내용이기에 틀린 부분이 있거나 더 효율적인 방법이 있다면, 언제든지 댓글로 알려주시길 바랍니다.
<참고>
https://medium.com/@hijessicahsu/deploy-postgres-on-minikube-5cd8f9ffc9c
Deploy Postgres on Minikube
A year ago, I attempted to install Minikube on my M1 Pro but was unsuccessful. Today, I gave it another try and it went well. Here is the…
medium.com
[쿠버네티스] pv, pvc 완전히 삭제하는 방법 (terminating 해결)
kubectl patch pv -p '{"metadata": {"finalizers": null}}' kubectl delete pv --grace-period=0 --force
jmholly.tistory.com
'MLOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Object 기초 - ConfigMap, Secret (0) | 2023.12.13 |
---|---|
[Kubernetes] Volume 기초 - emptyDir, hostPath, PVC/PV (2) | 2023.12.10 |
[Kubernetes] Service 기초 (1) | 2023.11.25 |
[Kubernetes] Helm 설치 (1) | 2023.11.15 |
[Kubernetes] Pod 기초 (0) | 2023.11.13 |
댓글