brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Nov 03. 2023

38탄-7. EKS DB - PostgreSQL 1/3

2023년 현재 Mysql보다 PstgreSQL이 지원이 더 잘 된다.



목표

PostgreSQL 설치법 알아보자

PostgreSQL 사용법 알아보자

CloudNativePG 사용해보자



<1> 기본 - 우분트에 PostgreSQL 설치하기

<2> 기본 - PostgreSQL 사용하기

<3> CloudNativePG설치

<4> CloudNativePG 기본 사용

<5> 테스트를 위해 DVD Rental Sample Database 불러오기




<1> 기본 - 우분트에 PostgreSQL 설치하기



Ubuntu 에 PostgreSQL 14 설치 

- 링크


1

# 설치 : 기본 버전 14 : ostgresql-14 postgresql-client-14

# apt-get -y install postgresql-<Version>


apt-get -y install postgresql


sed -i 's/postgres                                peer/postgres                                trust/g' /etc/postgresql/14/main/pg_hba.conf


sed -i 's/127.0.0.1\/32            scram-sha-256/127.0.0.1\/32            md5/g' /etc/postgresql/14/main/pg_hba.conf


systemctl restart postgresql



# pg_hba.conf 파일 확인

grep -v '^#' /etc/postgresql/14/main/pg_hba.conf | sed '/^$/d'

local   all             postgres                                trust

local   all             all                                     peer

host    all             all             127.0.0.1/32            md5

...


# 버전 확인

psql --version

psql (PostgreSQL) 14.3 (Ubuntu 14.3-0ubuntu0.22.04.1)



# postgres 계정으로 psql 접속

psql -U postgres

----------------


# 처음 접속 시 자동으로 postgres 데이터베이스(명)에 접속하게 됨

postgres=#


# 연결 정보 확인

postgres=# \conninfo

You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".



# 실습 진행~

----------------

# [터미널2] postgres연결 상태에서 연결 정보 확인 : UDS Unix Domain Socket , 호스트 내부 프로세스간 통신

ss | egrep 'Netid|postgresql'

Netid State  Recv-Q Send-Q    Local Address:Port                         Peer Address:Port Process

u_str ESTAB  0      0         /var/run/postgresql/.s.PGSQL.5432 42342    * 41348





<2> 기본 - PostgreSQL 사용하기


PostgreSQL 기본 사용 - 링크


1

# 데이터베이스 생성 : 소문자만 가능, 대문자로 작성해도 소문자로 바꿔서 저정됨

CREATE DATABASE doik_users;


# 데이터베이스 조회

\l

List of databases

    Name    |  Owner   | Encoding | Collate |  Ctype  |   Access privileges

------------+----------+----------+---------+---------+-----------------------

 doik_users | postgres | UTF8     | C.UTF-8 | C.UTF-8

 postgres   | postgres | UTF8     | C.UTF-8 | C.UTF-8

...



# 데이터베이스 이동(접속)

\c doik_users

You are now connected to database "doik_users" as user "postgres".

doik_users=#



# 추가 데이터베이스 생성

CREATE DATABASE temp_users;

\l



# 추가한 데이터베이스 삭제 : 참고로 현재 접속한 데이터베이스는 삭제할 수 없음

DROP DATABASE temp_users;

\l



# 테이블 생성 : '컬럼명 자료형'

CREATE TABLE TEAM (

   ID INT PRIMARY KEY     NOT NULL,

   NAME           TEXT    NOT NULL,

   AGE            INT     NOT NULL,

   ADDRESS        CHAR(50)

);



# 현재 데이터베이스에서 테이블 조회

\dt

List of relations

 Schema | Name | Type  |  Owner

--------+------+-------+----------

 public | team | table | postgres

(1 row)



# 테이블 삭제

DROP TABLE team;

\dt



# 다시 테이블 생성 : '컬럼명 자료형' - 링크

CREATE TABLE COMPANY(

   ID INT PRIMARY KEY     NOT NULL,

   NAME           TEXT    NOT NULL,

   AGE            INT     NOT NULL,

   ADDRESS        CHAR(50),

   SALARY         REAL,

   JOIN_DATE    DATE

);



# 데이터 추가하기 : 문자열 데이터는 작은따옴표(')로 감싸기

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (1, 'Paul', 32, 'California', 20000.00, '2001-07-13');



