Go, Vantage point
가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.
Github | https://github.com/overnew/
Blog | https://everenew.tistory.com/
티스토리 뷰
컨테이너의 storage
받아온 image는 변경이 불가능하고 container layer에 작업하게 된다.
계층별로 디자인을 위에서 찍는 그림이 유니온 파일 시스템이다.
한번에, 오버레이하여 서로 겹치지만 않으면 된다.
겹치면 위에 것이 읽히고, 아래 데이터는 보호할 수 있다.
최종적으로 맨 위에 쌓이는 계층이 읽기 쓰기를 제공하므로, 우리는 읽기 쓰기가 되는 것처럼 보인다.
하지만 Image layer는 읽기 전용이므로 변경이 되지 않는다.
즉, 우리가 컨테이너에서 변경하던 것은 container layer이었다.이였다.
유니온 파일 시스템
유니온 파일 시스템은 여러 개의 파일 시스템을 하나의 단일 파일 시스템으로 합치는 기술이다.
이것은 여러 개의 디렉터리와 파일들을 하나로 통합하여, 사용자에게는 단일한 파일 시스템으로 보이게 한다.
유니온 파일 시스템을 사용하면, 다양한 소스로부터 파일을 가져와서 하나의 가상 파일 시스템으로 표현할 수 있으며, 각 파일 시스템의 읽기 및 쓰기 작업을 동시에 지원한다.
이를 통해 운영 체제나 사용자 프로그램이 여러 저장소를 하나의 논리적인 단위로 투명하게 다룰 수 있다.
따라서 컨테이너를 삭제하면 사용하던 볼륨도 삭제된다.
서버 데이터가 날아가면 안 되는데, 이 볼륨을 어떻게 남길 수 있을까?
기본적으로 host의 Local 디스크에 mount 하는 방법이 제공된다.
docker run -v 옵션 사용하기
-v, -- volume 사용 예시
$ docker run -d -it -- name devtest -v /storage/source/ct03-bind01:/storage:ro nginx
콜론 문자(:)로 구분된 세 개의 필드로 구성
- 첫번째 -/storage/source/ct03-bind01 : 호스트 시스템의 파일 또는 디렉터리에 대한 절대경로
- 두번째 - /storage : 파일 또는 디렉터리가 컨테이너에 마운트 되는 경로
- 세번째 - ro : 선택사항이며, ro, z 및 Z와 같은 쉼표로 구분된 옵션 목록입니다. read only를 의미한다.
docker run -v는 바인드 마운트로 컨테이너의 볼륨을 호스트 시스템의 위치시켜 보관한다.
이 볼륨은 도커 컨테이너 혹은 프로세스끼리 정보를 공유할 수도 있게 만들어준다.
하지만 중요 파일을 수정해 버리면,다른 프로세스에게도 영향을 줄 수 있다.
따라서 중요한 볼륨의 옵션은 read only로 (-ro)주어야 함.
MySQL로 테스트해 보기
My sql을 환경 옵션을 주어서 실행하자.
docker run -d --name db -v /dbdata:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=54321 mysql:latest
-v -> 볼륨 마우트 시키기, 컨테이너의 var/lib/mysql를 /dbdata (루트 디렉토리에 dbdata) 폴더와 마운트
실행 후 dbdata라는 폴더가 자동 생성되어 있다.
안에 들어가서 확인해 보며 mysql의 /var/lib/mysql 데이터들이 모두 들어와 있다.
컨테이너에 접속해서 mysql에 접속하자.
cloud라는 DB를 만들었다.
dbdata에서 확인해 보면 cloud 데이터가 만들어져 있다.
docker rm -f db로로 삭제하여 정보가 남는지 확인하자.
(컨테이너만 삭제)
여전히 마운트했던 dbdata 폴더는 남아있다.
원래라면 새로 컨테이너 실행 시, docker 엔진의 관리하의 랜덤한 장소에 새로 생기지만 옵션을 통해 이 데이터를 사용하도록 하면 된다.
docker run -d --name db -v /dbdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql:latest
기존의 데이터를 새로운 mysql 컨테이너와 마운트 시킨다.
실행만해도 Cloud DB가 존재한다.
Inspect로 확인하면, 마운트 장소를 볼 수 있다.
docker inspect db
다시 없애보자.
docker rm -f db
마운트는 하지만 지정하지 볼륨 디스크를 지정하지 않게 시작한다.
docker run -d --name db -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:latest
자동으로 생성된 볼륨 마운트가 존재
v 옵션 시에 임시로 만들어 준 volume 폴더에 생성된다.
따라서 rm으로도 컨테이너를 날려도 데이터가 날아가지 않는다.
Docker volume ls
(볼륨이 남아있다.)
웹 서버 컨터이너들에게 폴더 공유시키기
이제 만든 폴더를 web container가 사용하게 해 보자.
간단히 index.html 파일을 만들어 주자.
공유 파일의 영향을 줄이기 위해 ro 옵션으로 조회만 가능하게 하여, 관리자만 사용하게 만들어주자.
docker run -d --name web -p 80:80 -v /webdata:/usr/share/nginx/html:ro nginx
이제 내용을 바꾸어보자.
원래라면 container에 접속해서 바꾸었지만, 지금은 /webdata 폴더에서 파일을 바꾸면 된다.
변경되어 보임.
이 폴더를 여러 개의 서버가 마운트 하여 한번에 변경도 가능하다.
여기서 좀 더 나아가는 것이, EFS 구조에서 사용한다.
하나의 정보로 여러 웹서버가 사용한다.
서버의 저장소 상태 데이터(df -h 명령어)를 웹에서 계속 확인하는 것을 만들자.
nano df.sh
#!/bin/bash
mkdir -p / webdata
while true
do
df -h / > webdata/index.html #수동으로 데이터를 index에 넣줌
sleep 10 #10초에 한번씩
done
Webdata 폴더를 공유하도록 마운트
Dokcer file로 sh 실행하도록 빌드하기
FROM ubuntu:22.04 #base image
ADD df.sh /webdata/df.sh #same directoty with docker file
RUN chmod +x /webdata/df.sh #exec permission
ENTRYPOINT ["/webdata/df.sh"]
index.html을 업데이트하는 도커 파일 빌드
docker build -t everenew/df_web:1.0 .
권한 오류가 나는 이유는 df.sh는 root만 접근이 가능하기 때문.
Df.sh를 누구나의 권한으로 바꾸어 주자.
Chmod 777 df.sh
빌드한 이미지를 실행시키자.
docker run -d -v /webdata:/webdata --name df everenew/df_web:1.0
이제 nginx 컨테이너를 하나 더 올려보자.
docker run -d --name web2 -v /webdata/:/usr/share/nginx/html:ro -p 8080:80 nginx
두 nginx가 다 파일 공유로 실행 중.
볼륨이라는 용어를 계속 혼용해서 사용했는데 제대로 정리해 보자.
도커 볼륨과 바인드 마운트의 차이
도커의 볼륨(volume)은 컨테이너와 호스트 간의 데이터를 저장하는 디렉터리나 파일입니다.
이는 도커 엔진이 관리하며, 도커가 관리하는 공간 내에서 컨테이너 간 데이터를 공유할 수 있도록 해줍니다.
반면 바인드 마운트(bind mount)는 호스트의 파일 시스템 경로를 직접적으로 컨테이너에 연결하는 것입니다.
이 둘의 차이는 데이터의 저장과 관리를 누가 책임지느냐에 있습니다. 볼륨은 도커가 데이터를 관리하며, 바인드 마운트는 호스트가 데이터를 관리합니다.
바인드 마운트
Host os의 특정 폴더를 container의 특정 폴더로 사용하는 것이다.
docker run -d --name myweb -p 80:80 -v /myweb:/usr/share/nginx/html:ro nginx
-v [host os 경로]:[container의 경로]
host os 경로가 container의 경로로 사용된다.
이때 다른 컨테이너를 동일한 host os 경로로 사용하도록 만들어 줄 수 있다.
docker run -d --name myweb2 -p 80:80 -v /myweb:/usr/share/nginx/html:ro nginx
이 webdata를 서로 공유하므로 동일한 index.html을 사용하게 된다.
볼륨
볼륨은 도커 엔진이 관리하는 저장소를 컨테이너가 사용하는 것이다.
docker volume create --name [볼륨 이름]
으로 volume을 만들 수 있다.
docker run -d --name myweb -p 80:80 -v volume_name:/root/ nginx
docker run -d --name myweb2 -p 80:80 -v volume_name:/root/ nginx
이러면 도커의 볼륨에 root부터 모두 올라오게 된다.
이 docker volume은 도커 엔진이 관리하는 디렉터리에 생성된다.
일반적으로 볼륨 생성 경로는 /var/lib/docker/volumes/volume_name/ 이다.
이러면 사용자는 볼륨을 전혀 관리할 필요가 없어진다.
만약 아래와 같이 생성하면,
docker run -d --name db -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:latest
(마운트는 하지만 host os의 경로를 지정하지 볼륨 디스크를 지정하지 않았음.)
자동으로 volume이 생성되어 마운트 된다.
'개발 > Docker' 카테고리의 다른 글
WordPress로 Docker 2tier 구현하기 (with DNS) (0) | 2024.03.01 |
---|---|
Docker Image Backup 전략 (Docker Registry container) (0) | 2024.03.01 |
Docker Hub에 Docker Image 업로드하기 (0) | 2024.02.28 |
Ubuntu Docker DNS 컨테이너 올리기 (forwaders 사용) (3) | 2024.02.28 |
[Virtual Box] Ubuntu에 Jenkins container 올리고 접속하기 (0) | 2024.02.28 |