2022. 1. 24. 17:11ㆍDevOps/Docker & kubernetes
docker volume을 알기 위해서는 도커 레이어 아키텍쳐가 무엇인지 알아야한다. 컨테이너 상에서 영구적으로 볼륨을 다루는 방법은 총 3가지가 있는데 각각 host volume, volume container, docekr volume을 이용하는 방법이다.
도커는 기본적으로 container layer와 image layers로 나누어져있다. 도커를 빌드할때 docker build -t app . 과 같은 빌드 명령어를 통해 dockerfile을 기반으로 하여 build가 된다. 이 이미지를 자세히 분석해 보면 5단계의 Layer로 구성이 되어있다. 도커 파일 안의 여러 명령어들이 순차적으로, Layer가 쌓이듯 저장이 된다고 볼 수 있다.
위 표는 ubuntu를베이스로 사용한다고 가정했을때의 layer architecture이다. 먼저 ubuntu layer가 쌓이고 그 다음으로는 필요로 하는 페키지를 설치하게 된다. 파이선과 관련된 pip 페키지가 그 다음으로 설치되며 소스코드를 복사한 다음으로는 엔트리포인트의 명령어를 변경하는것으로 image layer가 완성된다. 추후에 이미지를 변경하기에 정말 간편한데 pip(3번)를 바꾸고 싶으면 1,2의 레이어는 건들일 필요 없이 3번부터 새로운 레이어를 쌓아 올리면 되기 때문이다. 그렇기에 다양한 버전이 생기게 되더라도 저장공간이 별로 차지하지 않는 이미지이다.
run 명령어로 이미지를 실행하게 될 경우 컨테이너가 된다. 이미지 레이어를 불러 들여서 사용하는것이기에 읽기전용으로 항상 동일하지만 컨테이너 상에서 새로운 파일을 생성한다거나 할 경우 read write권한을 가진 container layer에 생성하게 된다. 하지만 컨테이너가 종료된다면 container layer도 같이 삭제되기 때문에 임시 저장소 정도로 이해하면 될 것이다.
host volume은 가장 간단하고 직관적이라고 할 수 있다. 호스트의 디렉토리를 컨테이너의 특정 경로에 마운트 한다.
먼저 host-volume.sh파일을 형성해 주도록 하자. 생성법은 다음과 같다
1. vim host-volume.sh 명령어를 입력한다.
2. 아래와 같은 공백의 화면이 나타나는것을 확인할 수 있다.
3. 단축키 i를 클릭한 후 하단에 insert라는 글자가 나타나는것을 확인한 후 아래의 명령어를 입력한다.
4. 모든 입력이 마친후 esc버튼을 클릭 한 후 ":" 버튼을 클릭한 다음 wq 를 입력하고 enter를 누른다.
docker run \
-d \
-v $(pwd)/html:/usr/share/nginx/html \
-p 80:80 \
nginx
~
이후 html 이라는 폴더를 생성하고 이 안에 index.html을 만들어 보도록하자. 아래의 명령어를 입력 후 간단하게 한 줄 정도의 명령어를 입력해 두자. ( chmod u+x 와 같은 권한부여는 이제 잘 할것이라 생각한다.)
mkdir html
cd html
sudo vi index.html
<h1> hello world</h1>
호스트 볼륨을 이용할대는 -v 옵션을 사용한다. 호스트 볼륨 경로와 컨테이너의 볼륨경로를 정한다. pwd는 현재 디렉터리 경로를 출력한다. $() 명령어를 통해 괄호안의 명령으로 치환된다.
자 이제 host-volume.sh을 실행시켜보자.
화면에 보듯 포트가 잘 바인드되었으며 curl을 실행했을때 아까 저장한 hello world를 잘 확인할 수 있다. 또한 exec 명령어를 사용했을때도 마찬가지로 잘 되는것을 확인할 수 있다. 디렉토리로 마운트를 했기 때문에 host에서도 확인할 수 있다.
volume container를 통해서도 마운트를 공유할 수 있는데 아래의 그림을 보도록 하자. data-only container가 볼륨 컨테이너라고 생각하면 편하다. 볼륨을 특정 어플리케이션에서 마운트 시키는것이 아닌, 볼륨컨테이너에서 볼륨 마운트만 진행하는 컨테이너를 만들어 두는것이다. 이 상태에서 컨테이너는 데이터 컨테이너를 참조해서 해당 컨테이너를 볼륨 컨테이너처럼 사용할 수 있으며, 마운트목록을 공유할 수 있다는 의미이다.
docker run -d\
--name my-volume \
-it \
-v /opt/html:/usr/share/nginx/html\
ubuntu:focal
#my-volume 컨테이너의 볼륨을 공유할때
docker run -d \
--name nginx \
--volumes-from my-volume \
nginx
먼저 아래의 volume-container.sh을 만든 후 실행해 보도록 하자.
#!/usr/bin/env sh
#웹 볼륨이라는 볼륨 컨테이너를 만들고 있다.ubuntu:focal이미지를 사용하고 있다.
docker run \
-d \
-it \
-v $(pwd)/html:/usr/share/nginx/html \
--name web-volume \
ubuntu:focal
#nginx를 실행한다. 각각 80,8080번을 바인드 하고있으며 --volumes-from을 통해서 웹 볼륨 컨테이너를 마운트 하고있다.
docker run \
-d \
--name test-nginx \
--volumes-from web-volume \
-p 80:80 \
nginx
docker run \
-d \
--name test2-nginx2 \
--volumes-from web-volume \
-p 8080:80 \
nginx
각각 포트가 test-nginx는 80을, test-nginx2는 8080을 잘 바인드 하는것을 확인할 수 있다.
또한 docker inspect test-nginx 명령어를 통해서도 마운트가 잘 되었는지 눈으로 확인할 수 있다. exec 명령어를 통해서도 역시 최초에 만든 hello와 index.html이 잘 있는것을 확인할 수 있다.
마지막으로 도커 볼륨을 생성해 보도록하자. 기본적인 명령어구조는 아래와 같다.
# 도커 볼륨 생성
docker volume create --name db
# 도커의 web-volume 볼륨을 nginx의 웹 루트 디렉토리로 마운트
docker run -d \
--name test-mysql \
-v db:/var/lib/mysql \ # mysql이 데이터를 쌓는 경로이다.
-p 3306:3306 \
mysql:5.7
도커가 제공하는 볼륨 관리기능(생성, 삭제 등)을 활용해 데이터를 보존할 수 있다.
기본 저장장소는 /var/lib/docker/volumes/${voluem-name}/_data 이다.
docker-volume.sh 을 만들도록 하자. 내용은 아래와 같다. db라는 이름의 볼륨을 만들것이며 볼륨목록을 확인한 후 mysql 컨테이너를 실행하는 절차이다. 이름은 test이다.
#!/usr/bin/env sh
docker volume create --name db
docker volume ls
docker run \
-d \
--name test-mysql \
-e MYSQL_DATABASE=test \
-e MYSQL_ROOT_PASSWORD=test \
-v db:/var/lib/mysql \
-p 3306:3306 \
mysql:5.7
권한을 부여한 후 실행해 보도록 하자. 최초로 mysql을 부르기 때문에 설치가 진행되며 이 후 아래와 같이 test-mysql이 잘 생성 되는것을 확인할 수 있을 것이다.
inspect명령어를 통해서도 잘 확인할 수 있으며 ls명령어도 마찬가지로 잘 형성되는것을 볼 수 있다.(참고. ls의 경우 sudo로 권한을 부여해야지 실행이 된다.)
또한 volume 명령을 통해서 db를 삭제하고자 할 때는 반드시 컨테이너를 지우고 나서 db를 삭제해야지 된다.(아래 그림 참조)
마지막으로 read-only volume을 연결해 보도록 하겠다. 보통은 변경이 되서는 안되는 디렉터리나 파일(설정, 웹 루트 디렉토리 등)에 지정을 한다. 기본적인 구성은 아래와 같다. 처음 host-volume과 유사함을 알 수 있다.
docker run -d\
--name nginx \
-v web-volume:/usr/share/nginx/html:ro \
nginx
host-volume을 아래처럼 변경한 후 실행해 보도록 하자.
#!/usr/bin/env sh
docker run \
-d \
-v $(pwd)/html:/usr/share/nginx/html:ro \
-p 80:80 \
--name ro-nginx \
nginx
docker exec ro-nginx touch /usr/share/nginx/html/hello
실행을 하게 되면 아래와 같이 touch 명령어가 입력이 되지 않고 read-0only라고 설명해 주는것을 확인할 수 있다.
'DevOps > Docker & kubernetes' 카테고리의 다른 글
Docker image Build(도커 이미지 빌드하기) (0) | 2022.01.28 |
---|---|
Docker log 확인 및 다뤄보기 (0) | 2022.01.26 |
Docker Network 구조 (0) | 2022.01.18 |
Docker 기본 개념 part.2 (Entrypoint, 환경변수, 실행 명령어) (0) | 2022.01.17 |
Docker 기본 개념 part.1 (container의 life cycle) (0) | 2022.01.16 |