# 데이터 추가하기 : SALARY 컬럼 생략

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,JOIN_DATE) VALUES (2, 'Allen', 25, 'Texas', '2007-12-13');



# 데이터 추가하기 : JOIN_DATE 컬럼에 default 값 사용

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (3, 'Teddy', 23, 'Norway', 20000.00, DEFAULT );



# 데이터 여러개 추가하기

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00, '2007-12-13' ), (5, 'David', 27, 'Texas', 85000.00, '2007-12-13');



# 테이블에 데이터 조회 : SELECT 컬럼 지정 , * 모든 컬럼을 의미 , FROM 테이블을 지정

SELECT * FROM company;

 id | name  | age |                      address                       | salary | join_date

----+-------+-----+----------------------------------------------------+--------+------------

  1 | Paul  |  32 | California                                         |  20000 | 2001-07-13

  2 | Allen |  25 | Texas                                              |        | 2007-12-13

  3 | Teddy |  23 | Norway                                             |  20000

  4 | Mark  |  25 | Rich-Mond                                          |  65000 | 2007-12-13

  5 | David |  27 | Texas                                              |  85000 | 2007-12-13

(5 rows)



# 선택한 자료(컬럼) 조회

SELECT id,name,age FROM company;

id | name  | age

----+-------+-----

  1 | Paul  |  32

  2 | Allen |  25

  3 | Teddy |  23

  4 | Mark  |  25

  5 | David |  27

(5 rows)



# 데이터 선택 조회 명령어 LIMIT

SELECT id,name,age FROM company LIMIT 2;



# 데이터 선택 조회 명령어 OFFSET

SELECT id,name,age FROM company LIMIT 2 OFFSET 2;



# 데이터 선택 조회 명령어 ORDER BY : 오름차순/내림차순, 정렬할 컬럼을 반드시 지정

SELECT * FROM company ORDER BY age ASC;

SELECT * FROM company ORDER BY age DESC;



# 데이터 선택 조회 명령어 WHERE : 컬럼 안에 특정한 내용을 필터링 조회, 비교 연산자(= , <> , > , < , >= , <=)

SELECT * FROM company WHERE id = 1;

SELECT * FROM company WHERE id <> 1;

SELECT * FROM company WHERE id > 3;

SELECT * FROM company WHERE id >= 3;



# 데이터 수정 : WHERE 로 수정할 low 조건을 지정 후, 'SET 컬럼명 = 바꿀 데이터 내용' 으로 수정, RETURNING 수정 내용 바로 조회

UPDATE COMPANY SET SALARY = 15000 WHERE ID = 3 RETURNING *;



# 데이터 삭제 : FROM 테이블명에, WHERE 로 삭제할 데이터 지정

DELETE FROM COMPANY WHERE ID = 2;

SELECT * FROM company;



# 테이블의 모든 데이터 삭제

DELETE FROM COMPANY;

SELECT * FROM company;



# 테이블 삭제

DROP TABLE COMPANY;

\dt





<3> CloudNativePG설치



1

CloudNativePG 소개 : 쿠버네티스 환경에서 PostgreSQL 워크로드를 관리 - 링크

CloudNativePG 는 EDB가 개발 , 오퍼레이터 Level V - Auto Pilot 지원 - 링크

EDB라는 회사.


‘23.10.29 CNPG 버전 : 1.21.x - 쿠버네티스 지원 버전(1.25 ~ 1.28), PostgreSQL 지원 버전(12 ~ 16)  - 링크





아키텍처

Architecture 

https://cloudnative-pg.io/documentation/current/architecture/


https://www.cncf.io/blog/2023/09/29/recommended-architectures-for-postgresql-in-kubernetes/


https://cloudnative-pg.io/documentation/current/use_cases/


스토리지 수준 복제 vs 애플리케이션 수준 복제

PostgreSQL는 스토리지 수준 복제를 권장하지 않음

https://www.youtube.com/watch?si=4Shn7hdxmCt4IDnO&v=99uSJXkKpeI&feature=youtu.be



Available services for applications:

rw  - Primary 

ro - slave

r - primary , slave


Multi-cluster deployments - 2개의 다른 쿠버네티스 클러스터에서, Replica Cluster 에 Designated Primary 는 Primary 클러스터의 Primary 의 복제



