도커에 대해서 공부하다보니 도커 파일을 계층으로 나눠서 저장할 수 있는 '유니온 마운트'기술과 도커 허브에 대해 알게되었고 각각이 무엇인지 찾아보게되었습니다,.
여러 개의 파일 시스템을 하나의 파일 시스템으로 취급할 수 있도록 해주는 것입니다.
UFS에서는 기존 레이어 위에 새로운 레이어가 쌓일 경우, 하위 레이어는 읽기 전용 상태가 됩니다. 또한 상위 레이어에서 하위 레이어에 쓰기 작업을 수행할 경우, 하위 레이어를 복사하여 사용하기 떄문에 상위 레이어에서는 하위 레이어에 아무런 영향을 주지않습니다.
image를 이용하여 Container를 기동한다는 건, 이렇게 차곡차곡 쌓인 image layer를 먼저 하단에 깔아두고(Read-Only Image Layer), 최종적으로 맨 위에 Container layer(Writable layer)를 얹은 후, 이 모든 layer을 결합하여 사용자에게 하나의 File system view(root filesystem)으로 제공하는 것입니다.
Union Mount를 지원하는 파일 시스템
복수의 파일 시스템을 하나의 파일 시스템으로 마운트하는 기능으로, 두 파일 시스템에서 동일한 파일이 있다면 나중에 마운트된 파일 시스템의 파일을 오버레이합니다.
하위 파일시스템에 대한 쓰기 작업은 CoW(Copy on Write)전략에 따라 복사본을 생성하여 수행하므로 원본 파일 시스템은 변하지 않는게 특징입니다.
Linux, FreeBSD, NetBSD를 위해 초기에 구현된 유니언 파일 시스템입니다.
AUFS(Advancded Multi Layered Unification Filesystem)은 리눅스 환경에서 Union Mount를 제공하는 기법입니다.
UnionFS를 완전히 재작성하여 신뢰성과 성능을 개선하면서도 Writable Branch Balancing과 같은 새로운 개념을 도입했습니다.
동일한 경로에 동일한 파일 이름이 있는 경우, AUFS Mount가 된 폴더내에서는 오직 Branch의 가장 마지막에 있는 폴더의 파일만 볼 수 있씁니다.
file_01 파일은 /layer_03 폴더와 /layer_01 폴더에 있지만 /mnt 폴더 내에서는 /layer_01의 file_01만 보이게됩니다.
/mnt 폴더에서 파일을 쓰는 경우, 써진 파일은 AUFS의 RW Branch 폴더에 그대로 저장됩니다.
/mnt 폴더 내에서 file_01를 변경하는 경우 AUFS는 변경된 일부분이 아니라 변경된 파일 전체를 /layer_rw폴더에 복사합니다. /layer_02 폴더 안에 원본 파일 그대로 유지되는 것을 알 수 있습니다.
파일이나 폴더를 지울 경우 RW Branch 폴더에 .wh. Writeout 파일을 생성하여 AUFS Mount가 된 폴더 내에서는 파일이 보이지않지만 원본은 유지됩니다.
file_01 파일을 삭제할 경우, RO Branch 폴더 안에 있는 Whiteout파일의 역할도 나타냅니다. Mount시 RO Branch에 +wh 옵션을 주었기 때문에 RO Branch의 Whiteout 파일이 하위 Branch의 파일을 숨깁니다.
주류 리눅스 커널에 통합된 버전입니다.
Container의 base가 되는 image layer(read-only layer)에 있는 내용을 변경하고 싶으면 어떻게 해야할까요?
이러한 경우에 Docker는 Copy-on-Write 기법을 사용합니다.
기존의 image 위에 추가되는 내용은 Writable layer에 그냥 기록하면 되지만
image의 기존 내용이 변경해야할 경우에는 data를 Writable layer로 먼저 Copy한 후에 이를 변경하는 기법을 사용합니다.
UFS는 이 Docker Storage Driver에 의해 구현됩니다.
Container에서 사용자가 UFS를 통해 Filesystem을 쉽게 사용할 수 있는 것은 이 Storage Driver가 있기 때문입니다. Copy-on-Write기법을 실현하는 것도 이 Storage Driver입니다.
Storage Driver는 container내에서 파일 I/O처리를 담당합니다.
다양한 Storage Driver가 존재하며 Pluggable 한 구조로 되어 있기 때문에, Docke에서 Storage Driver를 선택하여 사용할 수 있습니다.
Container상에서 변경되는 사항들은 Storage Driver의 도움에 의해 Backing filesystem에 저장되는 것입니다.
AUFS를 보면 Docker가 어떻게 Image Layer을 이용하는지 볼 수 있습니다.
Docker는 Container 생성시 Container를 위한 Root폴더와 RW폴더를 생성합니다.
그 후 Docker는 Base Image의 Layer들을 RO Branch로 설정하고,
Container RW 폴더를 RW Branch로 설정하여 Container의 Root 폴더에 AUFS Mount를 수행합니다.
Container가 동작하면서 변경하거나 추가한 파일들은 모두 Container의 RW 폴더에 남게되고 RO Branch들인 Base Image Layer들에게는 전혀 영향을 주지않습니다.
BaseImage Layer들은 변경되지않으므로 다른 Container들과 공유해서 사용가능합니다.
Container 파일 변경 내용은 RW 폴더에만 남기 때문에 Docker는 Snapshot 수행시 Container RW 폴더만 복사해서 관리합니다. Snapshot으로 생성한 이미지를 이용하여 Container를 생성할 경우 Docker는 복사해둔 RW 폴더를 새로운 Container의 RO Branch로 설정하여 이용합니다.
https://ssup2.github.io/theory_analysis/Union_Mount_AUFS_Docker_Image_Layer/
https://devaom.tistory.com/5
https://velog.io/@koo8624/Docker-%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C-Union-File-System
http://cloudrain21.com/examination-of-docker-containersize-ufs