2. 이미지와 컨테이너 내부의 데이터 관리 방법 , 다른 폴더 등에 연결하는 방식, 도커에 내장된 볼륨이라는 개념
다양한 데이터 종류 이해하기
우리가 작성한 코드 + package.json에 지정된 패키지 환경이 빌드 단계에서 이미지에 추가된다. -> Dockerfile을 사용
이미지에 복사된 코드는 고정되고 이미지가 빌드되면 변경될 수 없다. -> 이미지는 읽기 전용이다!
1. 임시 Application data
우리가 작성한 소스 코드가 아닌 Application이 실행되는 동안 생성된 데이터
ex) 입력 폼 데이터 같이 사용자가 직접 전달한 데이터를 가져와 서버에서 실행중인 컨테이너로 처리함
컨테이너가 종료될때 일시적인 데이터이기 때문에 잃어도 상관없다.
"일시적"으로 쓰고 싶은 데이터여서 이미지가 아닌 컨테이너에 저장된다. -> 이미지는 읽기 전용이니까!
또한 이미지가 아닌 컨테이너에 저장되는 것은 이미지 위에 도커에 의해 추가된 부가(extra) 레이어에 대한 이야기이다.
부가 레이어는 실제로 그 컨테이너를 구성하고, 기본적으로 logic이라 할 수 있다. -> 이미지를 인식하고 이미지의 파일 시스템을 인식하며, 복사하지 않고 파일 시스템을 미러링하는 로직이다.
도커는 실제로 read-write Access 권한을 가지며 파일의 시스템을 조작 할 수 있다.
-> 이미지에서 변경 x 부가 레이어에서 변경 o
또한 가장 뒷단에서 효율적인 방식으로 관리된다. 도커는 컨테이너 변경 사항과 이미지의 파일 시스템을 가져와 최종 파일 시스템을 파생시켜 read-write 레이어에 저장된 변경 사항과 결합한다.
컨테이너에 저장한다? -> 파일이 무엇이든 read-write 레이어에 저장하고 그 레이어의 도움을 받아 저장한다.
read-write 레이어는 모두 컨테이너 안에 있다.
2. temporary app data (일시적 app data)
3.. Permanent App Data (영구 App data)
ex) 회원가입 후 사용자 계정을 받아서 파일에 저장 or DB에 저장 하는 데이터 -> 영구 지속되어야 하는 데이터
컨테이너가 중지(삭제) 되고 다시 시작되어도 데이터가 그대로 있어야 함!
영구 Application 데이터는 read-write data이다. Application이 실행되는 동안 작성하지만 영구 저장 되어야함
컨테이너에 저장하지만 볼륨(Volumes)의 도움을 받는다. -> 볼륨은 핵심 개념 중 하나이다.
여기 예시 node 앱을 이용해서 위 3가지 종류의 데이터를 모두 도커화해보자!
$ docker build -t feedback-node .
-> 이미지 빌드 과정 -t 사용해서 태그 'feedback-node' 지정
$ docker run -p 4000:80 -d --name feedback-app --rm feedback-node
feedback-app 이라는 이름의 컨테이너 생성 Dockerfile의 80번 포트와 localhost4000 연결, --rm으로 컨테이너 중지시 자동 삭제
★ -d로 detached 모드로 실행함 -> 터미널에 log들을 띄우고 싶으면 attatched모드 / 터미널에 명령어 입력 가능하게 하려면 detached모드
어쨌든 실행 후 내 feedback을 적으면 (나는 Awesome 으로 적음!)
localhost:4000/feedback/awesome.txt 에 방문하면 내가 적은 feedback 내용이 보인다.
근데 내 vscode feedback 폴더에는 내가 쓴 내용이 저장되어 있지 않다.
내가 쓴 내용은 도커 컨테이너 내부에만 존재하기 때문에 실제로 내 폴더 안에서는 볼 수 없다.
컨테이너나 이미지와 로컬 파일 시스템 간에는 연결되어 있지 않기 때문이다.
우리는 처음 Dockerfile을 생성하고 우리의 폴더들을 이미지에 복사하고 컨테이너를 실행시켰다.
즉 내 로컬 폴더에 적용되는 것이 아닌 내가 복사한 이미지안의 폴더에 적용된것이다.
컨테이너는 격리되어 있는 개념이기에 파일이 컨테이너 내부에서 생성되어 컨테이너 내부에 저장된 것이다.
그렇기에 이 컨테이너를 중지 시키면
--rm 으로 자동 삭제를 시켰기 때문에
안에 내가 적은 feedback data도 날라갈것이다.
그래서 컨테이너를 중지 시킨 후
docker stop feedback-app
이번엔 새로운 컨테이너를 만드는데 중지해도 삭제되지 않게 만들어보자.
$ docker run -p 4000:80 -d --name feedback-app feedback-node
내가 만들었던 localhost:4000/feedback/awesome.txt 에 들어가면 파일이 존재하지 않는다는걸 알 수 있다.
그래서 다시 Awesome 이라는 feedback을 내용만 다르게 하여 만들고 들어가면 새롭게 만든 awesome.txt의 내용을 볼 수 있다.
이제 이 컨테이너를 중지시킨후 재시작하면 이 파일이 여전히 존재하는걸 볼 수 있다.
컨테이너를 중지 시킨 후 재시작하는건 괜찮지만 컨테이너를 삭제 후 다시 만드는것은 파일의 손실이 있다.
이런걸 왜 알아야 하면...
우리가 소스 코드의 변경을 위해 어쩔 수 없이 컨테이너를 삭제 후 다시 만들어야한다면 원래 컨테이너에 갖고 있던 데이터들이 손실될 것이다.
해결책?
이 해결책이 바로 위에서 영구 App data에서 얘기한 볼륨이다.
(바인드 마운트도 있지만 나중에 설명)
볼륨이란게 뭘까? -> 볼륨은 "호스트" 머신의 폴더이다.
컨테이너나 이미지에 있는 것이 아닌 내 컴퓨터에 장착된 하드 드라이브에 존재하여 사용하거나 컨테이너로 매핑되는 것을 말한다.
다시말해 도커가 인식하는 내 컴퓨터에 있는 폴더로서 도커 컨테이너 내부의 폴더에 매핑된다.
Dockerfile에서 했던 COPY는 일회성으로 파일과 폴더를 복사하는 것 뿐이기에 다른 개념이다.
내 컴퓨터에 있는 폴더(호스트 머신)에 파일을 추가하면 컨테이너 내부에서 액세스할 수 있고
컨테이너가 매핑된 경로에 파일을 추가하면 호스트 머신에서도 사용할 수 있다.
이 메커니즘으로 데이터를 유지한다. -> 볼륨은 컨테이너가 종료된 후에도 지속되며 계속 존재하기 때문
컨테이너에 볼륨을 추가하면 해당 볼륨은 제거되지 않으며 컨테이너가 제거되어도 볼륨은 유지한다.
데이터를 컨테이너 외부에도 저장시켜 컨테이너가 제거되도 살아남는 구조!
볼륨을 컨테이너에 추가하는 방법
Dockerfile에 Volume 명령을 추가하는법이 가장 쉽다.
볼륨에는 두 가지 타입이 있으며
1. 익명의 볼륨(Anonymous Volume) ->Dockerfile의 명령을 예로 들어 설명하면
VOLUME [ "/app/feedback" ]
이미지에 익명의 볼륨을 추가하고 이미지 기반으로 실행하는 컨테이너에 데이터를 추가
2. 명명된 볼륨(named Volume)
이 존재한다.
두 가지 모두 상관없이 작동한다. 또한 둘다 도커는 일부 폴더와 경로를 호스트 머신에 설정한다.
호스트 머신의 경로를 지정하지 않았기에 우리는 컨테이너 데이터를 가져온 폴더의 위치를 모른다.
이런 볼륨에 엑세스 하는 방법은 'docker volume' 명령을 사용하는 것이다.
docker volume --help 의 명령어들중 'docker volume ls' 옵션은 도커가 현재 관리중인 모든 볼륨을 보는것인데
나는 지금 익명의 볼륨을 사용했기에 자동 생성된 긴 암호같은 VOLUME NAME을 볼수있다
근데 이 익명의 볼륨의 치명적인 단점은 컨테이너가 존재하는 동안만 존재한다.
근데 컨테이너가 제거되면 데이터가 사라지는데 볼륨이 같이 사라지면 의미가 없는 것 아닌가?
근데 다시 주의할점!
컨테이너가 제거되면 자동으로 익명 볼륨이 제거되는 것이 아니다.
--rm 옵션으로 컨테이너를 시작할때만 컨테이너 제거시 익명 볼륨이 제거되는것이다.
--rm 없이 컨테이너를 시작하면 익명 볼륨 자체는 제거되지 않는다.
하지만 다시 컨테이너를 만들어 실행하면 원래 쓰던 익명 볼륨이 연결되지 않고 새로운 익명 볼륨이 생성되어 연결된다. 따라서 익명 볼륨만 쌓일뿐 제거되지 않는다고 하더라도 영구적인 데이터가 필요할땐 사용하는것은 아닌거같다.
볼륨 지우는법 -> docker desktop에서 직접 지우거나 'docker volume rm VOL_NAME' 또는 'docker volume prune'을 이용
그래서 명명된 볼륨(named volume)을 쓰자~
컨테이너가 종료된 후에도 볼륨은 유지가 되기 때문에 새 컨테이너를 시작하면 볼륨이 복구되고 폴더가 복구되어 폴더에 저장된 데이터를 계속 사용할 수 있다.
그래서 명명된 볼륨은 영구 app data나 편집하거나 직접 볼 필요가 없는 중요한 데이터에 적합하다.
$ docker run -d -p 4000:80 --rm --name feedback-app -v feedback:/app/feedback feedback-node:volumes
-v feedback:/app/feedback -> -v : 볼륨 옵션
-v 볼륨이름:컨테이너 내부 경로
자 이제 위에서 잠깐 언급했던 바인드 마운트(Bind Mounts)에 대해 알아보자.
호스트 머신상에 매핑될 컨테이너의 경로를 설정할 수 있다.
컨테이너는 바인드 마운트에 넣은 소스 코드를 인식하여
복사본에서 복사하지않고 바인딩 마운트에서 복사한다.
-> 영구적이고 편집이 가능한 데이터에 적합하다.
named volume(명명된 볼륨)은 영구 데이터에 적합하지만 편집은 실제로 불가능하다.
docker run -v /app/data.... -> 익명 볼륨 -> 컨테이너에 이미 존재하는 특정 데이터를 잠그는데 유용
docker run -v Name:/app/data... -> 명명 볼륨 ->
docker run -v /path/to/code:/app/code ... -> 바인드 마운트
'DevOps > Docker' 카테고리의 다른 글
Docker Compose (2) | 2024.02.06 |
---|---|
컨테이너 교차 통신, Docker로 다중 어플리케이션 구성하기 (0) | 2024.02.06 |
Docker 이미지 & 컨테이너 (0) | 2024.02.06 |
컨테이너 만들어 보기 (1) | 2024.01.14 |
Docker와 container (0) | 2024.01.11 |