Docker Volume 사용하기
지난 장에서 우리는 Container 내부에 직접 파일(dll,aspx)을 복사해 본 적이 있다. 그러나 컨테이너가 제거되면 내부의 파일도 사라지게 된다. 컨테이너의 상태와 상관 없이 파일을 유지할 수 없을까? 이번 포스트에서는 그러한 방법에 대해서 알아보도록 하겠다.
일단 호스트의 “D:\data” 하위에 다음과 같은 파일들을 만들어 놓는다.
bind mount
이전 포스트 Dockerfile을 이용하여 image에 프로그램설치하기 에서 생성해 놓았던 shw-installpgm-devexpress3(asp.net과 devexpress가 설치되어 있는 이미지) 를 기반으로 컨테이너를 하나 만든다. 이때 -v 옵션을 이용하여 호스트의 “D:\data” 폴더를 컨테이너 내부의 “C:\inetpub\wwwroot” 폴더에 마운트한다.
# -v D:\data:c:\inetpub\wwwroot
# -v 호스트폴더경로:컨테이너내부의폴더경로
# 호스트의 "D:\data" 폴더를 컨테이너 내부의 "C:\inetpub\wwwroot" 폴더에 마운트
docker run -it --name shw-aspnet-devexpress-container -v D:\data:c:\inetpub\wwwroot shw-installpgm-devexpress3
올라온 컨테이너의 내부로 진입하여 “C:\inetpub\wwwroot” 폴더를 확인해보면 호스트의 “D:\data” 폴더의 파일들이 그대로 들어 있는 것을 확인할 수 있다.
컨테이너 내부의 “C:\inetpub\wwwroot” 폴더에서 파일을 하나 생성하면 호스트의 D:\data폴더에도 같은 파일이 추가되어있음을 확인할 수 있다.
호스트의 로컬 경로가 아닌 네트워크에 존재하는 경로를 bind mount 하고 싶다면?
다음 예제를 참고하자.(Windows10 , Windows Server 2016 이상에 해당된다.)
#만약 로컬의 경로가 아닌 네트워크경로(203.245.245.245)라면
#1. 203.245.245.245 서버에서 파일공유설정을 먼저 해준다.
#2. 호스트에서 Remove-SmbGlobalMapping을 이용해 먼저 존재하는 공유를 끊어준다.
Remove-SmbGlobalMapping -LocalPath "X:"
Remove-SmbGlobalMapping -LocalPath "Y:"
#3. 호스트에서 203.245.245.245의 공유폴더에 접근하는 계정을 설정해준다.
$secpasswd = ConvertTo-SecureString 'password' -AsPlainText -Force;
$creds = New-Object System.Management.Automation.PSCredential ("local\PI2DevUser", $secpasswd);
#4. 호스트에서 203.245.245.245의 공유폴더를 특정 드라이브로 매핑시켜준다.
New-SmbGlobalMapping -RemotePath "\\203.245.245.245\websites" -Credential $creds -LocalPath X:
New-SmbGlobalMapping -RemotePath "\\203.245.245.245\files" -Credential $creds -LocalPath Y:
#5. -v옵션을 사용하여 docker run을 실행시켜준다.
docker run -p 8080:80 -it --name shw-aspnet-devexpress-container `
-v "x:\testsite:c:\websites\testsite" `
-v "x:\common service:c:\websites\common service" `
-v "y:\testsitefiles:c:\files" `
shw-aspnet-devexpress
Volume 사용
위에서 사용했던 호스트의 파일시스템의 경로를 직접 사용하는 bind mount에는 일부 기능이 제한되어 있으므로 Volume을 사용하는 것이 좋다. Volume을 사용하는 방법에 대해서 설명하겠다.
# 호스트의 폴더경로이동 한다.
cd "D:\data"
# 그리고 bind mount에서 사용했던 -v [호스트폴더경로]:[컨테이너폴더경로] 대신 -v [볼륨명]:[컨테이너폴더경로] 으로 사용하면 된다. 여기서 볼륨명은 hostedata 로 하겠다.
docker run -it --name shw-aspnet-devexpress-container -v hostdata:c:\inetpub\wwwroot shw-installpgm-devexpress3
컨테이너 내부로 진입해 “c:\inetpub\wwwroot” 경로를 살펴보면 하위에 파일을 생성하거나 하지 않았기 때문에 아직 파일이 없다.
docker volume ls
이 명령어를 통해 볼륨을 확인해 본다. 생성했던 컨테이너를 삭제하고 또 다시 볼륨을 확인해본다.
컨테이너의 상태와 상관 없이 볼륨은 계속 남아 있다. 참고로 볼륨은 별도의 명령어를 통해 삭제해주지 않는한 계속 남아 있는다.
[참고] 볼륨 삭제 명령어
# 특정볼륨삭제
# docker volume rm 볼륨명
docker volume rm hostdata
# 전체볼륨삭제
docker volume prune
[참고] 볼륨 상세 정보 확인
# 볼륨 상세 정보
# docker volume inspect 볼륨명
docker volume inspect hostdata
[
{
"CreatedAt": "2019-11-22T01:02:25+09:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "C:\\ProgramData\\Docker\\volumes\\hostdata\\_data",
"Name": "hostdata",
"Options": null,
"Scope": "local"
}
]
이번에는 다음 명령어를 통해 볼륨을 직접 생성해본다.
# docker volume create [볼륨명]
docker volume create hostdata2
# docker volume 목록 확인
docker volume ls
생성한 hostdata2 볼륨이 보인다.
shw-aspnet-devexpress-container 이라는 이름의 컨테이너를 생성하고 컨테이너 내부의 “c:\inetpub\wwwroot” 폴더를 호스트의 hostdata2 볼륨과 연결한다. 그리고 컨테이너 내부의 “c:\inetpub\wwwroot” 폴더하위에 파일을 생성해 본다.
# hostdata2 볼륨을 사용하는 shw-aspnet-devexpress-container 컨테이너 생성
docker run -it --name shw-aspnet-devexpress-container -v hostdata2:c:\inetpub\wwwroot shw-installpgm-devexpress3
# shw-aspnet-devexpress-container 컨테이너의 c:\inetpub\wwwroot폴더는 호스트의 hostdata2 볼륨에 연결된다.
# 컨테이너 내부진입
docker exec -i -t shw-aspnet-devexpress-container powershell
# C:\inetpub\wwwroot 폴더로 이동
cd C:\inetpub\wwwroot
# html 파일생성
New-Item -Name test1.html -ItemType File
New-Item -Name test2.html -ItemType File
shw-aspnet-devexpress-container2 이라는 이름의 컨테이너를 생성하고 컨테이너 내부의 “c:\inetpub\wwwroot” 폴더를 호스트의 hostdata2 볼륨과 연결한다. 그리고 컨테이너 내부의 “c:\inetpub\wwwroot” 폴더 하위 목록을 확인해 보자
# hostdata2 볼륨을 사용하는 shw-aspnet-devexpress-container2 컨테이너 생성
docker run -it --name shw-aspnet-devexpress-container2 -v hostdata2:c:\inetpub\wwwroot shw-installpgm-devexpress3
# shw-aspnet-devexpress-container2 컨테이너의 c:\inetpub\wwwroot폴더는 호스트의 hostdata2 볼륨에 연결된다.
# 컨테이너 내부진입
docker exec -i -t shw-aspnet-devexpress-container2 powershell
# C:\inetpub\wwwroot 폴더 내부 목록 확인
dir C:\inetpub\wwwroot
shw-aspnet-devexpress-container 컨테이너에서 저장했던 파일들이 shw-aspnet-devexpress-container2 컨테이너에서도 그대로 보이는 것을 확인할 수 있다.
결론적으로 컨테이너 상태에 상관 없이 볼륨에 연결만 시켜준다면 파일을 잃어버리지 않고 유지할 수 있게 되는 것이다. 그리고 컨테이너간에도 볼륨을 통해 파일을 공유할 수 있게 된다.
참고 URL
https://adamtheautomator.com/docker-volumes-windows/
https://blog.sixeyed.com/docker-volumes-on-windows-the-case-of-the-g-drive/
댓글남기기