2

설치


https://cloudnative-pg.io/documentation/current/installation_upgrade/

https://cloudnative-pg.io/documentation/current/quickstart/

https://operatorhub.io/operator/cloudnative-pg

https://www.postgresql.org/docs/current/multibyte.html

https://cloudnative-pg.io/documentation/current/replication/

https://cloudnative-pg.io/documentation/current/bootstrap/

https://cloudnative-pg.io/documentation/current/samples/



1

메뉴얼

https://operatorhub.io/operator/cloudnative-pg  오른쪽 위 Install  클릭


# Install Operator Lifecycle Manager (OLM), a tool to help manage the Operators running on your cluster.


curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.25.0/install.sh | bash -s v0.25.0


kubectl get ns

kubectl get all -n olm

kubectl get-all -n olm


kubectl get all -n operators

No resources found in operators namespace.

현재는 설치된 오퍼레이트가 없다.



kubectl get-all -n operators | grep -v packagemanifest



2

# Install the operator by running the following command


# This Operator will be installed in the "operators" namespace and will be usable from all namespaces in the cluster.


curl -s -O https://operatorhub.io/install/cloudnative-pg.yaml


cat cloudnative-pg.yaml | yh

kubectl create -f cloudnative-pg.yaml


kubectl get all -n operators





kubectl get-all -n operators | grep -v packagemanifest



3

kubectl get crd | grep cnpg

backups.postgresql.cnpg.io                    2023-11-16T08:05:33Z

clusters.postgresql.cnpg.io                   2023-11-16T08:05:33Z

poolers.postgresql.cnpg.io                    2023-11-16T08:05:33Z

scheduledbackups.postgresql.cnpg.io           2023-11-16T08:05:32Z


// clusters.postgresql.cnpg.io                   2023-11-16T08:05:33Z  // 포스트그래 CR이다.



## api 정보 확인

kubectl explain clusters

kubectl explain backups





4

# fter install, watch your operator come up using next command.


# To use it, checkout the custom resource definitions (CRDs) introduced by this operator to start using it.

오페레이터가 설치되었다~


kubectl get clusterserviceversions -n operators

NAME                     DISPLAY         VERSION   REPLACES                 PHASEcloudnative-pg.v1.21.1   CloudNativePG   1.21.1    cloudnative-pg.v1.21.0   Succeeded

NAME                     DISPLAY         VERSION   REPLACES                 PHASE

cloudnative-pg.v1.21.1   CloudNativePG   1.21.1    cloudnative-pg.v1.21.0   Succeeded



# csv = clusterserviceversions 축약


kubectl get csv -A



---------------------------------------



5

# 클러스터 설치 Deploy a PostgreSQL cluster : 버전 15.3 (추후 15.4 롤링 업데이트 예정)

## 3대 파드 구성(프라이머리 1대, 스탠드바이 2대) , config parameters 설정, pg_hba 설정, bootstrap 설정, 파드 모니터 설정



cat <<EOT> mycluster1.yaml

# Example of PostgreSQL cluster

apiVersion: postgresql.cnpg.io/v1

kind: Cluster

metadata:

  name: mycluster

spec:

  imageName: ghcr.io/cloudnative-pg/postgresql:15.3

  instances: 3  

  storage:

    size: 3Gi

  postgresql:

    parameters:

      max_worker_processes: "40"

      timezone: "Asia/Seoul"

    pg_hba:

      - host all postgres all trust

  primaryUpdateStrategy: unsupervised

  enableSuperuserAccess: true

  bootstrap:

    initdb:

      database: app

      encoding: UTF8

      localeCType: C

      localeCollate: C

      owner: app

  monitoring:

    enablePodMonitor: true

EOT


// monitoring = 프로메테우스 


# 설치되는 파드 순서 확인 : job.batch(initdb -> join)

kubectl apply -f mycluster1.yaml && kubectl get pod -w


// job인데  init db 



# 확인

kubectl get pod,pvc,pv,svc,ep


watch -d kubectl get pod,pvc,pv,svc,ep



kubectl df-pv




6

kubectl describe pod -l cnpg.io/cluster=mycluster # TCP 9187 메트릭 제공

