tmpfs 마운트

tmpfs 마운트 (tmpfs mounts)

호스트와 컨테이너 사이에서 파일을 공유하면서 데이터를 영속화하는 방법으로 볼륨과 바인드 마운트를 배웠어요. 그런데 데이터를 아예 남기지 않는 게 목표일 때는 어떤 방법을 쓸까요? 리눅스에서 도커를 돌리고 있다면 세 번째 선택지가 있어요. 바로 tmpfs 마운트예요. 컨테이너가 멈추면 함께 사라지는, 메모리에만 떠 있는 임시 저장 공간이랍니다.

출처: https://docs.docker.com/engine/storage/tmpfs

본문

tmpfs 마운트로 컨테이너를 만들면, 컨테이너의 쓰기 가능한 레이어 밖에 파일을 만들 수 있어요. 볼륨이나 바인드 마운트와 달리 tmpfs 마운트는 임시적이고 호스트 메모리에만 유지돼요. 컨테이너가 멈추면 tmpfs 마운트가 제거되면서 거기 써 둔 파일도 사라져요. 호스트나 컨테이너 어디에도 데이터가 남지 않게 하고 싶을 때, 보안상의 이유나 애플리케이션이 대량의 비영속 상태를 써야 할 때 성능 보호를 위해 주로 써요.

메모리와의 관계

tmpfs는 데이터를 메모리에 저장하므로 그 사용량이 컨테이너의 메모리 cgroup 제한(--memory, Compose에선 mem_limit)에 포함돼요. tmpfs-size를 크게 잡는다고 해서 제한 밖의 여분 RAM이 생기는 건 아니에요. 마운트가 가득 차면 컨테이너가 여전히 OOM(메모리 부족)으로 죽을 수 있어요. 그리고 컨테이너의 메모리 지표에도 tmpfs 사용량이 잡혀요.

한 가지 짚고 넘어갈 점이 있어요. 도커의 tmpfs 마운트는 리눅스 커널의 tmpfs를 그대로 매핑한 것인데, 임시 데이터가 스왑 파일에 기록되어 파일시스템에 남을 수도 있어요. '완전히 사라진다'고 100% 단정하기는 어렵다는 뜻이에요.

기존 데이터 위에 마운트하기

컨테이너의 어떤 디렉터리에 이미 파일이 있는데 그 위에 tmpfs 마운트를 만들면, 기존 파일·디렉터리는 마운트에 가려져요. 리눅스 호스트의 /mnt에 파일을 저장해 둔 뒤 USB 드라이브를 /mnt에 마운트하면 USB 내용이 기존 내용을 가리는 것과 비슷해요. 컨테이너에서는 마운트를 떼서 가려진 파일을 다시 드러내는 방법이 간단치 않으니, 마운트 없는 컨테이너를 새로 만드는 게 최선이에요.

tmpfs 마운트의 한계

  • 볼륨·바인드 마운트와 달리 컨테이너끼리 tmpfs 마운트를 공유할 수 없어요.
  • 리눅스에서만 사용할 수 있어요.
  • tmpfs의 데이터는 컨테이너 메모리 제한에 포함되고, size=를 크게 줘도 제한이 올라가지 않아요.
  • tmpfs에 권한을 설정하면 컨테이너 재시작 후 권한이 초기화될 수 있어요. 일부 경우 uid/gid를 지정하는 게 우회책이 될 수 있어요.

명령으로 tmpfs 마운트하기

docker run에서 tmpfs를 마운트하는 방법은 --mount 플래그와 --tmpfs 플래그 두 가지예요.

  • --mount는 옵션을 명시적으로 표현해요. 일반적으로 이쪽이 권장돼요.
  • --tmpfs는 더 간결하고 마운트 옵션을 더 유연하게 지정할 수 있어요. 단, swarm 서비스에서는 --tmpfs를 쓸 수 없고 반드시 --mount를 써야 해요.

--tmpfs 옵션

--tmpfs 플래그는 콜론(:)으로 구분된 두 필드로 구성돼요. 첫 필드는 tmpfs로 마운트할 컨테이너 경로, 두 번째 필드는 마운트 옵션(선택)이에요. 주요 옵션을 볼게요.

  • ro / rw — 읽기 전용 / 읽기-쓰기(기본값).
  • nosuid / suid — 실행 중 setuid·setgid 비트를 무시 / 허용(기본값).
  • nodev / dev — 장치 파일을 만들 수 없음 / 만들고 완전히 기능함.
  • exec / noexec — 마운트 파일시스템에서 실행 파일 실행 허용 / 금지.
  • sync / async — 파일시스템 I/O를 동기적으로 / 비동기적으로(기본값).
  • dirsync — 디렉터리 갱신을 동기적으로.
  • atime / noatime / diratime / nodiratime — 파일·디렉터리 접근 시간 갱신 여부.
  • size — tmpfs 마운트 크기(예: size=64m).
  • mode — 파일 모드(퍼미션, 예: mode=1777).
  • uid / gid — 소유자의 사용자/그룹 ID.
  • nr_inodes / nr_blocks — 최대 inode/블록 수.

예시는 이렇게 써요.

$ docker run --tmpfs /data:noexec,size=1024,mode=1777

리눅스 mount 명령의 tmpfs 기능 중 도커 --tmpfs가 지원하지 않는 것도 있어요. 고급 옵션이 필요하면 privileged 컨테이너를 쓰거나 도커 밖에서 마운트를 구성해야 할 수 있어요. 다만 --privileged로 실행하면 컨테이너에 과도한 권한이 주어져 호스트가 보안 위험에 노출될 수 있으니, 꼭 필요한 신뢰할 수 있는 환경에서만 써야 해요.

--mount 옵션

--mount 플래그는 여러 <key>=<value> 쌍을 콤마로 구분해 쓰는데, 키의 순서는 중요하지 않아요. type=tmpfs의 주요 옵션을 보면 이렇게 돼요.

  • destination(별칭 dst, target) — tmpfs로 마운트할 컨테이너 경로.
  • tmpfs-size — tmpfs 크기(바이트). 지정하지 않으면 기본 최대 크기는 호스트 전체 RAM의 50%예요.
  • tmpfs-mode — tmpfs의 파일 모드를 8진수로 지정(예: 700, 0770). 기본값은 1777(모두 쓰기 가능)이에요.

사용 예시

컨테이너 안에서 tmpfs 마운트를 쓰려면 --tmpfs 또는 --mount type=tmpfs를 사용해요. tmpfs 마운트에는 source가 없어요. Nginx 컨테이너의 /app에 tmpfs 마운트를 만드는 예시를 볼게요.

$ docker run --mount type=tmpfs,destination=/app nginx:latest

마운트가 실제로 tmpfs인지 확인하려면 docker inspect 출력의 Mounts 섹션을 보면 돼요.

더 알아보기