[Infra] 도커(docker)(9) 도커 PostgreSQL 컨테이너 배포하기

업데이트:

도커(docker)(9) 도커 PostgreSQL 컨테이너 배포하기

참고링크

운영체제 프론트엔드 백엔드 데이터베이스 인프라
리눅스구조 js필터 아파치에러로그 행삭제 아파치스쿱
프로세스 헬로월드 웹서버개념 ES기초 로그분석
네임스페이스 프로젝트생성 아파치설치 MySQL기초 beeline
디렉토리 헤더생성 flask연동 큐브리드 하둡기초
리다이렉션 async-get 장고MsSQL연결 null공백 나이파이
쓰레드 async-post 장고MySQL연결 MySQL설치(win) 백본
라즈베리파이설치 로그인페이지 장고inpectdb MySQL테이블생성 제플린
OSI7계층소개   장고read   SSL인증
OSI1계층   장고insert   커버로스
OSI2계층   장고put   도커개념
OSI3계층   장고del   도커설치
OSI4계층   flask한글요청   도커기초
OSI5,6,7계층       도커이미지
DNS서버       컨테이너네트워크
DHCP       도커API
bashrc       도커컴포즈
bash       도커볼륨
ifconfig       장고이미지
소켓프로그래밍       도커postgre
리눅스유저생성       도커이미지삭제
netstat포트열기       도커Redis
컴파일러       k8s구조
운영체제vs커널       k8s설치
작업스케쥴링       k8s서비스배포
디스크추가       POD네트워크
aws유저추가       퍼시스턴트볼륨
기초명령어       k8s에러
포트번호        

참고 링크

1. 서론

이번 포스팅에서는 도커를 이용해 PostgreSQL 이미지를 pull 받아 컨테이너로 띄워보겠습니다.

2. 이미지 받아서 컨테이너로 띄우기

2.1. 도커 허브에서 이미지 pull 받기

먼저 다음 코드와 같이 PostgreSQL 이미지를 도커 허브에서 pull받아보겠습니다.

$ docker pull postgres

Using default tag: latest
latest: Pulling from library/postgres
31b3f1ad4ce1: Already exists
dc97844d0cd5: Pull complete
9ad9b1166fde: Pull complete
286c4682b24d: Pull complete
1d3679a4a1a1: Pull complete
5f2e6cdc8503: Pull complete
0f7dc70f54e8: Pull complete
a090c7442692: Pull complete
81bfe40fd0f6: Pull complete
8ac8c22bbb38: Pull complete
96e51d1d3c6e: Pull complete
667bd4154fa2: Pull complete
87267fb600a9: Pull complete
Digest: sha256:b0ee049a2e347f5ec8c64ad225c7edbc88510a9e34450f23c4079a489ce16268
Status: Downloaded newer image for postgres:latest
docker.io/library/postgres:latest

위와 같이 도커 허브에서 pull을 받고 도커 이미지를 살펴보겠습니다.

$ docker image ls
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
postgres             latest    75993dd36176   2 weeks ago     376MB

이미지를 확인하면 PostgreSQL 이미지가 잘 받아진 것을 알 수 있습니다.

2.2. postgre 컨테이너 실행

앞서 pull 받은 이미지를 run 명령어를 통해 컨테이너를 실행해보겠습니다.

$ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
088f20012019a3be9b47eac2ea11f3811691f33a8100c2dadee0321364e2d7af

위 커맨드를 입력하면 컨테이너를 실행할 수 있습니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS      NAMES
088f20012019   postgres   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   5432/tcp   some-postgres

작동 중인 컨테이너를 확인하면 제대로 떠있는 것을 볼 수 있습니다.

2.3. 컨테이너 내부 탐험

이번에는 작동중인 PostgreSQL 컨테이너 내부를 탐험해보겠습니다.

~$ docker exec -it 088f20012019 /bin/bash

root@088f20012019:/# psql -U postgres

psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

postgres=# CREATE USER cheolwon PASSWORD '1234' SUPERUSER;
CREATE ROLE

postgres=# CREATE DATABASE test01 OWNER cheolwon;
CREATE DATABASE

postgres=# \c test01 cheolwon
You are now connected to database "test01" as user "cheolwon".

test01=# CREATE TABLE test_table(
    id INTEGER PRIMARY KEY,
    name VARCHAR(20)
);
CREATE TABLE

test01=# \dt
           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | test_table | table | cheolwon
(1 row)

test01=# SELECT * FROM test_table;
 id | name
----+------
(0 rows)

test01=# INSERT INTO test_table (id, name)
VALUES(
    '1',
    'youngjin'
);
INSERT 0 1

test01=# SELECT * FROM test_table;
 id |   name
----+----------
  1 | youngjin
(1 row)

test01=# \q

위 코드가 조금 길기 때문에 잘라서 보겠습니다.

~$ docker exec -it 088f20012019 /bin/bash

root@088f20012019:/#