Containers:

  postgres:

    Container ID:    containerd://5aa78ded9bddff24b138aee598f212c2d18278cbcaeb63cb2d85cfc9f21bf245

    Image:           ghcr.io/cloudnative-pg/postgresql:15.3

    Image ID:        ghcr.io/cloudnative-pg/postgresql@sha256:a77cf81d90ad26148d795a8ba2a880715d11b30ec45dd15aa34ae8d7cc4dc2dd

    Ports:           5432/TCP, 9187/TCP, 8000/TCP



// 9187 프로메테우스


kubectl get pod -l cnpg.io/cluster=mycluster -owide

curl -s <파드IP>:9187/metrics

curl -s 192.168.1.84:9187/metrics





# 프로메테우스 ingress 도메인으로 웹 접속

## Targets -> podMonitor/default/cluster-with-metrics 확인

## Graph : cnpg 로 메트릭 확인, 예) cnpg_pg_replication_lag

echo -e "Prometheus Web URL = https://prometheus.$MyDomain"

Prometheus Web URL = https://prometheus.masterseo1.link


status > target 확인




7


# 그라파나 대시보드 설정 : CloudNativePG 대시보드

kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/docs/src/samples/monitoring/grafana-configmap.yaml



# 그라파나 ingress 도메인으로 웹 접속 : 기본 계정 - admin / prom-operator

echo -e "Grafana Web URL = https://grafana.$MyDomain"




8

# 설치된 클러스터 확인

7분전에 생성된것만 확인할때


kubectl get-all --since 7m

NAME                          NAMESPACE  AGE

configmap/test-cnp-dashboard  default    4m49s



kubectl get cluster

