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
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io