컨테이너와 Docker (4) - commit - volume mount - 데이터 저장

Share

Last Updated on 10월 31, 2021 by Jade(정현호)



안녕하세요
이번 포스팅에서는 Docker commit, 실행시 환경 변수(env) 사용, 데이터 저장을 위한  volume mount 을 확인 해보도록 하겠습니다.


아래 포스팅에서 이어지는 글입니다.

     

Docker commit

docker commit 명령어는 컨테이너의 현재 상태 다른 도커 이미지로 생성합니다

컨테이너 내부에 새로운 라이브러리나 패키지를 설치하거나 설정을 변경하거나 파일을 추가하는 등의 변경사항이 있다면, 이를 반영한 이미지를 생성할 수 있습니다.


httpd 컨테이너 시작

먼저 테스트를 위해서 apache 컨테이너 1개를 실행 하도록 하겠습니다.

-- myhttpd-1 이름으로 실행
[devops@docker1 ~]$ docker run -d --name myhttpd-1 httpd:2.4


-- myhttpd-1 컨테이너 진입
[devops@docker1 ~]$ docker exec -it myhttpd-1 /bin/bash



테스트를 위해 패키지 몇개 와 파일을 편집을 하도록 하겠습니다.

-- apt repository update
root@684887b9fbcf:/usr/local/apache2# apt update

-- 패키지 설치
root@684887b9fbcf:/usr/local/apache2# apt install vim net-tools

-- 파일 수정
root@684887b9fbcf:/usr/local/apache2# cd htdocs
root@684887b9fbcf:/usr/local/apache2/htdocs# vim index.html 

<html><body><h1>It works! - Custom Page</h1></body></html>


root@684887b9fbcf:/usr/local/apache2/htdocs# exit


-- 파일 수정
[devops@docker1 ~]$ curl http://172.17.0.2
<html><body><h1>It works! - Custom Page</h1></body></html>




컨테이너 재시작

그 다음 컨테이너를 재시작 하여 변경 사항을 확인 해보도록 하겠습니다.
 

-- 정지
[devops@docker1 ~]$ docker stop myhttpd-1
myhttpd-1

-- 재시작
[devops@docker1 ~]$ docker restart myhttpd-1
myhttpd-1