(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get cluster

NAME        AGE   INSTANCES   READY   STATUS                     PRIMARY

mycluster   19m   3           3       Cluster in healthy state   mycluster-1




9

# cnpg 플러그인 설치 : 방안1(krew 활용), 방안2(직접 설치)


## (직접설치) curl -sSfL https://github.com/cloudnative-pg/cloudnative-pg/raw/main/hack/install-cnpg-plugin.sh | sudo sh -s -- -b /usr/local/bin



kubectl krew install cnpg

Installing plugin: cnpg

Installed plugin: cnpg

\

 | Use this plugin:

 |      kubectl cnpg

 | Documentation:

 |      https://github.com/cloudnative-pg/cloudnative-pg

/



kubectl cnpg status mycluster


플러그인으로 클러스터 모든 정보가  나온다.



10

더 디테일하게 볼때?

kubectl cnpg status mycluster --verbose  # -v , config 설정 적용 확인

...

PostgreSQL HBA Rules



# Grant local access

local all all peer map=local

# Require client certificate authentication for the streaming_replica user

hostssl postgres streaming_replica all cert

hostssl replication streaming_replica all cert

hostssl all cnpg_pooler_pgbouncer all cert

...



11

# 기본 리소스들 확인 : sts,deploy 사용하지 않음! , 오퍼레이터가 직접 개별 파드를 생성 <- Why?

kubectl get pod,deploy

kubectl get svc,ep,endpointslices -l cnpg.io/cluster=mycluster


endpoints/mycluster-r       192.168.1.120:5432,192.168.2.217:5432,192.168.3.93:5432   26m

endpoints/mycluster-ro      192.168.2.217:5432,192.168.3.93:5432                      26m

endpoints/mycluster-rw      192.168.1.120:5432                                        26m

// primary



kubectl get cm,secret

kubectl get pdb



12

# PV/PVC 확인

kubectl df-pv

kubectl get pvc,pv



13

## 아래 AWS EBS를 현재 PV로 사용하고 있는 상태에서, 아래 Node Affinity는 어떤 의미인가?

노드 어피티니 = aws ebs csi 드라이버는 디폴트는 az에서 배포되는 자동으로 들어간다.



kubectl describe pv | grep 'Node Affinity:' -A2


Node Affinity:     

  Required Terms:  

    Term 0:        topology.ebs.csi.aws.com/zone in [ap-northeast-2c]

--

Node Affinity:     

  Required Terms:  

    Term 0:        topology.ebs.csi.aws.com/zone in [ap-northeast-2a]

--

Node Affinity:     

  Required Terms:  

    Term 0:        topology.ebs.csi.aws.com/zone in [ap-northeast-2b]





4

리포트 확인 ??


# (참고) 리소스 및 이벤트 YAML 확인

입축에서 파일로 떨구어준다.


kubectl cnpg report cluster mycluster

unzip ~



5



# (참고) 로깅 - 링크

kubectl logs mycluster-1 -c bootstrap-controller

kubectl logs mycluster-2 -c bootstrap-controller

kubectl logs mycluster-1 | jq 'select(.logger=="postgres") | .record.message'

kubectl logs mycluster-2 | jq 'select(.logger=="postgres") | .record.message'

kubectl logs mycluster-3 | jq 'select(.logger=="postgres") | .record.message'

...

"entering standby mode"

...





<4> CloudNativePG 기본 사용


PostgreSQL 접속 : myclient 파드 생성 - Link


1

# 2개의 자격 증명이 저장된 secret 확인


kubectl get secret -l cnpg.io/cluster=mycluster

NAME                  TYPE                       DATA   AGE

mycluster-app         kubernetes.io/basic-auth   3      109m

mycluster-superuser   kubernetes.io/basic-auth   3      109m




2

슈퍼유저 


# superuser 계정명

kubectl get secrets mycluster-superuser -o jsonpath={.data.username} | base64 -d ;echo

postgres



# superuser 계정 암호

kubectl get secrets mycluster-superuser -o jsonpath={.data.password} | base64 -d ;echo

UUTWc0Apwp8i0BbXd06jauSlV6XKzoebMqEksQdANdNF0cPlQxio0



pg pass 

kubectl get secrets mycluster-superuser -o jsonpath={.data.pgpass} | base64 -d

mycluster-rw:5432:*:postgres:TOk00xrh8kuT1uJJpMOuwotWag3dsFieXIuZwzn04OZYoyA8GPdza2xu8OgiUMTd



3

# app 계정명

kubectl get secrets mycluster-app -o jsonpath={.data.username} | base64 -d ;echo

app



# app 계정 암호

kubectl get secrets mycluster-app -o jsonpath={.data.password} | base64 -d ;echo

nLDgzc1ZGTT5BC1NV8Rjw1LVHbQ3oI4IJUYp



# app 계정 암호 변수 지정

AUSERPW=$(kubectl get secrets mycluster-app -o jsonpath={.data.password} | base64 -d)



4

# myclient 파드 3대 배포 : envsubst 활용


## PODNAME=myclient1 VERSION=15.3.0 envsubst < myclient.yaml | kubectl apply -f -

curl -s https://raw.githubusercontent.com/gasida/DOIK/main/5/myclient-new.yaml -o myclient.yaml



파드 3개를 배포해보자~


for ((i=1; i<=3; i++)); do PODNAME=myclient$i VERSION=15.3.0 envsubst < myclient.yaml | kubectl apply -f - ; done

pod/myclient1 created

pod/myclient2 created

pod/myclient3 created



5

(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]# k get svc

NAME              TYPE           CLUSTER-IP       EXTERNAL-IP                                                                         PORT(S)                      AGE

kubernetes        ClusterIP      10.100.0.1       <none>                                                                              443/TCP                      30h

my-wordpress      NodePort       10.100.49.31     <none>                                                                              80:31575/TCP,443:30425/TCP   8h

mycluster-r       ClusterIP      10.100.139.155   <none>                                                                              5432/TCP                     49m

mycluster-ro      ClusterIP      10.100.69.75     <none>                                                                              5432/TCP                     49m

mycluster-rw      ClusterIP      10.100.250.212   <none>                                                                              5432/TCP                     49m

svc-nlb-ip-type   LoadBalancer   10.100.14.16     k8s-default-svcnlbip-1ff3700cb4-0a298ac735c2d895.elb.ap-northeast-2.amazonaws.com   80:32587/TCP                 28h





(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]# k get ep

NAME              ENDPOINTS                                                 AGE

kubernetes        192.168.1.92:443,192.168.3.91:443                         30h

my-wordpress      <none>                                                    8h

mycluster-r       192.168.1.120:5432,192.168.2.217:5432,192.168.3.93:5432   50m

mycluster-ro      192.168.2.217:5432,192.168.3.93:5432                      50m

mycluster-rw      192.168.1.120:5432                                        50m

svc-nlb-ip-type   <none>                                                    28h

(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]#

(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]#




# [myclient1] superuser 계정으로 mycluster-rw 서비스 접속


(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]# k get pod -owide

NAME          READY   STATUS    RESTARTS   AGE     IP              NODE                                               NOMINATED NODE   READINESS GATES

myclient1     1/1     Running   0          3m54s   192.168.1.121   ip-192-168-1-231.ap-northeast-2.compute.internal   <none>           <none>

myclient2     1/1     Running   0          3m51s   192.168.2.191   ip-192-168-2-233.ap-northeast-2.compute.internal   <none>           <none>

myclient3     1/1     Running   0          3m49s   192.168.1.223   ip-192-168-1-231.ap-northeast-2.compute.internal   <none>           <none>

mycluster-1   1/1     Running   0          46m     192.168.1.120   ip-192-168-1-231.ap-northeast-2.compute.internal   <none>           <none>

mycluster-2   1/1     Running   0          45m     192.168.2.217   ip-192-168-2-233.ap-northeast-2.compute.internal   <none>           <none>

mycluster-3   1/1     Running   0          45m     192.168.3.93    ip-192-168-3-215.ap-northeast-2.compute.internal   <none>           <none>

(11-15-access@myeks:default) [root@myeks-bastion-EC2 ~]#




kubectl cnpg status mycluster




6

myclient1번 파드에서 접속해보자. 


kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 --variable=HISTFILE=/tmp/.psql_history



-------------

# 연결 정보 확인

postgres=# \conninfo

You are connected to database "postgres" as user "postgres" on host "mycluster-rw" (address "10.200.1.40") at port "5432".

SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)



