[Infra] 도커(docker)(9) 도커 PostgreSQL 컨테이너 배포하기
업데이트:
도커(docker)(9) 도커 PostgreSQL 컨테이너 배포하기
참고링크
참고 링크
- (0)도커의 개념
- (1)도커 설치하기, hello world!
- (2)도커 컨테이너 조작 기초(pull, run, ps)
- (3)도커 이미지 변경 후 저장(commit)
- (4)도커 컨테이너 네트워크
- (5)도커 API 이미지 빌드 및 컨테이너 실행
- (6)도커 컴포즈를 활용한 여러 개의 Flask, Nginx 배포
- (7)도커 볼륨을 이용한 데이터 관리
- (8)도커 장고 이미지 살펴보기
- (9)도커 PostgreSQL 컨테이너 배포
- (1)쿠버네티스 구조
- (2)쿠버네티스 설치
- (3)쿠버네티스 서비스 배포하기
- (4)컨테이너 IP와 파드 IP의 관계
- (5)퍼시스턴트 볼륨 스토리지
- (6)쿠버네티스 에러 메시지
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이라는 롤이 유지되는 것을 볼 수 있습니다.