본문 바로가기

윈도우 개발환경

윈도우 쿠버네티스 개발환경 ; 1. PostgreSQL 배포하기

윈도우 쿠버네티스 개발환경

1. PostgreSQL 배포하기

2. MySQL 배포하기

 

DevOps 환경이 구축이 되었으니, 이제 만들어진 쿠버테티스 클러스터에 프로젝트에 필요한 프로그램을 설치하는 방법을 정리해 보기로 했다. 대부분은 Helm을 사용하면 쉽게 설치할 수도 있지만, 회사 개발자가 Helm으로 PostgreSQL을 설치하다가 문제가 발생하자 해결하지 못하는 것을 보고, 기본이 되는 쿠버네티스 설치부터 정리해 보기로 했다.

 

Docker로 PostgreSQL를 설치하는 방법은 앞에서 정리한 적이 있다.

 

윈도우에 만드는 리눅스 개발 환경; 8. Docker로 PostgreSQL 시작하기

윈도우에 만드는 리눅스 개발 환경 목차 1. 우분투 리눅스 설치 (윈도우 10) 2. 윈도우에 Docker 설치 3. 속도 개선 후 node.js 설치 4. VScode 설치 후 리눅스 연결 5. Docker로 MySQL시작하기 6. Docker로 MongoDB

front-it.tistory.com

쿠버네티스에서 PostgreSQL을 설치하는 방법은 Docker보다 복잡할 뿐 아니라 쿠버네티스 클러스터라는 복잡한 환경이 필요하다. 그래서, 단순히 개발에 필요한 PostgreSQL가 서버가 필요하다면 위 링크를 참고해서 Docker로 설치하는 것이 좋을 것이다.

 

하지만, 회사 서비스가 쿠버네티스에 구성되어 있고, 개발팀이 Ops까지 담당하는 DevOps구조이면, 내가 사용하는 윈도우 노트북의 DevOps 테스트 환경에도 PostgreSQL를 설치해야 할 경우가 생긴다.

 

앞에서 만든 윈도우 기반의 쿠버네티스 환경에 PostgreSQL을 설치해 보면 Docker처럼 간단하지 않다는 것을 알게 된다. Minikube를 윈도우에 설치할 때에도, WSL의 한계로 인해 NodePort로 설정된 Service가 외부에 노출되지 않는 불편함 점을 앞에서 봤다. 비슷한 이유로 인해 윈도우에 설치된 쿠버네티스에 PostgreSQL을 구성할 때에도 어려움이 발생한다.

1. Volume과 PV (Persistent Volume)

Docker를 사용하여 PostgreSQL을 실행할 때 db데이터의 저장위치를 -v를 사용하여 윈도우의 폴더로 지정하면, 컨테이너를 종료하고 지우더라도 같은 Docker image로 다시 실행하면 DB의 내용이 다시 복구된다.

 

쿠버네티스는 Volume이라는 Docker보다 좀 더 복잡한 방법으로 저장공간을 제공한다. Volume에는

  • Ephemeral volume: Pod를 만들 때 생겼다가 Pod가 없어지면 같이 지워지는 Volume
  • Persistent Volume: 관리자가 만들고 지울 때까지는 존재하는 Volume

이 있는데, ephemeral이 비록 Pod가 없어지면 같이 지원 진다 하더라도 컨테이너 내부의 저장공간은 아니고 Persistent Volume과 동일하게 지정된 외부 저장공간이다.

 

컨테이너를 만들기 위해 가상서버나 컴퓨터를 Node로 구성하듯, 엔터프라이즈 서비스에서는 Volume을 만들기 위해 전용 파일시스템 서버를 사용하고 있고, NFS나 클라우드 스토리지를 직접 연결하는 이전 방식에서 CSI (Container Storage Interface)라는 표준화된 방식을 이용하는 방식으로 바뀌고 있다.

a. PV를 사용하는 절차

아래 그림처럼, PV를 사용하려면 관리자가 생성한 PV가 먼저 존재해야 하고(pv create), PV영역을 할당받고(claim pv), 할당된 PV(claim)를 Pod에 연결(mount)하는 순서로 진행된다. 쉬운 비교로, OS의 파일시스템으로 비교하자면 PV가 disk, claim이 partition이라고 생각하면 되지 않을까?

 

b. 저장공간 만들기 - PV 생성

내 윈도우의 DevOps 환경에는 아직은 CSI를 지원하는 소프트웨어나 드라이버를 설치할 계획이 없기 때문에 폴더를 지정해서 PV를 만들기로 했다.

 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  labels:
    type: local
    app: postgres
spec:
  storageClassName: standard
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: <외부 저장소 폴더>

 