# 데이터베이스 조회


postgres=# \l


List of databases

   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges

-----------+----------+----------+---------+-------+-----------------------

 app       | app      | UTF8     | C       | C     

 postgres  | postgres | UTF8     | C       | C     

 template0 | postgres | UTF8     | C       | C     | =c/postgres          +

           |          |          |         |       | postgres=CTc/postgres

 template1 | postgres | UTF8     | C       | C     | =c/postgres          +

           |          |          |         |       | postgres=CTc/postgres

(4 rows)




# 타임존 확인


postgres=# SELECT * FROM pg_timezone_names WHERE name = current_setting('TIMEZONE');


    name    | abbrev | utc_offset | is_dst

------------+--------+------------+--------

 Asia/Seoul | KST    | 09:00:00   | f

(1 row)



# 빠져나오기

postgres=# \q

-------------



# [myclient1] superuser 계정으로 mycluster-rw 서비스 접속하여 데이터베이스 리스트 조회

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -l



7

# [myclient1] app 계정으로 mycluster-rw 서비스 접속하여 app 데이터베이스 이동 >> 

app 계정 암호 직접 입력


kubectl exec -it myclient1 -- psql -U app -h mycluster-rw -p 5432 -d app -W  --variable=HISTFILE=/tmp/.psql_history


or09VUb1rCWTVFqVWKWURls23wsslhC8Ru0UFYQ2nBnKFRiRPfqdcyXehba12nSw

-------------

app=> \conninfo

You are connected to database "app" as user "app" on host "mycluster-rw" (address "10.200.1.40") at port "5432".

SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)

app=> \l

app=> \dt

app=> \q

-------------

                    



8

외부에서 접속 ?

 → 보안을 위해서 접속 통제를 하거나, CLB 대신 NLB(보안 그룹, Internal) 설정을 권장


# postgresql psql 툴 설치

yum install postgresql -y



# Service(LoadBalancer)로 외부 노출 설정 : 3~5분 정도 대기 후 아래 접속 시도

kubectl get svc,ep mycluster-rw


kubectl patch svc mycluster-rw -p '{"spec":{"type":"LoadBalancer"}}'


kubectl annotate service mycluster-rw "external-dns.alpha.kubernetes.io/hostname=psql.$MyDomain"



콘솔 로드밸런서에서 확인하자~~



#

psql -U postgres -h psql.$MyDomain

----------------------------------

app=> \conninfo

app=> \l

app=> \q

----------------------------------




<5> 테스트를 위해 DVD Rental Sample Database 불러오기


복제 확인 및 Service 서비스별 접속 차이 확인 - Link


1

# 다운로드

curl -LO https://www.postgresqltutorial.com/wp-content/uploads/2019/05/dvdrental.zip

