docker exec -it -uroot db001 /bin/bash
mysql -uroot -p
mysql > create user 'exporter'@'localhost' identified by 'exporter123' with MAX_USER_CONNECTIONS 3;
mysql > grant PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
- 호스트에서 각각의 exporter 시작 쉘스크립트 실행
docker exec db001 sh /opt/exporters/node_exporter/start_node_exporter.sh
docker exec db001 sh /opt/exporters/mysqld_exporter/start_mysqld_exporter.sh
docker exec db002 sh /opt/exporters/node_exporter/start_node_exporter.sh
docker exec db002 sh /opt/exporters/mysqld_exporter/start_mysqld_exporter.sh
docker exec db003 sh /opt/exporters/node_exporter/start_node_exporter.sh
docker exec db003 sh /opt/exporters/mysqld_exporter/start_mysqld_exporter.sh
- ProxySQL : C++로 짜여진 오픈 소스 Proxy 프로그램으로 총 4개의 database schema를 가지며, Proxy를 컨트롤하고 모니터링할 수 있게 한다. - Proxy Layer를 두는 이유 :
앞서서Orchestra 설정을 해두면 Master(db001)이 샷다운 되더라도Slave(db002)이 자동으로 Master로 승격되어 고가용성, 곧 시스템이 지속될 수 있도록 할 수 있었다. 하지만, Application 입장에서는, Application의 자체 설정에 따라 기존의 Master(db001)을 계속해서 바라볼 수 있다. 이를 해결하기 위해 중간층인 Proxy Layer를 둘 수 있는데, MySql은 Proxy 프로그램으로 ProxySQL을 사용할 수 있다.
Ex. Spring Boot application-yml에서 Master를 db001로 설정해둔 경우
--> db001이 샷다운 되고 db002이 자동으로 Master가 되어도
--> Spring Boot는 여전히 db001를 Master로 인식하고 있다.
출처:https://dkswnkk.tistory.com/729
2. Docker로 Proxy SQL 생성하기
[1] proxy 디렉토리 생성 및 권한 부여
- ProxySQL 컨테이너도 MySQL 컨테이너와 마찬가지로 호스트 볼륨에 컨테이너 파일이 마운트될 수 있게 해줘야한다.
- 따라서, data 정보가 담길 data 디렉토리와 설정 정보가 담길 conf 티렉토리를 호스트에 생성해준다.
mkdir -p db/proxysql/data db/proxysql/conf
chmod 777 db/proxysql/data db/proxysql/conf
cd db/proxysql/conf
[2] proxysql.cnf 생성 후 권한을 644로 부여
- conf 디렉토리에서 proxysql 설정 파일을 만들어준다.
- mysql의 경우 my.cnf로 설정을 작성한다면, proxysql은 proxysql.cnf로 설정을 작성한다.
[4] ProxySQL 접속(호스트에서 접속하는 것으로, 이 경우 호스트에 mysql 있어야함)
- 여기서 살짝 헤맸는데, 호스트에서 ProxySQL에 직접적으로 접속하기 위해서는 먼저 호스트 OS안에 mysql이 별도로 설치가 되어 있어야 한다. (나는 없었어서 아래 명령어가 에러가 남..)
- MySQL을 설치하고, 아래 명령어를 입력하면 ProxySQL에 접속이 가능하다.
mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"
3. Proxy Layer 테스트해보기
[1] 먼저 Master 컨테이너 db001에서 테스트 데이버테이스와, 어플리케이션용 user, proxysql용 모니터링 user를 생성한다.
docker exec -it -uroot db001 /bin/bash
mysql -uroot -p
mysql > create user 'appuser'@'%' identified by 'apppass';
mysql > create database testdb default character set utf8;
mysql > grant select, insert, update, delete on testdb.* to 'appuser'@'%'
mysql > create user 'monitor'@'%' identified by 'monitor';
mysql > grant REPLICATION CLIENT on *.* to 'monitor'@'%';
mysql > flush privileges;
[2] proxy에서 hostgroup에 db 서버 정보 입력
- proxysql에서 현재 상태와 맞게 쓰기그룹, 읽기 그룹을 형성하고, 쓰기그룹/읽기그룹을 나누는 기준을 global의 " read_only "로 잡아둔다. (Slave는 global=read_only임)
mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"
# 쓰기 그룹(10)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(10, 'db001', 3306);
# 읽기 그룹(20)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db001', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db002', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db003', 3306);
# 호스트 그룹 설정
# VALUES(쓰기,읽기,쓰기/읽기 구분 기준, '')
INSERT INTO mysql_replication_hostgroups
VALUES(10, 20, 'read_only', '');
# 로드
LOAD MYSQL SERVERS TO RUNTIME;
# 설정 영구적인 저장
SAVE MYSQL SERVERS TO DISK;
- ProxySQL은 아래에서 설정한 default_hostgroup=10번그룹과 연결을 시도한다.
- 10번은 쓰기그룹이며 Master를 의미하는데, 이는 시스템 상황에 따라 db001 또는 db002로 변경될 수 있다. (이때, 구분 기준은 앞서 말했듯 read_only=응/아니 를 기준으로 한다.)
INSERT INTO mysql_users(username, password, default_hostgroup, transaction_persistent)
VALUES('appuser', 'apppass', 10, 0);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
[4] proxy에서 쿼리 룰 정보 입력
- 각 호스트 그룹별로 쿼리룰을 설정해준다.
- 기본적으로 모든 쿼리는 [3]에서 설정한 default_hostgroup 인 10번으로 가도록 되어 있는데,
아래와 같이 쿼리룰을 설정하면 Select/Update시에 10번으로, Select시에 20번으로 가게된다.
- **쿼리룰 순서가 중요. 반드시 순서대로 해주어야 한다.
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(1, 1, '^SELECT.*FOR UPDATE$', 10);
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(2, 1, '^SELECT', 20);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
[5] 호스트 os 에서 연결 테스트 쉘스크립트 실행
vi app_test_conn.sh
sh app_test_conn.sh
- app_test_conn.sh : hostip주소는 hostname -i로 확인할 수 있는 공인 ip주소를 작성해줘야한다.
# !/bin/bash
while true;
do
mysql -uappuser -papppass -h{hostip 주소} -P16033 -N -e "select@@hostname,now()" 2>&1| grep -v "Warning"
sleep 1
done
[5] 호스트 os 에서 insert테스트 쉘스크립트 실행
vi app_test_insert.sh
sh app_test_insert.sh
#!/bin/bash
while true;
do
mysql -uappuser -papppass -h{{공인ip}} -P16033 -N -e "INSERT INTO testdb.insert_test VALUES ('$(hostname)', NOW())" 2>&1 | grep -v "Warning"
sleep 1
done
[6] 장애 테스트 만들기
세 개의 shell를 연 상태에서 아래와 같이 작업을 수행한다.
(1) sh app_test_insert.sh 로 insert를 지속적으로 실행한다.
(2) slave인 db002에서 읽기를 계속해서 해준다.
(3) docker stop db001로 master db를 stop 시킨다.
그리고 결과를 확인하면, db001에서 insert를 하다가, db002에서 insert를 하는 걸 볼 수 있다.
create user orc_client_user@`172.%` identified by 'orc_client_password';
GRANT SUPER, PROCESS, REPLICATION SLAVE, RELOAD ON *.* TO orc_client_user@`172.%`;
[4] Orchestrator 접속
- https://{{호스트ip}}:3000/web/clusters 로 접속한다. - clusters > discover 에 들어가서, 마스터 컨테이너명(db001) : 포트(3306) 를 입력한다.
- clusters > dashboard에 들어가면 master가 떠있고 master를 누르면 아래처럼 연결된 slave가 나타난다.
3. HA 테스트 진행하기
- read/write 모두 가능한 마스터인 db001가 갑자기 샷다운 된다고 하면
docker stop db001
- master는 리커버리가 필요한 상태가 되며 slave들은 master와 연결이 끊어짐에 따라 read가 불가능해진다.
- 이때, Recovory를 눌러 db002를 마스터로 직접 승격해주면 db002가 master가 되며 db003이 slave로 붙는걸 볼 수 있다.
- db001를 db002의 slave로 들어가도록 하려면 db001를 재실행한 후, read_only 상태로 변경, db001의 master를 db002로 설정해준다.
[root@dev opc]# docker network ls
NETWORK ID NAME DRIVER SCOPE
697ad12cd5fa bridge bridge local
d955f1181bf5 host host local
30e9346c2d17 none null local
[root@dev opc]# docker network create --driver bridge mybridge
컴퓨터 성능을 1) Scale-up 하거나, 컴퓨터를 여러대 두는 2) Scale-out이 있다.
DB로 다수의 트랜잭션이 몰리면 race condition이 발생할 수 있다.
Replication(복제)으로 Master/Slave 구조를 형성하면 DB에 가해지는 부하를 분산하여 이러한 race condition을 미연에 방지할 수 있다. 일반적으로 Master에서 write(쓰기)를 하도록 하고, Slave에서는 read(읽기)를 하도록 하여, 부하를 분산한다.
MySQL에서 Master/Slave가 동작하는 방식은 아래와 같다.
[1] Insert/Update/Delete 트랜잭션이 들어오면 Master에서 이를 처리하고 Binary Log에 변경사항을 기록한다.
출처:서버 분산 처리 환경에서 MySQL을 MasterSlave로 이중화하기(링크하단참조)
Binary Log는 my.cnf에서는 binlog라는 명칭으로 사용되는데,
MySQL에서 발생하는 모든 변경사항을 담고 있는 로그 파일을 말한다.
MySQL의 디폴트 설정값에서는 이 Binary Log가 비활성화 되어 있기 때문에 my.cnf에 binlog를 활성화해주어야한다.
my.cnf에서 binlog 설정과 관련된 내용은 아래와 같다.
# Master에서 binlog 설정을 꼭 해주어야 binlog 내용을 replica에 전달할 수 있다.
[mysqld]
log_bin=mysql-bin #binlog의 파일명을 mysql-bin으로 시작하게 설정
binlog_format=ROW #binlog의 포맷을 row로 설정 (자세한 세팅은 앞선 블로그 내용 참고)
log_slave_updates=ON #slave업데이트 여부
expire_logs_days=90 #로그 저장 시간 (지정하지 않으면 로그가 계속 쌓인다)
Docker를 통해 Master/Slave 서버 구축하기
[1] 호스트 OS에서 Master와 Slave my.cnf 파일 설정하기
db/db001, db/db002, db/db003 경로를 각각 만든 후에, 각 경로에 data, log, conf 디렉토리를 만들고, 권한을 777 준뒤,
[1] 호스트 OS에서 log,conf 파일 경로를 먼저 생성 [2] mysql 기본 설정 파일(my.cnf)을 호스트 OS의 conf 경로에 저장 * 주의 ) 이 때, my.cnf 파일의 설정값은 컨테이너를 기준으로 한다. 예를 들어, basedir=/var/lib/mysql 로 설정한다면, 이는 컨테이너의 /var/lib/mysql 경로를 의미한다. [3] 컨테이너를 재생성하며 -v 옵션을 통해 호스트 OS의 log/conf 경로와 컨테이너 log/conf 경로를연결 * my.cnf 에서 설정했던 log 경로가 곧 컨테이너 log 경로이다. 컨테이너 conf 경로는 my.cnf이 저장되는 아무 경로로 설정하면 된다.
호스트 OS에 log/conf 파일 경로 생성
기존 컨테이너는 삭제하고, 새로 data, log, config 를 저장할 경로를 생성한뒤 각 경로에 권한을 777로 설정했다.
# 경로 생성
mkdir db/db001/data db/db001/log db/db001/conf
# 권한 설정
chmod 777 db/db001/data db/db001/log db/db001/conf
호스트 OS의 config 경로에 MySQL 기본 설정 파일 생성 - my.~~
MySQL에서는 기본 설정값을 my로 시작하는 파일에 담아 둔다.
- 유닉스 계열 : my.cnf
- 윈도우 : my.ini
Docker 컨테이너에서 아래의 명령어를 치고 디폴트로 잡힌 my.cnf 파일 경로를 확인했다.
docker exec db001 mysql --help
/etc/my.cnf부터 /etc/mysql/my.cnf, /usr/etc/mysql... 경로들 중에서 어딘가에 my.cnf이 있다는 거다.
(내 컨테이너 안에서는 확인해보니 /etc/my.cnf 경로에 my.cnf 파일이 담겨 있었다.)
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
docker container 또한 앞서 말했듯 일종의 게스트 OS로 자신만의 분할 공간을 가지고 있기에, docker container 내의 파일을 열어보기 위해서는 docker container의 쉘을 열어줘야 한다. Unix 계열의 OS의 경우, sh/bash/zbash 의 쉘 종류들이 존재하는데, 그 중 bash를 사용하면 된다. docker를 exec로 실행할 때, /bin/bash를 붙이면 해당 Container의 bash쉘을 실행시키겠다는 뜻이다.
(mysql container의 mysql를 다이렉트로 실행하기 위해서는 docker exec -it {컨테이너명} mysql -uroot -p를 쓴다)
사이드로 빠진 얘기는 차치하고, 다시 /etc/my.cnf의 my.cnf 파일을 확인해보면 아래와 같다.
[root@db001 /]# cat /etc/my.cnf
#
# The Percona Server 5.7 configuration file.
#
#
# * IMPORTANT: Additional settings that can override those from this file!
# The files must end with '.cnf', otherwise they'll be ignored.
# Please make any edits and changes to the appropriate sectional files
# included below.
#
!includedir /etc/my.cnf.d/
!includedir /etc/percona-server.conf.d/
해석하면,
* 중요 : 이 파일을 통해 추가적인 세팅들을 덮어쓸 수 있다!
파일들은 항상 .cnf 확장자로 끝나야 하며, 그렇지 않으면 무시된다.
아래 경로들에 있는 부분 섹션 파일들과 같이 적절한 방식으로 작성해두어라.
!includedir /etc/my.cnf.d/
!includedir /etc/percona-server.conf.d/
하라는 대로 하기 위해서, 제시된 경로들을 확인해보니 파일이 딱 하나 있었다.
mysql 또한 하나의 소프트웨어 프로그램이기 때문에 client와 server가 존재하며,
my.cnf에 쓰는 mysql이 client 프로그램이고, mysqld가 server(=데몬) 프로그램을 의미했다.
아래의 mysqld는 그 중 서버 프로그램(이자 데몬 프로그램)을 말한다.
# /etc/my.cnf.d/docker.cnf 파일
# mysql의 background 설정
[mysqld]
skip-host-cache
skip-name-resolve
my.cnf 파일 구성하기
[ 시작 전에 - mysql의 동작 방식에 대해 간단히 살펴보기 ]
mysql은 내부적으로 클라이언트 프로그램(mysql), 서버 프로그램(mysqld)를 두며, socket을 통해 클라이언트-서버 간 양방향 통신을 한다. 이 때, socker 통신 방식으로 크게 두 가지의 방식을 사용한다. 1) TCP/IP 통신 : 서버-클라이언트가 다른 컴퓨터에 있을 때 사용 2) Unix Domain Socker 통신 : 서버-클라이언트가 같은 컴퓨터에 있을 때 mysql.sock 파일을 통해 통신 mysql를 로컬 컴퓨터에서 docker로 생성해줬기 때문에 지금 내 경우 mysql은 2)과 같이 socket 통신을 한다. 이 때 mysql.socket이 위치한 경로는 디폴트로 /var/lib/mysql/mysql.sock 이다.
mysql의 Replication(복제방식)은 여러가지가 있으며, 그 중 Async Replication은 Binary Log를 활용해 Replica를 형성한다. Slave에서는 상위(ex.Master)로부터 로그를 받아 relay log에 저장하는데, 만약 log_slave_updates 파라미터가 활성화(ON)되어 있다면 이 로그를 자신의 binlog에도 함께 기록한다.
출처:https://hoing.io/archives/3111
정말 아름답게도 my.cnf 파일의 모든 옵션을 정리해준 블로그글이 있었다(갓), 그 중에 당장 필요한 것만 뽑았는데 세밀한 옵션 설정이 필요하다면 나중에 또 이분의 글을 참고하면 도움이 될 것 같다.
# Mysql 서버 옵션
[mysqld]
server-id=1 # 서버 id값/master,slave들이 서로 달라야함
report_host=db001 # 호스트명
basedir=/var/lib/mysql # 기본 경로
datadir=/var/lib/mysql # 데이터 저장 위치
socket=/var/lib/mysql/mysql.sock # 소켓 파일 경로
log_bin=mysql-bin # binlog(서버 내 모든 변경 내역) mysql-bin.0001 형식으로 저장
binlog_format=ROW # binlog 저장 방식 - statement/row/mixed
# row : binary / statement : sql query / mixed : statement+row
log-error=/var/log/mysql/mysql.log # 에러 로그 경로
gtid_mode=ON # 트랜잭션 고유 식별자 ON
enforce-gtid-consistency=true # gtid on할 때 DDL명령어 안되는 것 강제 해제
log_slave_updates # Slave라면 ON으로 자신의 binlog에 로그 저장
symbolic-links=0 # Disabling symbolic-links is recommended to prevent assorted security risks
pid-file=/var/run/mysqld/mysqld.pid # 프로세스 id 파일 경로 설정 (꼭 mysqld_safe에도 넣어야함)
# Mysqld_safe : mysqld를 감시하는 데몬으로, mysqld_safe가 mysqld를 실행한다.
[mysqld_safe]
socket=/var/lib/mysql/mysql.sock
pid-file=/var/run/mysqld/mysqld.pid
nice=0
conf 디렉토리에 my.cnf파일을 vi로 넣어두었다. 또 권한을 644(rw-r-r) 로 두었다.
vi my.cnf
// rw-r-r 로 권한 설정
chmod 644 my.cnf
이제, 컨테이너를 재생성 해준다.
컨테이너 재생성 및 실행
# 컨테이너 생성
docker run -i -t --name db001 -h db001 -p 3306:3306 \
-v /home/opc/db/db001/data:/var/lib/mysql \
-v /home/opc/db/db001/log:/var/log/mysql \
-v /home/opc/db/db001/conf:/etc/percona-server.conf.d \ <--- 설정 파일
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
# 참고) 오라이클 클라우드를 쓰면 /home/opc/ 를 입력해줘야 처음 사용자 접속 경로에서 내려간다.
이 상태에서, /db/db001/log 로 가면, 아래와 같이 mysql.log가 잘 들어간 걸 볼 수 있었다.
[root@sideproject log]# ll
total 8
-rw-r-----. 1 polkitd input 4133 Dec 29 11:57 mysql.log
* VM : Virtual Machine 가상 머신으로, 분할 공간의 가상 환경을 제공한다.
* 호스트 OS : 서버 OS
* 게스트 OS : VM이 서버 OS위에 올리는 가상 OS
* 하이퍼바이저 : 게스트 OS를 구동하고 모니터링하는 소프트웨어
-> 유형 1 : Native/Bare-Metal 하이퍼바이저, 호스트 OS 없이 게스트 OS들만 존재
ex. VMware의 ESXi, Citrix의 Xen, Microsoft의 Hyper-V
-> 유형 2 : Hosted 하이퍼바이저, 호스트 OS 위에 게스트 OS들을 둔다.
ex. VmWare의 Workstation, Oracle의 VirtualBox
가상 머신(VM)의 경우, 하이퍼바이저를 통해 호스트 OS 위에 게스트 OS들을 두거나, 호스트 OS 없이 게스트 OS들을 사용할 수 있도록 분할된 가상 환경을 제공한다. 이 경우, 각각의 분할된 OS 마다 자원을 할당해주어야 한다. 도커(Docker)의 경우, 이와 달리 하나의 호스트 OS 의 커널을 각각의 컨테이너가 공유하는 형태를 띈다.
Docker의 컨테이너가 독립된 공간을 가질 수 있는 이유
Docker는 기본적으로 리눅스를 기반으로 만들어진 오픈 소스 프로그램이다. 리눅스 커널의 Cgroup은 프로세스들이 쓸 수 있는 사용량을 제한하며, Name space는 각 프로세스가 볼 수 있는 범위를 제한한다. (자세한 내용은 아래 참고 링크 확인) 도커는 이러한 리눅스의 특성을 활용해 Container를 구성했고, 각 Container는 따라서 마치 게스트 OS와 같이 독립된 공간을 가질 수 있다.
docker run -i -t --name [db이름] -e MYSQL_ROOT_PASSWORD="비밀번호" -d persona:5.7.30
// -it : 컨테이너에 쉘로 접속하기 위한 옵션
// --name : 컨테이너 이름 할당
// -e : 환경변수 세팅
// -d : 백그라운드로 컨테이너 실행
> Docker는 image만 있다면 어디서든지 컨테이너 생성이 가능하다.
> 컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당 받으며, 기본적으로 172.17.0.x의 IP를 순차적으로 할당한다.
docker run -it --name network_test ubuntu:14.04
* 위와 같이 -p 옵션이 없이 docker를 실행하면, 이 컨테이너는 외부에서 접속을 할 수 없고, 호스트에서만 접속이 가능하다. > 따라서, 외부에서 접근을 할 수 있도록 하려면 이 컨테이너에 -p 옵션을 두고 {호스트port}:{도커port} 로 연결하거나, {외부IP:port}:{도커port} 로 연결하도록 해야한다.
docker run -it --name network_test -p {ip:port}:{port} ubuntu:14.04
원격으로 MySQL Container 접속하기
호스트의 3306 포트에서 컨테이너의 3306 포트로 연결하여, 호스트에서 컨테이너의 mysql를 접속할 수 있게 한다면, 아래와 같이 코드를 작성하면 된다.
-- docker container 생성
docker run -it --name db001 -e MYSQL_ROOT_PASSWORD="root" -p 3306:3306 -d percona:5.7.30
-- percona에서 mysql 이미지를 다운로드한다.
https://docs.percona.com/percona-server/8.0/yum-download-rpm.html
> 이제 호스트OS 3306에서 컨테이너 3306로 MySQL 접속이 가능하게 됐다.
> 하지만 위의 경우, 컨테이너를 삭제하면 컨테이너 계층의 mysql 데이터 또한 삭제되게 된다. mysql 처럼 데이터의 영속성이 중요한 경우 이와 같이 컨테이너-영속성 데이터가 종속관계가 되어서는 안된다.
* mysql의 데이터는 기본적으로 /var/lib/mysql 경로에 저장하는데, Docker 컨테이너 안의 /var/lib/mysql 에 데이터가 저장되어, 컨테이너를 삭제하면 /var/lib/mysql 데이터가 유실된다. > 이를 막기 위한 방법은, 컨테이너와 독립적으로 데이터를 저장하는 것이다. 이때, 볼륨이라는 개념을 이해해야하는데, 볼륨은 운영체제에서 논리 드라이브(local drive)라고도 불리는 것으로, SSD와 같은 물리 드라이브와 달리 논리적으로만 존재하는 드라이브를 말한다. 대표적으로 C드라이브가 이 볼륨에 해당된다. > 볼륨을 컴퓨터가 사용할 수 있도록 적용하는 과정을 마운트라고 하는데, 컨테이너가 삭제되더라도 데이터를 유지하기 위해서는, 호스트 OS로부터 컨테이너로 볼륨를 마운트해야 한다.
> 볼륨을 마운트하는 방법은 크게 세가지가 있다. 1) 호스트와 볼륨을 공유하는 방법
2) 볼륨 컨테이너를 활용하는 방법 3) 도커가 관리하는 볼륨을 사용하는 방법
출처 : 3. Docker Volume (tistory.com)
Docker Volume
1. 호스트와 볼륨 공유 -v 옵션을 통해 호스트 OS의 특정 디렉토리와 컨테이너의 특정 디렉토리를 공유할 수 있다.
// 먼저 호스트에 디렉토를 생성한다.
mkdir -p /db/db001/data
// 호스트 디렉토리의 권한을 수정한다.
chmod 777 /db <-- /db 하위 폴더까지 권한 수정
// -v {호스트디렉토리}:{컨테이너디렉토리}
docker run -it --name db001 -p 3306:3306 \
-v /db/db001/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
[root@sideproject opc]# docker volume ls
DRIVER VOLUME NAME
local ec9de5f4574d28879fead241b36addffc99ae8390048546c07ac2067265e8e56
local mysqlVolume
local myvol
이후 docker run과 함께 -v 옵션에 {호스트의 volume 이름}:{컨테이너 경로}를 넣어주면 Container안의 /var/lib/mysql 경로와 호스트의 /var/lib/docker/volumes/{볼륨이름}/_data와 마운트를 해준다.
docker run -it --name db001 -p 3306:3306 \
-v myvolume:/var/lib/mysql\
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
// 옵션 설명
// --name : 컨테이너 이름
// -d : detached container (백그라운드에서 동작한다)
// -e : 환경설정
// --volume : 영속적인 데이터베이스 스토리지 생성
아래의 명령어를 통해 확인해보니, /var/lib/docker/volumes의 하위로 호스트 경로가 생성되는 걸 볼 수 있었다.