위 명령어를 이용하면 해당 컨테이너 ID의 내부로 들어갈 수 있습니다.

root@088f20012019:/# psql -U postgres

psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

postgres=#

위 명령어는 postgres 롤로 psql을 실행하겠다는 의미입니다.

postgres=# CREATE USER cheolwon PASSWORD '1234' SUPERUSER;
CREATE ROLE

postgres=# CREATE DATABASE test01 OWNER cheolwon;
CREATE DATABASE

다음으로 위와 같이 새로운 롤(USER)와 데이터베이스를 생성합니다.

postgres=# \c test01 cheolwon
You are now connected to database "test01" as user "cheolwon".

test01=#

위 코드는 cheolwon 유저로 test01 데이터베이스에 접속하겠다는 의미입니다.

test01=# CREATE TABLE test_table(
    id INTEGER PRIMARY KEY,
    name VARCHAR(20)
);
CREATE TABLE

test01=# \dt
           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | test_table | table | cheolwon
(1 row)

test01=# SELECT * FROM test_table;
 id | name
----+------
(0 rows)

위 코드는 test01 데이터베이스에 test_table이라는 테이블을 생성하는 코드입니다.

test01=# INSERT INTO test_table (id, name)
VALUES(
    '1',
    'youngjin'
);
INSERT 0 1

test01=# SELECT * FROM test_table;
 id |   name
----+----------
  1 | youngjin
(1 row)

test01=# \q

위 코드는 test_table이라는 테이블에 데이터를 추가시키는 코드입니다.

2.4. 컨테이너를 정지하면 데이터가 살아있을까?

도커 컨테이너를 이용해 DB를 띄우는 경우 컨테이너를 정지하면 데이터가 살아 있을까요? 이번에는 컨테이너를 종료해도 데이터가 살아있는지 확인해보겠습니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS        PORTS      NAMES
088f20012019   postgres   "docker-entrypoint.s…"   45 hours ago   Up 45 hours   5432/tcp   some-postgres

먼저 위 코드와 같이 작동 중인 컨테이너를 조회합니다.

$ docker container stop 088f20012019
088f20012019

그리고 해당 컨테이너를 정지(stop)시킵니다. 중요한건 컨테이너를 삭제(rm)하는게 아니라 정지만 시키는 것입니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS        PORTS      NAMES

컨테이너를 정지시켰으므로 작동중인 컨테이너는 조회되지 않습니다.

$ docker container ls -a
CONTAINER ID   IMAGE           COMMAND                  CREATED        STATUS                     PORTS     NAMES
088f20012019   postgres        "docker-entrypoint.s…"   45 hours ago   Exited (0) 7 seconds ago             some-postgres

정지된 컨테이너를 포함해서 전체 컨테이너를 검색하면 나옵니다.

$ docker start 088f20012019
088f20012019

start 명령어를 통해 정지한 컨테이너를 재가동 하겠습니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED        STATUS         PORTS      NAMES
088f20012019   postgres   "docker-entrypoint.s…"   45 hours ago   Up 5 seconds   5432/tcp   some-postgres

컨테이너가 잘 돌아가는 것을 알 수 있습니다.

$ docker exec -it 088f20012019 /bin/bash
root@088f20012019:/# psql -U postgres
psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

postgres=# \c test01 cheolwon
You are now connected to database "test01" as user "cheolwon".
test01=# \dt
           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | test_table | table | cheolwon
(1 row)

test01=# SELECT * FROM test_table;
 id |   name
----+----------
  1 | youngjin
(1 row)

test01=# \q

컨테이너 내부에 들어가서 데이터를 확인해보면 데이터가 살아있는 것을 알 수 있습니다.

이처럼 컨테이너를 정지(stop)시켰다가 재가동해도 데이터는 살아있다는 것을 알 수 있습니다. 이때 주의해야할 점은 컨테이너를 삭제(rm)시킨다면 데이터가 같이 사라집니다. 그렇다면 좀더 안전하게 데이터를 보관할 수는 없을까요?

2.5. 도커 마운트(mount) - 호스트 경로와 컨테이너 연결

이번에는 도커 마운트 개념에 대해 알아보겠습니다. 도커 마운트는 호스트 상의 경로와 컨테이너를 연결하는 개념입니다. 먼저 이미지를 검색하면 다음과 같습니다.

~$ docker image ls
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
postgres             latest    75993dd36176   2 weeks ago     376MB

호스트 경로를 확인하면 다음과 같습니다.

:~/work/test$ ll
total 12
drwxrwxr-x 2 kodkod kodkod 4096 Sep 25 05:10 ./
drwxrwxr-x 4 kodkod kodkod 4096 Sep 30 04:26 ../
-rw-rw-r-- 1 kodkod kodkod   22 Sep 23 05:19 while_loop.py

위와 같이 ~/work/test 경로를 컨테이너로 연결해보겠습니다.