unzip dvdrental.zip



# myclient1 파드에 dvdrental.tar 복사

kubectl cp dvdrental.tar myclient1:/tmp



# [myclient1] superuser 계정으로 mycluster-rw 서비스 접속 후 데이터베이스 생성


데이터 베이스  만든다.

kubectl exec -it myclient1 -- createdb -U postgres -h mycluster-rw -p 5432 dvdrental


데이터 베이스 리스트 본다.

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -l


dvd rental 만들어 졌다.



# DVD Rental Sample Database 불러오기

kubectl exec -it myclient1 -- pg_restore -U postgres -d dvdrental /tmp/dvdrental.tar -h mycluster-rw -p 5432



# DVD Rental Sample Database 에서 actor 테이블 조회

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -d dvdrental -c "SELECT * FROM actor"




2

각 파드에 접근해서 DVD Rental Sample Database  복제 동기화 확인


# 각각 mycluster-ro 와 mycluster-r(mycluster-any) 서비스에 접속해보자

kubectl get svc,ep,endpointslices -l cnpg.io/cluster=mycluster



# 파드IP 변수 지정

POD1=$(kubectl get pod mycluster-1 -o jsonpath={.status.podIP})

POD2=$(kubectl get pod mycluster-2 -o jsonpath={.status.podIP})

POD3=$(kubectl get pod mycluster-3 -o jsonpath={.status.podIP})



# 파드별 actor 테이블 카운트 조회

kubectl exec -it myclient1 -- psql -U postgres -h $POD1 -p 5432 -d dvdrental -c "SELECT COUNT(*) FROM actor"

 count

-------

   200

(1 row)



kubectl exec -it myclient1 -- psql -U postgres -h $POD2 -p 5432 -d dvdrental -c "SELECT COUNT(*) FROM actor"

 count

-------

   200

(1 row)



kubectl exec -it myclient1 -- psql -U postgres -h $POD3 -p 5432 -d dvdrental -c "SELECT COUNT(*) FROM actor"

 count

-------

   200

(1 row)




# (참고) 각 서비스명으로 접근 조회 확인

actor 확인 해보자~


kubectl exec -it myclient1 -- psql -U postgres -h mycluster-ro -p 5432 -d dvdrental -c "SELECT * FROM actor"


kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -d dvdrental -c "SELECT * FROM actor"


kubectl exec -it myclient1 -- psql -U postgres -h mycluster-r  -p 5432 -d dvdrental -c "SELECT * FROM actor"



3


rw vs ro vs r 차이 확인


# rw 로 접근

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -c "select inet_server_addr();"

------------------

 192.168.1.120

(1 row)



for i in {1..9}; do kubectl exec -it myclient1 -- psql -U postgres -h mycluster-rw -p 5432 -c "select inet_server_addr();"; done | sort | uniq -c | sort -nr | grep 192


결과 ?

rw1대로만 접속한다.

 9  192.168.1.120




# ro 로 접근

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-ro -p 5432 -c "select inet_server_addr();"


for i in {1..9}; do kubectl exec -it myclient1 -- psql -U postgres -h mycluster-ro -p 5432 -c "select inet_server_addr();"; done | sort | uniq -c | sort -nr | grep 192


결과 ?

스텐바이 2대로 부하 분산 되는 결과

      5  192.168.3.93

      4  192.168.2.217




# r 로 접근

kubectl exec -it myclient1 -- psql -U postgres -h mycluster-r -p 5432 -c "select inet_server_addr();"


for i in {1..9}; do kubectl exec -it myclient1 -- psql -U postgres -h mycluster-r -p 5432 -c "select inet_server_addr();"; done | sort | uniq -c | sort -nr | grep 192


결과 ?

-r은 3대 모두에 분산되는 결과가 나온다.

      5  192.168.2.217

      3  192.168.1.120

      1  192.168.3.93




4

여러가지 방법으로 임포팅 하는 방법들


(옵션) Importing Postgres databses : https://cloudnative-pg.io/documentation/current/database_import/



다음은


https://brunch.co.kr/@topasvga/3508





주말 CloudNet  스터디 내용 참고하여  정리한 부분입니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  






매거진의 이전글 38탄-6. EKS DB - 워드프레스 DB사용 3/3
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari