반갑습니다. 저는|기업가이자, 엔지니어입니다.
k8s 이용해서 웹 서버 구축하기 - 5-1부. (번외편) PostgreSQL 배포 및 연동

k8s 이용해서 웹 서버 구축하기 - 5-1부. (번외편) PostgreSQL 배포 및 연동

Tags
k8s
k3s
PostgreSQL
Published
발행일 - 2022년 9월 6일
Author
Eugene Jeon (전유진)
AuthorLink

 
 

개요

PostgreSQL 은 오픈소스이며, k8s 에서는 HA 를 지원한다. 그래서 유럽에서는 많은 기업들이 사용하고 있다. 그래서 이번에는 PostgreSQL 을 배포하고 연동해 볼 것이다.
 

Namespace 생성

(yaml)
kubectl create ns postgres
 

ConfigMap 생성

환경 변수는 ConfigMap 으로 만들어 관리하면 편리하다.
(yaml)
apiVersion: v1 kind: ConfigMap metadata: name: postgres-configmap namespace: postgres data: TZ: Asia/Seoul LANG: ko_KR.UTF-8 LANGUAGE: ko_KR.UTF-8 LC_ALL: ko_KR.UTF-8
 
LC_ALL 을 한글로 설정할 경우, 오류가 날 수 있다.
이때는 아래 링크를 참고하여 한글 베이스 OS 의 PostgreSQL 이미지를 만들어 사용해야 한다.
 

Secret 생성

DB 의 접속 정보 (이름, 유저네임, 아이디, 비밀번호 등) 와 같은 보안이슈가 있는 값은 secret 으로 생성하고 관리하는 것이 좋다. 이 값은 나중에 deployment 를 정의할 때 사용할 것이다.
 
먼저, 아래 내용을 env 파일 등으로 작성해두자.
(plain text)
POSTGRES_DB=database POSTGRES_USER=user POSTGRES_PASSWORD=user_password
 
작성한 env 파일을 이용하여 secret 을 생성할 것이다.
(bash)
kubectl create secret generic postgres-secret --from-env-file env -n postgres
 
💡
사용한 파일은 지워도 무방하다. 파일을 작성하기 싫다면, secret 을 생성할 때 --from-literal 키워드를 이용하거나 값을 직접 입력할 수 있다.
 

StorageClass 생성

스토리지를 따로 관리하기 위해 StorageClass 를 생성한다.
(yaml)
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: postgres-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true
 
작성한 파일을 이용하여, StorageClass 를 생성한다.
(bash)
kubectl apply -f postgres-storageclass.yaml
 

PV (PersistentVolume) 생성

PV 는 클러스터 리소스이며, 스토리지 자원이다. PV 에 저장된 데이터는 클러스터의 종료, 삭제와 무관하게 별도로 관리되는 자원이므로 항상 데이터를 유지하고자 할 때 사용할 수 있다.
(yaml)
apiVersion: v1 kind: PersistentVolume metadata: name: postgres-pv namespace: postgres labels: type: local spec: storageClassName: postgres-storage capacity: storage: 80Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"
 
정의한 파일을 실행하여, PV 를 생성한다.
(bash)
kubectl apply -f postgres-pv.yaml
 

PVC (PersistentVolumeClaim) 생성

PVC 는 사용자의 스토리지에 대한 요청을 처리하는 자원이다. PVC 는 PV 리소스를 사용하며, Deployment 와 연결된다.
(yaml)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: postgres spec: storageClassName: postgres-storage accessModes: - ReadWriteOnce resources: requests: storage: 80Gi
 
정의한 파일을 실행하여, PVC 를 생성한다.
(bash)
kubectl apply -f postgres-pvc.yaml
 

Deployment 생성