-v {호스트경로}:{컨테이너경로}:{권한-rw:읽고쓰기}
$ docker run -e POSTGRES_PASSWORD=mysecretpassword -v ~/work/test:/work/test:rw -d postgres
1067212afd531515c2ddd9ed3ed12256fd41ea586f7ab3b3cd9f6830ad4021d4

위 명령어와 같이 v옵션으로 호스트상의 경로와 컨테이너 상 경로를 연결할 수 있습니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS      NAMES
1067212afd53   postgres   "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   5432/tcp   elastic_neumann

작동중인 컨테이너를 확인하면 위와 같이 잘 작동 되는 것을 알 수 있습니다.

$ docker exec -it 1067212afd53 /bin/bash

root@1067212afd53:/# ls
bin  boot  dev  docker-entrypoint-initdb.d  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  work

root@1067212afd53:/# cd work/
root@1067212afd53:/work# ls
test
root@1067212afd53:/work# cd test/
root@1067212afd53:/work/test# ls
while_loop.py


root@1067212afd53:/work/test# mkdir inside
root@1067212afd53:/work/test# ls
inside  while_loop.py
root@1067212afd53:/work/test# exit
exit
:~/work/test$ ls
inside  while_loop.py

위 코드와 같이 컨테이너 안에서 디렉토리를 생성했는데, 호스트에도 디렉토리가 생성된 것을 알 수 있습니다.

2.6. 도커 볼륨(volume)

이번 절에서는 도커 볼륨을 이용해 데이터를 보존해보겠습니다.

~$ docker volume ls
DRIVER    VOLUME NAME

우선 도커 볼륨을 조회해 보겠습니다. 위 코드를 입력하면 아무것도 안나오는 것을 알 수 있습니다.

$ docker volume create myvolume01
myvolume01

$ docker volume ls
DRIVER    VOLUME NAME
local     myvolume01

위 코드를 입력하면 도커 볼륨을 생성할 수 있습니다.

$ docker volume inspect myvolume01
[
    {
        "CreatedAt": "2022-10-03T05:58:30Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume01/_data",
        "Name": "myvolume01",
        "Options": {},
        "Scope": "local"
    }
]

inspect 명령어를 이용하면 도커 볼륨의 상세정보를 확인할 수 있습니다.

$ docker run -e POSTGRES_PASSWORD=mysecretpassword -v myvolume01:/var/lib/postgresql/data -d postgres
442f74a72312f42d5fda6f181eb9f8ca098d171bab88b2882b3726c09007ab15

그러면 이제 도커 볼륨을 붙여서 컨테이너를 실행해봅시다. 참고로 컨테이너 경로는 /var/lib/postgresql/data지정해야 하는데, 이는 postgreSQL 데이터가 저장되는 경로입니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS      NAMES
442f74a72312   postgres   "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds   5432/tcp   wizardly_fermat

그러면 위와 같이 컨테이너가 제대로 실행된 것을 볼 수 있습니다.

$ docker exec -it 442f74a72312 /bin/bash

root@442f74a72312:/# psql -U postgres
psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

postgres=# CREATE USER cheolwon PASSWORD '1234' SUPERUSER;
CREATE ROLE
postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 cheolwon  | Superuser                                                  | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \q
root@442f74a72312:/# exit
exit

그럼 이제 데이터가 유지가 되는지 보겠습니다. 위 코드와 같이 컨테이너 내부로 들어가 cheolwon이라는 role을 추가하겠습니다. 그리고 빠져나온후 컨테이너를 내리고 다른 이미지로 컨테이너를 띄운후, 데이터가 여전히 살아있는지 확인해보겠습니다.

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS              PORTS      NAMES
442f74a72312   postgres   "docker-entrypoint.s…"   About a minute ago   Up About a minute   5432/tcp   wizardly_fermat

먼저 컨테이너가 살아있음을 확인하고,

$ docker container stop 442f74a72312
442f74a72312

그리고 컨테이너를 정지시킵니다.

~$ docker run -e POSTGRES_PASSWORD=mysecretpassword -v myvolume01:/var/lib/postgresql/data -d postgres
81ab16812bcb769bb3c6500ab6d1a1284673a8fb1c5f1731153a74ea2e6c0d51

$ docker container ls
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS      NAMES
81ab16812bcb   postgres   "docker-entrypoint.s…"   3 seconds ago   Up 3 seconds   5432/tcp   zen_golick

그리고나서 다른 컨테이너를 띄웁니다.

~$ docker exec -it 81ab16812bcb /bin/bash

root@81ab16812bcb:/# psql -U postgres
psql (14.5 (Debian 14.5-1.pgdg110+1))
Type "help" for help.

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 cheolwon  | Superuser                                                  | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \q
root@81ab16812bcb:/# exit
exit

그리고나서 컨테이너 내부로 들어간 후, role을 확인해보면 여전히 cheolwon이라는 롤이 유지되는 것을 볼 수 있습니다.