Reading and Designing the Mount Tree
한국어 원문으로 표시합니다.
목표
/proc/self/mountinfo 를 직접 읽어 마운트 트리와 전파 방식을 파악하고, 바인드 마운트와 tmpfs 를 fstab 과 systemd 유닛 두 형식으로 작성합니다.
왜 중요한가
컨테이너 시대에 마운트가 어려워진 이유는 마운트 네임스페이스와 전파 방식 때문입니다. 호스트에서 붙인 볼륨이 컨테이너에 안 보이거나, 컨테이너를 지웠는데 마운트가 남아 디스크를 붙잡는 현상이 전부 여기서 나옵니다. 그리고 그 정보는 mount 명령 출력에 없고 /proc/self/mountinfo 의 선택 필드에만 있습니다. 이 파일을 읽을 줄 아는 것과 모르는 것의 차이가 큽니다.
이 실습은 우분투 24.04 VM 에서 돕니다. 그래서 7번에서 쓴 .mount 유닛을 systemctl start 로 실제로 붙여 봅니다 — 유닛 이름이 경로와 한 글자라도 다르면 systemd 가 거부한다는 것을, 규칙을 외워서가 아니라 거부당해 보면서 알게 됩니다. 예전에는 파드에서 돌아 mount 권한이 없었고, 읽기와 설계까지가 전부였습니다.
단계
/root/mnt디렉터리를 만들고,/proc/self/mountinfo의 각 줄에서마운트지점 타입 옵션세 값을 뽑아 공백으로 구분해/root/mnt/parsed.txt로 저장하세요. 최소 5줄이어야 하고/proc가 포함돼야 합니다.findmnt로 현재 마운트를타깃,소스,타입형식으로 출력해/root/mnt/findmnt.txt로 저장하세요.- 타입이
tmpfs인 마운트만 골라/root/mnt/tmpfs.txt로 저장하세요. 최소 1줄이어야 합니다. - 각 마운트의 전파 방식을 판정해
마운트지점 <shared|slave|private>형식으로/root/mnt/propagation.txt에 저장하세요. 최소 5줄이어야 합니다. /root/mnt/bind.fstab에 다음 바인드 마운트 줄을 한 줄 작성하세요. 원본/srv/data, 대상/var/www/data, 타입none, 옵션에bind와ro포함, dump0, pass0./root/mnt/tmpfs.fstab에 다음 tmpfs 줄을 한 줄 작성하세요. 마운트 지점/var/cache/app, 타입tmpfs, 옵션에size=256M,mode=1777,noexec,nosuid,nodev모두 포함, dump0, pass0.- 6번과 같은 내용을 systemd 유닛으로도 작성하세요. 파일 이름은 마운트 지점을 이스케이프한 정확한 이름이어야 하고
/root/mnt/아래에 둡니다.[Unit],[Mount],[Install]세 섹션이 있어야 하고[Mount]에는What,Where,Type,Options네 키가 있어야 합니다. /root/mnt/design.txt를 다음 4줄로 만드세요.MOUNTS=<1번 파일의 줄 수>/TMPFS=<3번 파일의 줄 수>/BIND_TARGET=/var/www/data/UNIT=<7번에서 만든 파일 이름(경로 제외)>
참고
- mountinfo 는 하이픈(
-) 하나를 경계로 앞뒤 필드 개수가 다릅니다. 마운트 지점은 5번째, 타입은 하이픈 다음 첫 필드입니다. findmnt -n -o TARGET,SOURCE,FSTYPE형태로 원하는 열만 뽑을 수 있습니다.- 유닛 이름은
systemd-escape --path --suffix=mount /var/cache/app로 얻을 수 있습니다. 도구가 없으면 규칙(앞 슬래시 제거, 나머지 슬래시를 하이픈으로)을 직접 적용하세요. - 흔한 실수 1: 1번에서 선택 필드 개수가 줄마다 달라 awk 의 고정 열 번호가 어긋나는 경우. 하이픈 위치를 먼저 찾으세요.
- 흔한 실수 2: 7번에서 유닛 이름을 임의로 정하는 경우. systemd 는 이름이 경로와 다르면 유닛을 거부합니다.
mountinfo 파싱
/root/mnt 디렉터리를 만들고, /proc/self/mountinfo 의 각 줄에서 마운트지점 타입 옵션 세 값을 뽑아 공백으로 구분해 /root/mnt/parsed.txt 로 저장하세요. 최소 5줄이어야 하고 /proc 가 포함돼야 합니다.
필드 구분자는 공백이고, 중간에 개수가 가변인 선택 필드가 있습니다. 하이픈 하나가 그 경계입니다.
findmnt 로 보기
findmnt 로 현재 마운트를 타깃,소스,타입 형식으로 출력해 /root/mnt/findmnt.txt 로 저장하세요.
findmnt 는 /proc 를 읽는 도구라 특권 없이 동작합니다. 출력 형식을 지정하는 옵션이 있습니다.
tmpfs 마운트만 골라내기
타입이 tmpfs 인 마운트만 골라 /root/mnt/tmpfs.txt 로 저장하세요. 최소 1줄이어야 합니다.
타입이 tmpfs 인 것만 필터링하세요. size 옵션이 있는 것과 없는 것을 눈여겨보세요.
전파 방식 표 만들기
각 마운트의 전파 방식을 판정해 마운트지점 <shared|slave|private> 형식으로 /root/mnt/propagation.txt 에 저장하세요. 최소 5줄이어야 합니다.
선택 필드에 shared: 나 master: 가 있으면 각각 shared, slave 입니다. 아무것도 없으면 private 입니다.
바인드 마운트 fstab 줄
/root/mnt/bind.fstab 에 다음 바인드 마운트 줄을 한 줄 작성하세요. 원본 /srv/data, 대상 /var/www/data, 타입 none, 옵션에 bind 와 ro 포함, dump 0, pass 0.
바인드 마운트의 타입 필드는 none 이고 옵션에 bind 가 들어갑니다. 읽기 전용도 함께 지정할 수 있습니다.
tmpfs fstab 줄
/root/mnt/tmpfs.fstab 에 다음 tmpfs 줄을 한 줄 작성하세요. 마운트 지점 /var/cache/app, 타입 tmpfs, 옵션에 size=256M, mode=1777, noexec, nosuid, nodev 모두 포함, dump 0, pass 0.
장치 자리에는 tmpfs 를 씁니다. 크기를 반드시 지정하고 보안 옵션 세 가지를 함께 넣으세요.
.mount 유닛 파일
6번과 같은 내용을 systemd 유닛으로도 작성하세요. 파일 이름은 마운트 지점을 이스케이프한 정확한 이름이어야 하고 /root/mnt/ 아래에 둡니다. [Unit], [Mount], [Install] 세 섹션이 있어야 하고 [Mount] 에는 What, Where, Type, Options 네 키가 있어야 합니다.
유닛 이름은 마운트 지점 경로를 이스케이프한 것이어야 합니다. systemd-escape 로 정확한 이름을 얻을 수 있습니다.
마운트 설계 문서
/root/mnt/design.txt 를 다음 4줄로 만드세요.
MOUNTS=<1번 파일의 줄 수> / TMPFS=<3번 파일의 줄 수> / BIND_TARGET=/var/www/data / UNIT=<7번에서 만든 파일 이름(경로 제외)>
값은 앞 단계에서 만든 파일에서 가져오면 됩니다. 개수는 줄 수로 세면 충분합니다.