PostgreSQL 공식 이미지를 이용하고, 이전에 생성했던 secret, pvc 를 함께 정의한다.
별도로 한글화된 OS 의 PostgreSQL 이미지를 사용할 수 도 있다.
(yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: postgres spec: selector: matchLabels: app: postgres strategy: type: Recreate template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:latest # 주의! postgres 이다. postgresql 아니다. envFrom: - secretRef: name: postgres-secret ports: - name: postgres-port containerPort: 5432 protocol: TCP volumeMounts: - name: postgres-volume mountPath: /var/lib/pgsql/data volumes: - name: postgres-volume persistentVolumeClaim: claimName: postgres-pvc
 
정의한 파일을 실행하여, deployment 를 생성한다.
(bash)
kubectl apply -f postgres-deployment.yaml
 
 

💡
PostgreSQL 에 접속해서 간단히 해야할 일이 있다. 처음 ConfigMap 을 작성해서 쉘 스크립트로 할 수 있지만, 여기서는 직접 적용하는 방법을 소개한다.
  1. pod 접속
    1. (yaml)
      kubectl exec -it <POD_NAME> -n postgres /bin/bash
  1. postgresql 접속 후 database 에 ko_KR.UTF-8 적용
    1. (yaml)
      $ psql -U user -d database ... database=# update pg_database set datcollate='C', datctype='ko_KR.UTF-8' where datname='database';
      datcollate 는 LC_COLLATE 가 들어가는데, C 로 하는 이유는 한글 정렬을 위해서이다.
 
  • 유저 생성 및 테이블 생성을 다시 하고 싶다면, 다음을 참고할 수 있다.
    • (shell)
      # 유저 생성 CREATE USER 유저 PASSWORD '비밀번호'; # 테이블 생성 CREATE DATABASE 테이블 OWNER 유저;

 

Service 생성

PostgreSQL pod 은 생성되었으나, pod 외부에서 접근하기위해 Service 도 함께 정의한다.
(yaml)
apiVersion: v1 kind: Service metadata: name: postgres-service namespace: postgres spec: ports: - name: postgres protocol: TCP port: 5432 targetPort: 5432 selector: app: postgres
 
정의한 파일을 실행하여, service 를 생성한다.
(bash)
kubectl apply -f postgres-service.yaml
 
 

💡
여기까지가 데이터 베이스를 생성하고, 클러스터 내부에서 DB 에 접근하는 방법이다. 이하 내용은 외부에서 DB 에 직접 접근하는 방식이다. 보안상 취약점이 많기 때문에, 실제 배포할 때는 추천하지 않는 방법이다.

 
 

Ingress 생성

주의! 위 PostgreSQL 는 namespace 가 postgres 이다. 이를 default 와 같이 다른 namespace 의 ingress 에 연동하려 한다면 ingress 와 같은 namespace, 여기서는 default, 이 곳에 다음과 같은 서비스를 하나 더 생성해주어야 한다.

default namespace 에 external service 생성

(yaml)
apiVersion: v1 kind: Service metadata: name: postgres-service namespace: default spec: type: ExternalName # 자세한 사항은 아래 참고 링크를 확인하자. externalName: postgres-service.postgres.svc.cluster.local # k8s style reference ports: - port: 5432 targetPort: 5432
 

ExternalName 서비스와 연동하여 Ingress 생성

(yaml)
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: postgresql-ingress namespace: default annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "false" nginx.ingress.kubernetes.io/rewrite-target: / # nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: nginx # created default class rules: - host: {IP}.sslip.io http: paths: - path: "/" pathType: Prefix backend: service: name: postgres-service port: number: 5432
 
작성한 파일을 실행하여, ingress 를 생성한다.
(bash)
kubectl apply -f postgres-ingress.yaml
 

Nginx Ingress 의 TCP/UDP Port Forward 적용

만약, 위 ingress 파일을 적용 할 때 host 를 적지 않으면 k8s node ip 로 할당이 된다. 이때는 port 를 함께 날려줘야 하는데, 추가 tcp/udp 포트를 허용하기 위해서 nginx ingress controller 에서 추가 설정을 해야할게 있다.
 
💡
또한! ingress 에서 host 를 사용하지 않을 것이라면, ingress 를 생성하지 말고 바로 nginx-ingress-controller 에서 tcp/udp 포트 포워딩을 적용해주면 된다.
 
Nginx Ingress 설정하는 방법을 담은 페이지이다. 하단의 TCP/UDP 포트 추가하는 내용을 참고하면된다.
 

Loading Comments...