[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND              CREATED          STATUS          PORTS     NAMES
684887b9fbcf   httpd:2.4   "httpd-foreground"   25 minutes ago   Up 23 seconds   80/tcp    myhttpd-1


-- curl로 접속 하여 내용 확인
[devops@docker1 ~]$ curl http://172.17.0.2
<html><body><h1>It works! - Custom Page</h1></body></html>


-- 컨테이너로 진입
[devops@docker1 ~]$ docker exec -it myhttpd-1 /bin/bash


-- 설치하였던 패키지 확인
root@684887b9fbcf:/usr/local/apache2# which vi
/usr/bin/vi


-- 설치하였던 패키지 확인
root@684887b9fbcf:/usr/local/apache2# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 16  bytes 1218 (1.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 640 (640.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


root@684887b9fbcf:/usr/local/apache2# exit

 

위에서 확인 한것 처럼 도커 컨테이너의 정지(stop) 후 재시작의 경우는 기존의 변경사항이 유지되는 것을 확인 할 수 있습니다.



컨테이너 종료 후 시작

이번에는 위에서 작업한 컨테이너 를 종료(rm) 를 한 후 다시 시작(run) 하겠습니다.

- 컨테이너 확인
[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND              CREATED          STATUS         PORTS     NAMES
684887b9fbcf   httpd:2.4   "httpd-foreground"   27 minutes ago   Up 2 minutes   80/tcp    myhttpd-1

-- 컨테이너 stop
[devops@docker1 ~]$ docker stop myhttpd-1
myhttpd-1



[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS                     PORTS     NAMES
684887b9fbcf   httpd:2.4   "httpd-foreground"       27 minutes ago   Exited (0) 2 seconds ago             myhttpd-1


-- 컨테이너 rm
[devops@docker1 ~]$ docker rm myhttpd-1
myhttpd-1


-- 컨테이너 시작
[devops@docker1 ~]$ docker run -d --name myhttpd-2 httpd:2.4
b08f824a008a11238cb9aa13a8852fbbb62dac40b58c5aa8160a7a2ae87474ab


-- 컨테이너 안으로 진입
[devops@docker1 ~]$ docker exec -it myhttpd-2 /bin/bash

-- 위에서 변경한 내용 재확인 : 도커 이미지로 원복
root@b08f824a008a:/usr/local/apache2# cat htdocs/index.html 
<html><body><h1>It works!</h1></body></html>

-- 위에서 변경한 내용 재확인 : 도커 이미지로 원복
root@b08f824a008a:/usr/local/apache2# which ifconfig
root@b08f824a008a:/usr/local/apache2# which vim



이번에는 컨테이너를 rm 으로 삭제(종료) 후 다시 다른 이름으로 시작(run) 하였습니다. 그 다음 컨테이너 안에서 이전에 변경을 진행한 내역에 대해서 확인을 하였습니다.

이전 포스팅에서 언급한 도커의 특성의 휘발성과 관련된 내용으로 도커 컨테이너를 정지 또는 삭제 를 하게 되면 변경한 내용도 같이 사라지게 되게 됩니다. 그래서 기존 컨테이너 이미지에서 무엇인가 변경이나 파일등의 추가 등의 변경을 하였고 이 내용이 계속 지속되길 바란다면 commit 을 통해 컨테이너 이미지에 반영을 해야 합니다.



Docker commit 명령어

처음에 설명 한 내용처럼 docker commit 명령어는 컨테이너의 현재 상태 다른 도커 이미지로 생성합니다

컨테이너 내부에 새로운 라이브러리나 패키지를 설치하거나 설정을 변경하거나 파일을 추가하는 등의 변경사항이 있다면, 이를 반영한 이미지를 생성할 수 있습니다.


명령어 사용법은 아래와 같습니다. [container] 는 생략 가능 합니다.
docker [container] commit <옵션> <참조(Source)컨테이너 이름> < 새로운이미지 이름>:<태그>


확인을 위하여 이전 단계에서 실행한 컨테이너에 몇가지 패키지를 설치 후 진행하겠습니다.

-- 컨테이너 안으로 진입
[devops@docker1 ~]$ docker exec -it myhttpd-2 /bin/bash

-- 다시 설치
root@b08f824a008a:/usr/local/apache2# apt update

root@b08f824a008a:/usr/local/apache2# apt -y install vim wget net-tools

root@b08f824a008a:/usr/local/apache2# exit


[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND              CREATED          STATUS          PORTS     NAMES
b08f824a008a   httpd:2.4   "httpd-foreground"   13 minutes ago   Up 13 minutes   80/tcp    myhttpd-2


-- Docker commit 실행
[devops@docker1 ~]$ docker commit \
-a "hyunho Jung<admin@hoing.io>" \
myhttpd-2 webhoing:1.0
sha256:55784344ce1b07e8d7bb3d49c8b12af00f41c18235e5f2e7de703dba9cd02794


[devops@docker1 ~]$ docker images
REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
webhoing                  1.0       55784344ce1b   13 seconds ago   193MB
httpd                     2.4       30287d899656   2 weeks ago      138MB


-- Author 정보 확인
[devops@docker1 ~]$ docker inspect -f {{.Author}} 55784344ce1b
hyunho Jung<admin@hoing.io>


이번에 commit 명령어 사용시 에는 -a 를 통해 컨테이너 이미지 작성자(author) 정보도 추가를 하였으며 docker inspect 를 통해 확인 할 수 있습니다.


commit 을 통해 생성한 컨테이너 이미지를 실행 후 이전의 변경 사항이 저장이 되어있는지 확인 해보도록 하겠습니다.

-- docker 시작 
[devops@docker1 ~]$ docker run -d webhoing:1.0


[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE          COMMAND              CREATED          STATUS          PORTS     NAMES
ea68b6b7614a   webhoing:1.0   "httpd-foreground"   16 seconds ago   Up 15 seconds   80/tcp    quizzical_mcnulty
750474222b22   httpd:2.4      "httpd-foreground"   3 minutes ago    Up 3 minutes    80/tcp    myhttpd-2


-- 컨테이너 안으로 진입
[devops@docker1 ~]$ docker exec -it quizzical_mcnulty /bin/bash


-- 추가된 패키지 확인
root@ea68b6b7614a:/usr/local/apache2# which vi
/usr/bin/vi


-- 추가된 패키지 확인
root@ea68b6b7614a:/usr/local/apache2# which ifconfig
/sbin/ifconfig


-- 추가된 패키지 확인
root@ea68b6b7614a:/usr/local/apache2# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 
이와 같이 사용중인 컨테이너 내에 데몬의 설정 변경이나 파일의 변경 등을 진행 후 다른 서버에도 반영하는 등의 이유로 영구적으로 반영이 필요할 경우 commit 을 통해 이미지를 저장 하면 됩니다.


Volume Mount

Docker 컨테이너의 데이터를 영속적으로 저장할 수 있는 기능과 관련된 Volume Mount 에 대해서 설명 드리도록 하겠습니다.


이미지 다운로드 및 실행

Volume Mount 를 테스트 및 확인 하기 위해서 먼저 MySQL 도커 이미지의 다운로드 및 컨테이너 실행을 진행합니다 포스팅에서는 5.7 버전을 이용 하였습니다.

-- 도커 이미지 다운로드
[devops@docker1 ~]$ docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists 
a462b60610f5: Pull complete 
578fafb77ab8: Pull complete 
524046006037: Pull complete 
d0cbe54c8855: Pull complete 
aa18e05cc46d: Pull complete 
32ca814c833f: Pull complete 
52645b4af634: Pull complete 
bca6a5b14385: Downloading [================================>                  ]  70.94MB/108.2MB
309f36297c75: Download complete 
7d75cacde0f8: Download complete 


-- 도커 실행
[devops@docker1 ~]$ docker run -d mysql:5.7


-- 도커 프로세스 상태 조회
[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS                      PORTS     NAMES
c086d445a7a8   mysql:5.7   "docker-entrypoint.s…"   47 seconds ago   Exited (1) 46 seconds ago             dreamy_perlman


STATUS 가 Exit 로 확인되며 실행한 컨테이너는 종로되었습니다 왜 그런것인지 확인 해봐야 합니다. 이전에는 백그라운드로 실행하였기 때문에, run 할때 이번에는 foreground 로 하거나 이미 실행한(종료된) 컨테이너의 로그를 살펴볼수도 있습니다. 


Docker logs

docker를 백그라운드 실행시 발생되는 에러 또는 warning 이나 로그 내역은 logs 옵션을 통해서 확인 할 수 있습니다.

logs 옵션을 통해서 실행 로그를 살펴 보겠습니다.

[devops@docker1 ~]$ docker logs c086d445a7a8
2021-07-10 18:47:43+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.
2021-07-10 18:47:43+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-07-10 18:47:43+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.34-1debian10 started.
2021-07-10 18:47:43+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD


위와 같이 도커 이미지 별로 실행시 별도의 인자값이나 환경정보가 필요로 할 수 있습니다. 위의 MySQL 5.7 컨테이너는 실행하기 위해서 root 유저의 패스워드 관련된 변수 3개 중에 1개는 지정해야 한다고 로그에서 확인 할 수 있습니다.


Docker env

그럼 로그에서 확인 한 대로 3개의 변수 중 한개를 지정하여 컨테이너를 실행해보도록 하겠습니다. env 옵션을 사용 하면 됩니다.

-- env 옵션을 사용하여 컨테이너 실행
[devops@docker1 ~]$ docker run -d --name mydb --env MYSQL_ROOT_PASSWORD='mypass!@#' mysql:5.7
f42e3fbc8e9013439b8e12198471f165db00269f2797418a082bab3da9212d90


-- 컨테이너 상태 정보
[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS                      PORTS                 NAMES
f42e3fbc8e90   mysql:5.7   "docker-entrypoint.s…"   8 seconds ago    Up 6 seconds                3306/tcp, 33060/tcp   mydb  <---
f3a7df54c26b   mysql:5.7   "docker-entrypoint.s…"   27 minutes ago   Exited (1) 27 minutes ago                         optimistic_mahavira


컨테이너 실행이름을 mydb로 지정한 컨테이너를 실행 하였고 이전과는 다르게 계속 실행중인 것을 확인 할 수 있습니다. 도커 이미지 마다 생성시 지정한 필요한 인자값(변수) 입니다 포스팅에서는 MYSQL_ROOT_PASSWORD 를 지정하여 실행 하였으며 --env 옵션이 사용됩니다.


그럼 정상적으로 사용 가능한지 컨테이너에 들어가서 데이터를 입력해 보도록 하겠습니다.

-- 컨테이너로 진입
[devops@docker1 ~]$ docker exec it mydb1 /bin/bash


-- MySQL 접속
root@cf9bd9b4a328:/var/lib/mysql# mysql -u root -p
Enter password: 
( 컨테이너 실행시 지정한 패스워드 입력 - 포스팅에서는 mypass!@#  )

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.34 MySQL Community Server (GPL)
-- 포스팅시점에서 5.7버전은 5.7.34 가 설치 됨

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 


-- 데이터베이스 생성
mysql> create database test;


-- 데이터베이스 조회
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+


-- 데이터베이스 선택
mysql> use test;


-- 테이블 생성 및 데이터 입력
mysql> create table tb_test
(
    id int not null,
    primary key(id)
);

mysql> insert into tb_test values(1);


-- 위에서 입력한 1건 데이터가 있음을 확인
mysql> select * from tb_test;
+----+
| id |
+----+
|  1 |
+----+


이 처럼 실행시 옵션이나 필요한 환경변수가 있는 도커 이미지의 경우는 필요한 옵션 인자 등을 사용해야 합니다.


docker inspect

위에서 실행한 MySQL의 이미지 정보를 한번 살펴보면 아래와 같은 부분을 확인 할 수 있습니다.

[devops@docker1 ~]$ docker images 
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        5.7       09361feeb475   2 weeks ago    447MB


[devops@docker1 ~]$ docker image inspect 09361feeb475 -f {{.Config.Volumes}}
map[/var/lib/mysql:{}]


[devops@docker1 ~]$ docker image inspect 09361feeb475 -f {{.ContainerConfig.Volumes}}
map[/var/lib/mysql:{}]


[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES
cf9bd9b4a328   mysql:5.7   "docker-entrypoint.s…"   7 minutes ago   Up 7 minutes   3306/tcp, 33060/tcp   mydb1


-- Container Inspect
[devops@docker1 ~]$ docker inspect cf9bd9b4a328
< ... 중략 ...>
 "Mounts": [
            {
                "Type": "volume",
                "Name": "125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989",
                "Source": "/var/lib/docker/volumes/125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
< ... 중략 ...>



위의 에서 볼 수 있듯이 MySQL 이미지의 설정된 내역에서 Volume Mount 에 대한 설정 내역을 확인 할 수 있으며 실행된 컨테이너의 정보에서도 Source 정보 와 Destination mount 정보를 알 수 있습니다. MySQL 이나 다른 도커 이미지에서는 기본으로 Volume 이 설정되어 사용 되는 경우가 있습니다. 


별도의 위치와 volume 명이 기재되어있지 않았기 때문에 위치는 /var/lib/docker/volumes 아래 생성되게 됩니다. 그리고 volume 정보와 실제 디렉토리를 조회하면 아래와 같이 파일 등이 확인이 됩니다. volume 이 2개 보이는 이유는 env 변수 없이 실행한 MySQL 컨테이너(바로 종료된) 와 현재 실행중인 MySQL 컨테이너 2개에 대한 volume 입니다.

[devops@docker1 ~]$ docker volume ls
DRIVER    VOLUME NAME
local     1f2c629c5c7a0de36d6fdf158974718d5cf9bd43c189b83359322a7e89b67a28
local     125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989


[devops@docker1 ~]$ docker volume inspect 125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989
[
    {
        "CreatedAt": "2021-07-11T03:28:32+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989/_data",
        "Name": "125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989",
        "Options": null,
        "Scope": "local"
    }
]


[devops@docker1 ~]$ sudo ls -al /var/lib/docker/volumes/125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989/_data
total 188484
drwxrwxrwt 5 polkitd input      328 Jul 11 03:28 .
drwx-----x 3 root    root        19 Jul 11 03:28 ..
-rw-r----- 1 polkitd input       56 Jul 11 03:28 auto.cnf
-rw------- 1 polkitd input     1676 Jul 11 03:28 ca-key.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 ca.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 client-cert.pem
-rw------- 1 polkitd input     1680 Jul 11 03:28 client-key.pem
-rw-r----- 1 polkitd input     1359 Jul 11 03:28 ib_buffer_pool
-rw-r----- 1 polkitd input 79691776 Jul 11 03:28 ibdata1
-rw-r----- 1 polkitd input 50331648 Jul 11 03:28 ib_logfile0
-rw-r----- 1 polkitd input 50331648 Jul 11 03:28 ib_logfile1
-rw-r----- 1 polkitd input 12582912 Jul 11 03:28 ibtmp1
drwxr-x--- 2 polkitd input     4096 Jul 11 03:28 mysql
drwxr-x--- 2 polkitd input     8192 Jul 11 03:28 performance_schema
-rw------- 1 polkitd input     1680 Jul 11 03:28 private_key.pem
-rw-r--r-- 1 polkitd input      452 Jul 11 03:28 public_key.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 server-cert.pem
-rw------- 1 polkitd input     1680 Jul 11 03:28 server-key.pem
drwxr-x--- 2 polkitd input     8192 Jul 11 03:28 sys
drwxr-x--- 2 polkitd input       58 Jul 11 03:30 test



Volume Mount 를 사용하였기 때문에 Host OS의 Local 영역을 컨테이너에서 Mount 하여 사용하게 되며 별도의 volume 명을 지정하지 않았기 때문에 local 이라고 표기 되어 있습니다.


그럼 컨테이너를 2개 실행 해보도록 하겠습니다.

[devops@docker1 ~]$ docker run -d --name mydb2 \
--env MYSQL_ROOT_PASSWORD='mypass!@#' mysql:5.7


[devops@docker1 ~]$ docker run -d --name mydb3 \
--env MYSQL_ROOT_PASSWORD='mypass!@#' mysql:5.7


[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS                 NAMES
0a6dd0ca212c   mysql:5.7      "docker-entrypoint.s…"   6 seconds ago    Up 5 seconds                3306/tcp, 33060/tcp   mydb3
2f5eadcbdb1a   mysql:5.7      "docker-entrypoint.s…"   9 seconds ago    Up 8 seconds                3306/tcp, 33060/tcp   mydb2
cf9bd9b4a328   mysql:5.7      "docker-entrypoint.s…"   19 minutes ago   Up 19 minutes               3306/tcp, 33060/tcp   mydb1
c086d445a7a8   mysql:5.7      "docker-entrypoint.s…"   25 minutes ago   Exited (1) 25 minutes ago                         dreamy_perlman



2개를 더 실행하였습니다. volume 정보를 확인 해보도록 하겠습니다. 위에서 확인 한것 처럼 컨테이너 별로 volume 이 생성이 되고 있습니다.

[devops@docker1 ~]$ docker volume ls
DRIVER    VOLUME NAME
local     1f2c629c5c7a0de36d6fdf158974718d5cf9bd43c189b83359322a7e89b67a28
local     125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989
local     1976793c58cd0fafec197ba38cf73e8eb4eba275c33ea4e1a15d579b1401f39e
local     3298102e50427584b152fb6cd053d968ef6de43c4d877476fd3a46d6fc2c3512



컨테이너 중지 및 삭제

그럼 위에서 실행한 MySQL 컨테이너 모두를 정지 및 삭제 하도록 하겠습니다.

[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS                 NAMES
0a6dd0ca212c   mysql:5.7      "docker-entrypoint.s…"   3 minutes ago    Up 3 minutes                3306/tcp, 33060/tcp   mydb3
2f5eadcbdb1a   mysql:5.7      "docker-entrypoint.s…"   3 minutes ago    Up 3 minutes                3306/tcp, 33060/tcp   mydb2
cf9bd9b4a328   mysql:5.7      "docker-entrypoint.s…"   22 minutes ago   Up 22 minutes               3306/tcp, 33060/tcp   mydb1
c086d445a7a8   mysql:5.7      "docker-entrypoint.s…"   28 minutes ago   Exited (1) 28 minutes ago                         dreamy_perlman


[devops@docker1 ~]$ docker rm -f 0a6dd0ca212c 2f5eadcbdb1a cf9bd9b4a328 c086d445a7a8
0a6dd0ca212c
2f5eadcbdb1a
cf9bd9b4a328
c086d445a7a8


[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES



이제 다시 volume 를 조회해보도록 하겠습니다. 도커 컨테이너를 중지 및 삭제를 하였지만 volume 은 여전히 남아 있습니다.

[devops@docker1 ~]$ docker volume ls
DRIVER    VOLUME NAME
local     1f2c629c5c7a0de36d6fdf158974718d5cf9bd43c189b83359322a7e89b67a28
local     125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989
local     1976793c58cd0fafec197ba38cf73e8eb4eba275c33ea4e1a15d579b1401f39e
local     3298102e50427584b152fb6cd053d968ef6de43c4d877476fd3a46d6fc2c3512


[devops@docker1 ~]$ docker inspect 125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989
[
    {
        "CreatedAt": "2021-07-11T03:28:32+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989/_data",
        "Name": "125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989",
        "Options": null,
        "Scope": "local"
    }
]


[devops@docker1 ~]$ sudo ls -al /var/lib/docker/volumes/125720d1662d9fde7e1c5fe0f2c1a5f05dba16799b0a91e5f6ade29d19824989/_data
total 188484
drwxrwxrwt 5 polkitd input      328 Jul 11 03:28 .
drwx-----x 3 root    root        19 Jul 11 03:28 ..
-rw-r----- 1 polkitd input       56 Jul 11 03:28 auto.cnf
-rw------- 1 polkitd input     1676 Jul 11 03:28 ca-key.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 ca.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 client-cert.pem
-rw------- 1 polkitd input     1680 Jul 11 03:28 client-key.pem
-rw-r----- 1 polkitd input     1359 Jul 11 03:28 ib_buffer_pool
-rw-r----- 1 polkitd input 79691776 Jul 11 03:28 ibdata1
-rw-r----- 1 polkitd input 50331648 Jul 11 03:28 ib_logfile0
-rw-r----- 1 polkitd input 50331648 Jul 11 03:28 ib_logfile1
-rw-r----- 1 polkitd input 12582912 Jul 11 03:28 ibtmp1
drwxr-x--- 2 polkitd input     4096 Jul 11 03:28 mysql
drwxr-x--- 2 polkitd input     8192 Jul 11 03:28 performance_schema
-rw------- 1 polkitd input     1680 Jul 11 03:28 private_key.pem
-rw-r--r-- 1 polkitd input      452 Jul 11 03:28 public_key.pem
-rw-r--r-- 1 polkitd input     1112 Jul 11 03:28 server-cert.pem
-rw------- 1 polkitd input     1680 Jul 11 03:28 server-key.pem
drwxr-x--- 2 polkitd input     8192 Jul 11 03:28 sys
drwxr-x--- 2 polkitd input       58 Jul 11 03:30 test



docker run volume

위에서 컨테이너를 삭제하였지만 volume 은 여전히 남아 있는 상태입니다. 해당 볼륨을 사용하여 다시 MySQL 컨테이너에서 사용하는 방법은 여러가지가 있을 수 있겠습니다.


• 파일 복사

먼저 새로운 컨테이너에 기존 파일을 복사하는 형태로 사용하는 유형을 살펴보겠습니다. MySQL 컨테이너를 새로 하나 실행을 하며, 실행시 별도의 env 를 사용하지 않고 실행하도록 하겠습니다.

[devops@docker1 ~]$ docker run -d --name mydb4 mysql:5.7
6171eef35811f0b19d3d1aa678b2004999f6e0e437d56ff711e8c233e69a1f01

[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                    PORTS     NAMES
6171eef35811   mysql:5.7      "docker-entrypoint.s…"   2 seconds ago   Exited (1) 1 second ago             mydb4



필요한 env 정보가 없기 때문에 바로 실행 종료가 되었습니다. 종료가 되었으나 한번 실행이 되었기 때문에 컨테이너가 남아있으며, 해당 컨테이너가 실행되면서 사용한 볼륨도 있을 것 입니다.  조회를 해보면 아래와 같이 경로를 확인 할 수 있습니다.

[devops@docker1 ~]$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                    PORTS     NAMES
6171eef35811   mysql:5.7      "docker-entrypoint.s…"   2 seconds ago   Exited (1) 1 second ago             mydb4


[devops@docker1 ~]$ docker inspect 6171eef35811 -f {{.Mounts}}
[{volume d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9 
/var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data 
/var/lib/mysql local  true }]

* 가로 길이에 따라서 개행을 하였습니다.


해당 경로에는 실행되면서 생성된 mysql data 파일이 있을 것 입니다. 해당 파일을 삭제 후 데이터파일을 복사 하도록 하겠습니다 그 다음 restart 를 통해 재시작하여 이전에 생성한 데이터가 존재 하는지 확인 하도록 하겠습니다.

-- 신규 생성한 컨테이너의 volume 에서 파일 삭제
sudo rm -rf /var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data/*

-- 이전 mydb1 의 volume 에서 파일 copy
sudo cp -rp /var/lib/docker/volumes/6e329e868303aea64b0e0b1c154b3e4ae19116b5b0ad883f0f4bd113389e3488/_data/* \
/var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data/


-- 컨테이너 재시작(restart)
[devops@docker1 ~]$ docker restart mydb4
mydb4


-- 실행 되고 있음
[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES
6171eef35811   mysql:5.7   "docker-entrypoint.s…"   4 minutes ago   Up 3 seconds   3306/tcp, 33060/tcp   mydb4


-- 컨테이너로 진입
[devops@docker1 _data]$ docker exec -it mydb4 /bin/bash


-- MySQL 접속
root@6171eef35811:/# mysql -u root -p
Enter password: 
( 컨테이너 실행시 지정한 패스워드 입력 - 포스팅에서는 mypass!@#  )

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed


-- 데이터 조회
mysql> select * from tb_test;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)


이와 같이 호스트 OS에서 볼륨 간의 파일 copy 를 통해서 복구 형태로 기존의 볼륨의 파일을 사용할 수도 있습니다.



• Volume 공유

컨테이너가 가지고 있는 볼륨을 다른 컨테이너와 공유 할 수도 있습니다.

다른 컨테이너와 공유는 --volume-from 을 통해서 할 수 있으며 컨테이너가 존재 해야 합니다.
테스트로 사용할 mydb4 컨테이너는 존재 함으로 --volume-from 을 통해서 새로운 컨테이너를 실행하도록 하겠습니다.

--  --volumes-from 를 통해 mydb5 이름으로 컨테이너 실행
[devops@docker1 _data]$ docker run -d --volumes-from  mydb4 --name mydb5 mysql:5.7
e087af34e936c4645867cf85deb8d0af53e6ece44066b7219ee6cd08c77b43cc

[devops@docker1 _data]$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES
e087af34e936   mysql:5.7   "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   3306/tcp, 33060/tcp   mydb5



실행은 정상적으로 되었습니다 새로 생성한 컨테이너와 기존 컨테이너가 동일한 volume 을 사용하는 지 확인 해보겠습니다.

[devops@docker1 ~]$ docker inspect mydb4 -f {{.Mounts}}
[{volume d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9
/var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data
/var/lib/mysql local  true }]

[devops@docker1 ~]$ docker inspect mydb5 -f {{.Mounts}}
[{volume d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9 
/var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data 
/var/lib/mysql local  true }]

* 가로 길이에 의해서 개행 되어있습니다.


2개의 컨테이너에 등록된 volume 경로가 같은 것을 확이 할 수 있습니다. 그 다음 MySQL 에 접속하여 기존 데이터가 있는지 확인 해보도록 하겠습니다.

[devops@docker1 ~]$ docker stop mydb5
mydb5

[devops@docker1 ~]$ docker exec -it mydb5 /bin/bash

root@e087af34e936:/# mysql -u root -p
Enter password: 
( 컨테이너 실행시 지정한 패스워드 입력 - 포스팅에서는 mypass!@#  )
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from tb_test;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)


이전에 입력하였던 데이터가 정상적으로 확인되고 있습니다.



• docker-compose

Docker Compose 는 뒤에서 자세히 설명하겠지만 다중 컨테이너 애플이케이션을 정의하여 사용할 수 있는 도구 입니다. Docker Compose 를 기존 볼륨을 사용하는 방법은 간략 하게 아래와 같은 순서로 진행하면 됩니다.

먼저 docker-compose.yaml 파일을 생성하여 파일안에 아래 내용을 입력 합니다.

version: "3.7"
services:
  db:
    image: mysql:5.7
    restart: always
    command: --lower_case_table_names=1
    container_name: mydb6 # 컨테이너 이름
    environment: # -e 옵션
      - MYSQL_ROOT_PASSWORD='mypass!@#'
      - TZ=Asia/Seoul
    command: # 명령어 실행
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - /var/lib/docker/volumes/d95a0c665baf09695d96b1f63b01d96ead3f3df9871a6c64e1d533a442f939f9/_data:/var/lib/mysql 
      # -v 옵션 (다렉토리 마운트 설정)

* 파일의 들여쓰기를 지켜야 합니다.


그 다음 위에서 작성한 compose 파일을 통해서 컨테이너를 기동 합니다.

[devops@docker1 work]$ docker-compose up -d
Creating network "work_default" with the default driver
Creating mydb6 ... done

[devops@docker1 work]$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES
ec69fa41b5b5   mysql:5.7   "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   3306/tcp, 33060/tcp   mydb6



컨테이너 기동이 완료 되었으며 데이터가 조회되는지 확인 해보도록 하겠습니다.

devops@docker1 work]$ docker exec -it mydb6 /bin/bash

root@ec69fa41b5b5:/# mysql -u root -p
Enter password: 
( 컨테이너 실행시 지정한 패스워드 입력 - 포스팅에서는 mypass!@#  )
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed


-- 데이터 조회
mysql> select * from tb_test;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)



기존 볼륨을 통해서 정상적으로 데이터가 조회가 가능함을 확인 하였습니다.  

이와 같은 방법 이외 볼륨을 사용하는 방법은 다양하게 있을 것 입니다. volume 을 사용하면 호스트OS에 파일이 존재 하기 때문에 실수로 컨테이너를 삭제하여도 데이터가 유지가 될수 있으며, 위의 예시 처럼 다른 컨테이너에서 사용 한다던지, 호스트 OS 에서 바로 파일을 복사하는 등으로 사용 할 수 있습니다.



사용자 정의 Volume 경로

MySQL 컨테이너 생성시 /var/lib/docker 기본 경로 외 다른 경로를 사용할 수 있습니다 먼저 사용할 디렉토리를 생성 하도록 하겠습니다.

[devops@docker1 ~]$ sudo mkdir -p /var/dbdata1



• 컨테이너 실행 mount 사용

컨테이너 실행시 --volume 옵션을 사용하여 실행을 합니다.

[devops@docker1 ~]$ docker run -d --name mydb7 \
--volume=/var/dbdata1:/var/lib/mysql \
--env MYSQL_ROOT_PASSWORD='mypass!@#' mysql:5.7

[devops@docker1 ~]$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES
58d6b5667580   mysql:5.7   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   3306/tcp, 33060/tcp   mydb7


[devops@docker1 ~]$ cd /var/dbdata1
[devops@docker1 dbdata1]$ ls -al
total 188488
drwxr-xr-x   5 polkitd root       328 Jul 12 04:32 .
drwxr-xr-x. 23 root    root      4096 Jul 12 04:31 ..
-rw-r-----   1 polkitd input       56 Jul 12 04:32 auto.cnf
-rw-------   1 polkitd input     1676 Jul 12 04:32 ca-key.pem
-rw-r--r--   1 polkitd input     1112 Jul 12 04:32 ca.pem
-rw-r--r--   1 polkitd input     1112 Jul 12 04:32 client-cert.pem
-rw-------   1 polkitd input     1680 Jul 12 04:32 client-key.pem
-rw-r-----   1 polkitd input     1359 Jul 12 04:32 ib_buffer_pool
-rw-r-----   1 polkitd input 79691776 Jul 12 04:32 ibdata1
-rw-r-----   1 polkitd input 50331648 Jul 12 04:32 ib_logfile0
-rw-r-----   1 polkitd input 50331648 Jul 12 04:32 ib_logfile1
-rw-r-----   1 polkitd input 12582912 Jul 12 04:32 ibtmp1
drwxr-x---   2 polkitd input     4096 Jul 12 04:32 mysql
drwxr-x---   2 polkitd input     8192 Jul 12 04:32 performance_schema
-rw-------   1 polkitd input     1676 Jul 12 04:32 private_key.pem
-rw-r--r--   1 polkitd input      452 Jul 12 04:32 public_key.pem
-rw-r--r--   1 polkitd input     1112 Jul 12 04:32 server-cert.pem
-rw-------   1 polkitd input     1680 Jul 12 04:32 server-key.pem
drwxr-x---   2 polkitd input     8192 Jul 12 04:32 sys



--volume 에서 사용한 인자의 의미는 아래와 같습니다.

/var/dbdata1:/var/lib/mysql
로컬디렉토리경로:도커내 데이터파일 경로

컨테이너 실행시 지정한 로컬 경로에 파일이 생성이 되는 것을 확인 할 수 있습니다.


다음은 도커 이미지 이동, 생성, Docker Compose 등을 확인해보도록 하겠습니다.



Reference

Reference Link
 • docs.docker.com/commit

 • docs.docker.com/volume_create


0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x