터칭 데이터

Docker & K8S - Docker Volume이란 본문

Docker & K8S

Docker & K8S - Docker Volume이란

터칭 데이터 2023. 12. 20. 11:13

 

 

Docker Volume이란?

 

Docker Container가 무슨 이유로건 중단되고 재실행된다면 그전의 데이터는 어떻게 되는 걸까?

 

 

 

 

 

 

 

 

 

그 문제를 해결하기 위해 등장한 것이 Docker Volume입니다.

Docker Volume의 필요성

 

Docker Container가 실행되었다가 중단되면 데이터들은 어떻게 될까?

 

특정 소프트웨어가 Docker Container를 통해 일회성으로 동작하는 것이 아니라 계속해서 동작해야 한다면 데이터가 영구적으로 보관되어야함

예) 데이터베이스가 Docker Container안에서 동작한다면?

 

이를 보장하는 기능이 Docker Volumes => Data Persistence

 

Docker Container내의 가상 파일 시스템과 호스트 시스템의 파일 시스템을 맵핑

이런 맵핑은 3가지 방법 중 하나입니다.

 

예) 호스트 파일 시스템의 /home/jon/logs를 Docker Container의 /var/lib/airflow/logs로 맵핑
이 경우 Docker Container가 중단되더라도 모든 Airflow logs는 기록이 남게 됨

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 예

 

Container와 Host 시스템(윈도우나 맥 등)이 특정 폴더를 공유

Container가 사라지더라도 데이터는 남게 하는 것!

 

 

 

Container로 MySQL을 실행하는 경우 데이터가 저장되는 공간을 Docker Volume으로 설정

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 정의

 

호스트 파일 시스템 폴더를 Docker Container 파일 시스템의 폴더로 마운트(Mount)하는 것

호스트쪽에서 내용을 바꾸면 바로 Docker Container쪽에도 반영됨

    - 반대도 사실이지만 Volume의 속성을 잡기 나름임 (예를 들면 읽기 전용)

    - 읽기 전용으로 하나의 폴더를 다수의 Docker 컨테이너와 공유하도록 할 수도 있음

이를 통해 Docker Container의 상태와 관계없이 데이터를 영구적으로 보관

 

파일 시스템에서 마운트란?

원래 마운트란 디스크와 같은 물리적인 장치를 파일 시스템의 특정 위치(폴더)에 연결해주는 것을 말함
예를 들어 윈도우에서 USB를 꼽으면 내 컴퓨터에 새로운 :D 혹은 :E와 같은 식으로 새로운 폴더가 생기는 것이 바로 마운트임 반대로 USB를 뽑아 폴더가 사라지면 언마운트(Unmount)

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 타입

 

1. Host Volumes: docker run -v를 실행할 때 페어로 지정

docker run -v /home/jon/logs:/var/lib/airflow/logs


:앞호스트 파일 시스템 패스이고 컨테이너 파일 시스템 패스임

 

2. Anonymous Volumes: docker run -v를 실행할 때 컨테이너 패스만 지정

docker run -v /var/lib/mysql/data 


이 방식이 Dockerfile에서 사용되는 방식으로 호스트쪽에 액세스되지는 않지만 재시작해도 유지됨

/var/lib/mysql/data 내용이 중요하니 니가 알아서 Data persistence를 유지하라는 명령

호스트 시스템마다 다르지만 호스트 시스템 내의 특정 폴더를 랜덤한 이름으로 만들어 /var/lib/mysql/data에 마운트함

잘 안쓰이는 방식입니다. 이름을 정하지 않기 때문에 매번 컨테이너 ID를 찾는 번거로움이 있기 때문입니다.

 

3. Named Volumes: docker run -v를 실행할 때 이름과 컨테이너 패스를 지정

docker run -v name:/var/lib/mysql/data


가장 선호되는 방식임. 이 방식이 하나의 Volume을 다수의 컨테이너에서 공유하는 것도 가능하게 해줌
이 포맷으로 뒤에서 살펴볼 docker-compose에서도 사용됨

 

Volume을 Readonly로 지정하고 싶다면?

name:/var/lib/mysql/data:ro

 

 

 

명령어 예시에서 짐작하셨듯이 2번과 3번 방식은 별도로 호스트 파일 시스템을 정해주지 않습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이미지 생성시 Docker Volume 사용법

 

1. Dockerfile

VOLUME 명령을 통해 anonymous volume만 지정 가능

 

2. docker-compose

Host Volume이나 Named Volume을 사용하는 것이 일반적

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 사용예: nginx를 실행해보자

Nginx는 강력한 로드 밸런싱, 리버스 프록시, 캐싱, SSL/TLS 지원 등 다양한 기능을 제공하여 웹 서버 환경을 최적화할 수 있습니다. 또한 Apache와 함께 사용되어 정적 콘텐츠를 처리하고 동적 콘텐츠를 처리하는 데 사용되기도 합니다.

