Docker - Host DB와 Container DB 연동

Docker

데이터의 영구 보존

Container image는 Read Only이다. 따라서 컨테이너에 추가되는 데이터들은 별도의 RW 레이어에 저장이 되어야한다.

Docker는 Union File System 혹은 overlay을 통해 RO와 RW 레이어의 변경 사항이 하나의 시스템인 것처럼 나타낸다. 컨테이너를 삭제하면 저장된 데이터도 함께 영구 삭제된다. 따라서 컨테이너가 만들어주는 데이터를 영구적으로 보존 시킬 방법을 강구해야한다.

Docker host에 directory, disk 등 저장 공간을 마련하여 데이터를 쌓아두어야한다. 이를 volume mount라고 한다.

코드로는 docker run -d --name db -v /hostdisk:/var/lib/mysql와 같이 -v 옵션을 사용하면 된다.

volume 옵션을 통한 데이터 저장

-v 옵션을 사용하여 volume mount를 통해 disk에 데이터를 저장하면 서비스를 삭제 후 실행, 재실행해도 데이터를 유지할 수 있다.

-v <Host path>:<Container mount path>

  • Host의 db데이터를 container의 path에 volume mount한다.
  • container path의 데이터를 Host의 db에 저장하게 한다.
  • container가 host의 데이터를 수정할 수 있는 단점이 있다.

-v <Host path>:<Container mount path>:<read write mode>

  • docker run -d -v /hostdisk:/var/www/html:ro ~
  • container은 host의 데이터에 대해 RO(Read Only) 권한을 갖는다.
  • default는 read write이다.

-v <Container mount path>

  • /var/lib/docker/volumes/uuid디렉토리/data 경로에 uuid 디렉토리를 생성하여 자동으로 mount를 시켜준다.

예제 확인하기

1. MySQL DB data 영구 보존하기

환경

Mac OS (M1) 환경에서 docker desktop을 다운로드 후 iterm2에서 실행하였습니다.

사전 설정

docker desktop - preferences - Resources - FILE SHARING에서 mount될 디렉토리를 추가한 후 진행하였습니다.

  • /User/InwooJeong/dbtest

1. 컨테이너 생성

명령어에 오타가 있을 시 container가 실행하자마자 종료될 수 있습니다.

  • docker background 실행
  • 컨테이너 이름 : dbtest
  • Host DB directory : /Users/InwooJeong/dbtest
  • Container DB directory : /var/lib/mysql
  • Mysql Root password = pass
  • platform : linux/amd64
    • M1칩 기반의 Mac Os를 사용할 때는 플랫폼을 명시적으로 설정해주어야합니다.

1. Host path:Container path 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ docker run -d --name dbtest -v /Users/InwooJeong/dbtest:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=pass --platform linux/amd64 mysql:latest
````

위와같이 실행하면 Container는 `background` 환경에서 `mysqld` 명령어를 통해 mysql이 실행되고 있다.
- mysqld는 mysql의 Dockerfile 내에 명령어로 입력되어 있다.

> Container Path만 작성해도 데이터를 Host path에 영구적으로 저장할 수 있다.
>
> Linux 기준으로 랜덤한 UUID를 통해 /var/lib/docker/volume/UUID/_data에 저장된다.

### 2. MySQL에 접속
`mysql` client 명령을 통해 외부에서 접속할 수 있지만, container 내부에 들어가서 실행할 수도 있다. 아래 코드를 통해 `dbtest`라는 컨테이너에 접속해서 `/bin/bash`에 접근한다.

```shell
docker exec -it dbtest /bin/bash
````

### 3. mysql 실행

컨테이너 내부에 접속하였으니 `mysql`으로 접속하여 data를 생성해보려한다.

현재는 **root 계정**만 존재하고 있으므로 `user(-u)는 root`, `password(-p)`는 docker run을 할 때 설정해주었던 pass로 입력하여 접속한다.
- `-p`와 `password`인 pass를 **붙여서 작성**해주어야한다.

```shell
root@213kl1j23k:/# mysql -u root -ppass
````

### 4. 데이터 생성

```shell
mysql> create database inwoo;

위 코드를 통해 데이터베이스를 생성한 후 Host Database Directory로 설정한 /Users/InwooJeong/dbtest를 확인해보면 inwoo 폴더가 생성되어 있는 것을 확인할 수 있다.

2. Host DB에 있는 서비스를 Container에 지원하기

-v <host path>:<container mount path>:<read write mode>

1. 제공할 웹 컨텐츠 만들기

Host의 원하는 디렉토리에 간단한 index.html 파일을 생성하여 저장해주었다.

  • Host path : /Users/InwooJeong/webdata
  • file name : index.html
  • contents : <h1>Inwoo Jeong Web Service Test</h1>

2. Container 실행하기

  • docker background 모드로 실행
  • container 이름 : web
  • 포트포워딩 : 80:80
  • volume 설정
    • host path : /Users/InwooJeong/webdata
    • container path : /usr/share/nginx/html
    • read write option : ro
      • container에서 host의 서비스를 임의로 변경할 수 없도록 Read Only로 설정한다.
1
docker run -d --name web -p 80:80 -v /Users/InwooJeong/webdata:/usr/share/nginx/html:ro nginx:1.14

3. Web 접속

공인 ip:port 주소로 접속하면 container를 통해 host path에 접근하여 서비스를 제공받을 수 있다.


Docker - Host DB와 Container DB 연동

http://inwoo.github.io/01/14/datapersistence/

Author

Inwoo Jeong

Posted on

2022-01-14

Updated on

2022-02-23

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

댓글