<외부 저장소 폴더>를 결정하기 전에 먼저, minikube는 VirtualBox의 가상서버(vm)에서 동작한다는 것을 기억해야 한다. 윈도우 폴더를 VirtualBox의 가상서버에서 사용하려면 공유폴더로 지정이 되어 있어야 하는데, minikube를 설치하면 기본적으로 C:드라이버만 공유폴더로 지정된 것을 VirtualBox의 설정화면에서 확인할 수 있다.

 

아이러니하게도, 공유폴더를 "/c/works/pgdata"처럼 윈도우 폴더로 지정하면, 사용권한이 없다고 Pod생성이 되지 않는다. 이 문제는 PostgreSQL에서 공식적으로 확인해 줬다고 한다. 하지만, PostgreSQL을 운영환경에 설치하는 것이 아니기 ㅐ문에 간단하게 minikube가상머쉰 내부에 공간을 만들고 지정하면 된다.

 

minikube ssh
mkdir -p postgres/data

 

이제 <외부 저장소 폴더>를 "/home/docker/postgres/data"로 지정하면 Pod가 문제없이 만들어진다.

 

  ... <앞과 동일>
  hostPath:
    path: /home/docker/postgres/data

 

위에서 만든 내용을 수정한 후, "postgres-pv.yaml"로 저장하고, kubectl apply를 실행하면 PV가 만들어진다.

 

kubectl apply -f postgres-pv.yaml
kubectl get pv

 

c. 저장공간 할당 - PV Claim

앞에서 만든 PV에 PostgreSQL POD에서 사용할 저장공간을 할당하기 위해 다음과 같이 pv claim을 만들었다.

 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pv-claim
  labels:
    app: postgres
spec:
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

 

위 내용을 postgres-claim.yaml로 저장하고 kubectl apply를 실행하면 위에 정의된 postgres-pv-claim이 만들어진다.

 

2. PostgreSQL을 쿠버네티스에 배포

PostgreSQL DB의 내용을 저장할 PV를 만들고 claim으로 할당했으니, 이제 PostgreSQL을 Deployment와 Service를 사용해서 배포해 본다.

a. Deployment

이제 만들어진 pv claim을 사용해서 PostgreSQL을 배포하면서 외부 저장공간을 연결한다.

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 2
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: 'postgres'
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_PASSWORD
              value: somepassword
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: pgdata
      volumes:
        - name: pgdata
          persistentVolumeClaim:
            claimName: postgres-pv-claim

 

  • image는 tag 없이 'postgres'만 지정해서 latest버전을 선택했는데, 일반적으로 회사에서는 버전을 고정해서 버전변경에 따른 문제를 방지한다.
  • PostgreSQL의 docker image는 한 개의 환경변수, 'POSTGRES_PASSWORD'는 필수로 지정해야 한다고 docker hub에 설명되어 있기 때문에 env로 값을 선언했다. 일반적으로는 환경변수는 ConfigMap에 저장하고, 암호는 분리해서 저장한다. (포스팅이 길어져서 ConfigMap은 따로 정리할 예정이다.)
  • volume은 postgres-pv-claim으로 이미 할당받은 pv영역을 사용하여 /var/lib/postgresql/data에 mount 해서 db데이터를 보존하도록 했다.

내용을 'postgres-deployment.yaml'로 저장하고 kubctl apply로 배포하면

 

kubectl apply -f postgres-deployment.yaml
kubectl get all

 

정상적으로 배포된 것을 확인할 수 있다.

b. Service

배포된 Pod를 NodePort로 네트워크를 열기 위해 아래와 같이 Service를 작성하고 'postgres-service.yaml'로 저장하고

 

apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  type: NodePort
  ports:
    - port: 5432
  selector:
    app: postgres

 

kubectl apply를 실행한다.

 

kubectl apply -f postgres-service.yaml
kubectl.exe get svc

 

c. PostgreSQL 확인하기

간단하게 연결을 테스트하기 위해 2개의 replica로 배포된 PostgreSQL 중 하나의 Pod를 선택하고, psql client를 실행해서 database목록을 조회해 보기로 했다.

 

kubectl.exe get pod
kubectl exec -it postgres-65cdc45d44-cc7tv -- psql -h localhost -U postgres --password -p 5432 postgres

 

입력하고 나면 password를 요청하는데, 위에서 env로 전달할 "somepassword"를 입력하면 login이 되고 "\l" 명령으로 database 목록을 확인할 수 있다.

 

 

만일 minikube를 VirtualBox기반으로 설치했아면 minikube ip (보통은 192.168.59.102)와 NodePort (kubectl로 확인한 31898)를 사용하면 윈도우상의 프로그램에서 PostgreSQL로 연결할 수 있을 것이다.