많은 대형 웹 사이트 및 웹 애플리케이션에서 Nginx를 사용하여 빠르고 안정적인 웹 서비스를 제공하고 있습니다.

Nginx 역시 Docker에서 Official Image를 제공합니다.

 

 

docker run -d --name=nginx -p 8081:80 nginx

nginx 공식 이미지를 다운 받아 실행하는데 이름은 nginx로 주고 포트 맵핑은 8081:80으로 연결합니다.

 

브라우저 방문: http://localhost:8081/

Welcome 메시지를 보여주는 nginx 페이지가 나올 것입니다.

 

docker exec --user=root -it nginx sh

nginx 컨테이너에 root유저로 로그인해 Welcome 메시지를 보여주는 index.html을 편집해볼 겁니다.

    - apt update
    - apt install nano
    - nano /usr/share/nginx/html/index.html (내용 편집: Welcome to Docker Volume)
    - exit

 

그런데 Volume이 지정되어 있지 않기 때문에 컨테이너를 stop하고 remove하게 되면 바꾼 내용들이 사라지게 됩니다.

 

docker restart nginx

    - 위의 과정을 반복해 /usr/share/nginx/html/index.html 내용 확인시 원상복구된 것을 볼 수 있음

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 사용예: -v 옵션과 함께 nginx를 실행해보자

 

호스트 파일 시스템인 /Users/jobox/Downloads/grepp/kdt/nginx/html를 컨테이너 파일 시스템인 /usr/share/nginx/html에 맵핑(마운트) 할 것입니다.

 

ls -tl /Users/jobox/Downloads/grepp/kdt/nginx/html

index.html

test.html

 

호스트 파일 시스템에서 위와 같이 내용을 바꾸면 Docker에서도 바뀐 내용이 반영될 것입니다.

 

 

마운트 명령어

docker run -p 8081:80 -d -name nginx_demo -v /Users/jobox/Downloads/grepp/kdt/nginx/html:/usr/share/nginx/html
nginx

 

/Users/jobox/Downloads/grepp/kdt/nginx/html에 있는 index.html과 test.html 파일들으 수정하는 순간순간 마다 /usr/share/nginx/html의 내용들이 실시간으로 반영될 것입니다.

 

 

http://localhost:8081/

 

index.html 내용 수정하고 브라우저에서 재방문

 

nginx를 재시작하고 내용이 유지되는지 확인

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume을 Dockerfile에서 사용한 예 (2)

강의에서 다루지 않은 PDF 페이지라서 일단 필기만 해두고 내용은 접어두었습니다.

더보기

 

이번에는 아래 Dockerfile로 이미지를 빌딩

FROM nginx:latest
RUN echo "<h1>Hello from Volume</h1>" > /usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html

 

docker build -t demo-earthly .

 

docker run -p 8081:80 -d --name nginx_demo demo-earthly

 

http://localhost:8081/

 

docker exec -it --user=root nginx_demo sh

apt update;apt install nano
nano /usr/share/nginx/html/index.html
exit

 

docker restart nginx_demo

 

 

 

 

 

 

 

 

 

 

 

Docker Volume을 docker-compose.yml에서 사용한 예

 

Airflow 예)

volumes:
  - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags
  - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs 
  - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins

 

 

 

 

호스트 파일시스템:

airflow-setup/dags
MySQL_to_Redshift_v2.py
UpdateSymbol_v3.py
UpdateSymbol.py
…

 

 

위의 호스트 파일시스템과 아래의 Docker Container 파일시스템의 내용이 동일해야 합니다.

 

 

Docker Container 파일시스템: /opt/airflow/dags

$ docker exec 4f8635eefa02 ls -tl /opt/airflow/dags
MySQL_to_Redshift_v2.py
UpdateSymbol_v3.py
UpdateSymbol.py

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Docker Volume 명령들

 

docker volume ls

볼륨들을 조회

 

docker volume rm

특정 볼륨을 삭제

 

docker volume prune

사용되지 않은 모든 볼륨들을 삭제

 

docker volume inspect

특정 볼륨의 내용을 살펴보기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

데모: 앞서 nginx 두 가지 실행 예 살펴보기

첫번째는 하나는 볼륨없이 내용이 사라지는 경우를

두번째는 볼륨을 지정하고 실행하며 내용이 사라지지 않는 경우를

 

이렇게 두 상황을 살펴보았습니다.

 

이 상황들에 대한 데모를 진행해보겠습니다.

 

거기에 더해

 

세번째는 Airflow의 docker-compose.yml에서 volumes 내용만 살펴보기도 했는데요.

데모의 끝 부분에서 airflow의 docker-compose.yml 파일도 잠깐 살펴볼 예정입니다.