데이터 디스크 마운트를 확인한 뒤 서비스 시작하기
데이터 디스크 마운트에 실패해도 애플리케이션에서 바로 오류가 발생하는 것은 아닙니다. 마운트 지점으로 쓰려던 /srv/data는 여전히 시스템 디스크의 일반 디렉터리로 남아 있으므로, 서비스가 계속 데이터를 기록하다가 시스템 디스크 공간을 모두 소진할 수 있습니다. 마운트를 복구하면 이렇게 기록된 파일은 마운트된 파일 시스템에 가려지고, 어느 쪽이 올바른 데이터인지 구분하기 어려운 두 벌의 데이터가 생깁니다. 운영 투입 전 검증에서는 디렉터리가 존재하는지만 볼 것이 아니라, 해당 경로를 실제로 제공하는 파일 시스템을 확인해야 합니다.
1. 데이터 디스크 식별 정보와 작업 범위부터 확인하기
이 글은 Ubuntu Server 24.04 LTS에서 이미 ext4 파일 시스템이 있는 데이터 파티션을 사용하는 경우를 다룹니다. 파티션 생성이나 포맷은 수행하지 않습니다. 명령은 SSH로 서버에 접속해 실행합니다. CloudSFP 접속 정보는 결제 후 콘솔에서 확인할 수 있으며, 주소가 여러 개이면 첫 번째 주소를 사용합니다.
기본 구성은 각각 직접 연결된 1TB NVMe 두 개이며, 하드웨어 RAID는 없습니다. 장치 번호만으로 시스템 디스크와 데이터 디스크를 구분할 수 없고, 번호를 보고 중복 구성 여부를 판단해서도 안 됩니다. 이미 소프트웨어 RAID나 다른 스토리지 계층을 사용 중이라면 상위 계층의 파일 시스템을 마운트해야 합니다. 해당 계층을 우회해 구성원 디스크를 직접 마운트하면 안 됩니다.
lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS
sudo blkid
findmnt -T /
findmnt -T /srv
용량, 파일 시스템 유형, 현재 마운트 지점, 설치 기록을 함께 확인해 대상 파티션을 식별하고 UUID를 기록합니다. UUID는 장치 열거 이름보다 안정적이지만, 언제나 고유한 것은 아닙니다. 파일 시스템을 복제하면 UUID도 복제될 수 있습니다. 중복이 발견되면 먼저 식별 정보 충돌을 해결하고, 그 상태로 부팅 설정에 등록하지 않습니다.
아래 변경은 데이터 디스크를 업무에 사용하기 전에 완료해야 합니다. 이미 운영 중인 서버라면 먼저 쓰기 작업을 중지하고 백업과 복구 절차를 확인해야 합니다. 테스트를 위해 사용 중인 파일 시스템을 바로 마운트 해제해서는 안 됩니다.
2. 시험 마운트 후 fstab에 등록하기
빈 마운트 지점을 만들고 내부에 파일이 있는지 확인합니다. 숨김 파일도 확인해야 합니다. 디렉터리가 비어 있지 않다면 먼저 파일이 생긴 경위를 조사하고, 삭제하거나 덮어쓰지 않습니다.
sudo mkdir -p /srv/data
sudo find /srv/data -mindepth 1 -maxdepth 1 -print
read -r -p 'Filesystem UUID: ' DATA_UUID
sudo blkid -U "$DATA_UUID"
sudo mount -t ext4 -o ro "UUID=$DATA_UUID" /srv/data
findmnt -M /srv/data -o TARGET,SOURCE,FSTYPE,OPTIONS,UUID
blkid 출력이 기록해 둔 디스크 식별 정보와 일치할 때만 마운트를 진행합니다. 첫 읽기 전용 마운트는 내용을 확인하기 위한 절차이며, 손상된 파일 시스템을 복구하는 방법이 아닙니다. 여기서 findmnt -M은 지정한 경로 자체가 마운트 지점인지 확인합니다. 반면 findmnt -T는 해당 경로를 제공하는 파일 시스템을 찾으므로, 데이터 디스크가 마운트되지 않은 상태에서는 루트 파일 시스템을 반환할 수 있습니다. 따라서 이 명령이 성공적으로 종료되었다는 이유만으로 마운트가 정상이라고 판단해서는 안 됩니다.
마운트 소스와 내용을 확인한 뒤 읽기 전용 마운트를 해제합니다. /etc/fstab을 백업한 다음 편집하며, 같은 마운트 지점을 중복으로 추가하지 않습니다. 예시의 UUID는 앞에서 확인한 실제 값으로 바꿔야 합니다.
UUID=<已核对的文件系统UUID> /srv/data ext4 defaults,nofail,x-systemd.device-timeout=15s 0 2
이 설정은 디스크가 없어도 시스템 부팅을 계속 진행하도록 합니다. 장치 대기 시간 상한인 15초는 이 예시에서 선택한 값일 뿐, 제공 시간이나 복구 시간을 보장하는 값이 아닙니다. 업무 요건상 디스크가 없으면 시스템 부팅을 막아야 한다면 부팅 정책을 별도로 설계해야 하며, nofail을 그대로 적용해서는 안 됩니다.
sudo umount /srv/data
sudo cp -a /etc/fstab /etc/fstab.before-data-mount
sudoedit /etc/fstab
sudo findmnt --verify --verbose
sudo systemctl daemon-reload
sudo mount /srv/data
findmnt -M /srv/data -o TARGET,SOURCE,FSTYPE,OPTIONS,UUID
검증에 실패하면 먼저 설정을 수정하고, 마운트를 계속 진행하지 않습니다. 대상 경로만 마운트해 모든 파일 시스템을 한꺼번에 마운트하면서 다른 설정 문제를 놓치는 일을 피합니다. 구문 검사를 통과했다고 해서 장치를 실제로 사용할 수 있다는 뜻은 아니므로, 실제 마운트 결과도 확인해야 합니다.
3. 서비스 시작에 마운트 의존성 설정하기
nofail은 시스템 부팅 동작을 제어할 뿐, 애플리케이션의 안전한 동작까지 보장하지는 않습니다. 데이터 디렉터리를 사용하는 서비스에는 마운트 의존성을 명시해야 합니다. 아래의 app.service는 실제 업무용 서비스 유닛을 나타내는 예시입니다. 실제 유닛 이름으로 바꾸고, 해당 유닛이 데이터를 기록하는 프로세스를 시작하는지 확인해야 합니다.
sudo systemctl edit app.service를 실행하고 다음 내용을 추가합니다.
[Unit]
RequiresMountsFor=/srv/data
AssertPathIsMountPoint=/srv/data
RequiresMountsFor는 해당 경로에 접근하는 데 필요한 마운트를 시작하고 시작 순서를 설정합니다. 단언 조건은 “디렉터리는 있지만 마운트 지점은 아닌” 상태에서 서비스가 시작되지 않도록 합니다. 두 설정 모두 잘못된 디스크를 식별할 수 없으며, 애플리케이션의 데이터 일관성 검사를 대신하지도 못합니다. 따라서 UUID가 올바른 대상의 것인지 확인하는 절차는 별도로 수행해야 합니다.
sudo systemctl daemon-reload
sudo systemctl cat app.service
sudo systemctl show app.service -p Requires -p After
추가한 오버라이드 설정이 적용되었는지 확인하고, 애플리케이션의 실제 데이터 디렉터리가 /srv/data 아래에 있는지 점검합니다. 시작 스크립트에서 경로를 따로 변경하면 의존성이 올바르게 설정되어 있어도 엉뚱한 위치에 기록할 수 있습니다. 예약 작업, 수동 실행 스크립트, 다른 서비스에는 이러한 제약이 자동으로 적용되지 않으므로 각각 확인해야 합니다.
마운트가 성공한 뒤 업무용 하위 디렉터리를 만들고, 실제 서비스 계정에 맞춰 소유자와 권한을 설정합니다. 데이터 디스크 전체에 모든 계정의 쓰기 권한을 허용하지 말고, 마운트 설정에 인증 정보를 기록하지 않습니다.
4. 실제 데이터 기록 전에 디스크 부재와 복구 상황 테스트하기
테스트는 업무 데이터가 없고 쓰기 작업도 진행되지 않는 단계에서 수행해야 합니다. 먼저 애플리케이션을 중지한 다음 데이터 마운트 유닛을 중지합니다. /srv/data에 해당하는 유닛 이름은 systemd-escape --path --suffix=mount /srv/data로 확인할 수 있습니다. 복잡한 경로의 유닛 이름을 임의로 추측해서는 안 됩니다.
sudo systemctl stop app.service
sudo systemctl stop srv-data.mount
sudo systemctl mask --runtime srv-data.mount
sudo systemctl start app.service
sudo systemctl status app.service srv-data.mount --no-pager
마운트 유닛을 일시적으로 마스킹하는 이유는 마운트를 사용할 수 없는 상황을 재현하고, 애플리케이션을 시작할 때 자동으로 다시 마운트되는 것을 막기 위해서입니다. 예상 결과는 서비스 시작 실패이며, 업무용 프로세스가 실행되지 않아야 합니다. 마운트 해제 시 사용 중이라는 메시지가 나오면 어떤 프로세스가 점유하고 있는지 확인합니다. 강제 마운트 해제나 지연 마운트 해제로 이 확인 절차를 우회하지 않습니다.
이 상태에서 마운트 아래에 가려져 있던 원래 /srv/data 디렉터리에 새 파일이 생겼는지 확인합니다. 테스트가 끝나면 먼저 마스킹을 해제하고 마운트를 복구합니다.
sudo systemctl unmask --runtime srv-data.mount
sudo systemctl start srv-data.mount
findmnt -M /srv/data -o TARGET,SOURCE,FSTYPE,OPTIONS,UUID
sudo systemctl reset-failed app.service
sudo systemctl start app.service
마운트 소스가 일치하고 애플리케이션 상태 검사를 통과해야 복구가 완료된 것으로 판단합니다. 검증을 마칠 때는 임시 마스킹이 해제되었는지 반드시 확인해야 합니다. 시작 의존성은 주로 서비스 시작 단계를 보호하는 장치이지, 실행 중 발생하는 디스크 장애를 감지하는 장치는 아닙니다. 이후에도 애플리케이션의 오류 처리와 모니터링이 필요합니다.
5. 다시 확인할 수 있는 운영 투입 기록 남기기
기록에는 디스크 식별 정보, UUID, 마운트 지점, 파일 시스템 유형, fstab 변경 사항, 서비스 오버라이드 설정, 디스크 부재 테스트 결과가 포함되어야 합니다. 재부팅 검증은 업무에 투입하기 전에 수행하고, 마운트가 먼저 완료된 뒤 서비스가 시작되는지 확인합니다. 현재 수동 마운트가 한 번 성공했다는 사실로 부팅 검증을 대신할 수는 없습니다.
마운트 후 시스템 디스크 공간 사용량에 이상이 발견되면, 먼저 마운트에 가려진 기존 파일이 있는지 확인합니다. 관련 쓰기 작업을 중지하고 점검을 계획해야 합니다. 운영 중에 마운트를 해제한 뒤 곧바로 파일을 삭제해서는 안 되며, 원래 디렉터리의 내용과 데이터 디스크의 내용을 무작정 합쳐서도 안 됩니다.
최종 통과 조건은 올바른 소스가 사용되고, 해당 경로가 실제로 마운트되어 있으며, 서비스 의존성이 적용되고, 디스크가 없을 때 잘못된 위치에 기록하지 않으며, 복구 후 상태 검사를 통과하는 것입니다. 마운트 설정은 중복 구성도 백업도 제공하지 않습니다. 이 두 가지는 별도로 설계하고 검증해야 합니다.
자주 묻는 질문
마운트에 장치 이름 대신 UUID를 사용하는 이유는 무엇인가요?
장치가 인식되는 순서는 달라질 수 있습니다. 확인된 고유 파일 시스템 UUID를 사용해야 합니다. 복제된 파일 시스템은 UUID가 중복될 수 있으므로 lsblk, blkid, findmnt로 마운트 원본을 대조합니다.
nofail만 설정하면 시스템 디스크에 잘못 기록하는 일을 막을 수 있나요?
아니요. nofail은 마운트 실패 시에도 부팅을 계속하도록 할 뿐입니다. 서비스에 RequiresMountsFor와 AssertPathIsMountPoint를 설정하고 마운트 원본도 확인해야 합니다.