네트워크 스토리지
저장장치를 네트워크 너머에 두는 방법이다. 파일을 나눠 주는 NAS와, 디스크 자체를 빌려주는 SAN이 기본 두 갈래다.
목차 (7)
DAS, NAS, SAN: 파일 시스템이 어디 있나
저장장치를 서버에 잇는 방법은 셋으로 나뉜다. DAS(Direct-Attached Storage)는 SATA·SAS·NVMe 케이블로 서버에 직접 붙인 디스크다. PC의 SSD도 DAS다. NAS(Network-Attached Storage)는 파일 시스템을 가진 장비가 이더넷으로 파일을 나눠 준다. SAN(Storage Area Network)은 디스크 자체(블록 장치)를 네트워크 너머에서 빌려준다.
셋을 가르는 질문은 하나다. 파일 시스템이 어느 쪽에 있나? DAS와 SAN은 서버가 파일 시스템을 갖고 블록을 요청한다. 서버 입장에서 SAN 볼륨(LUN)은 그냥 로컬 디스크처럼 보인다. NAS는 장비가 파일 시스템을 갖고, 클라이언트는 경로와 범위로 파일을 요청한다. 앞 글의 블록과 파일 스토리지 구분이 그대로 네트워크 위로 옮겨 간 것이다.
NFS: 유닉스의 파일 공유
NFS(Network File System)는 리눅스·유닉스의 표준 파일 공유 프로토콜이다. 클라이언트는 원격 디렉터리를 자기 파일 시스템의 한 곳에 마운트하고, 앱은 로컬 파일처럼 open·read·write를 부른다. 커널의 NFS 클라이언트가 이를 RPC 요청으로 바꿔 서버에 보낸다. 판마다 설계가 크게 다르다.
| 판 | 표준 | 특징 |
|---|---|---|
| NFSv3 | RFC 1813(1995) | 상태 없음(stateless). 서버는 열린 파일을 기억하지 않는다. 잠금(NLM)과 마운트는 따로 된 보조 프로토콜 |
| NFSv4.0 | RFC 7530 | 상태 있음(stateful). OPEN·CLOSE와 잠금이 본 프로토콜 안에, 포트 2049 하나, 여러 연산을 묶는 COMPOUND, 위임(delegation) |
| NFSv4.1 | RFC 8881 | 세션과 정확히 한 번 처리(exactly-once), 데이터를 여러 서버에서 병렬로 읽는 pNFS |
| NFSv4.2 | RFC 7862 | 서버 안 복사(server-side copy), 빈 구간이 있는 파일(sparse) 다루기 |
v3가 상태를 두지 않은 것은 서버가 재시작해도 클라이언트가 같은 요청을 다시 보내면 그만이게 하려는 설계였다. 대신 "누가 이 파일을 열었나"를 모르니 잠금과 캐시 일관성을 따로 붙여야 했다. v4는 서버가 열린 파일과 잠금을 상태로 들고, 각 클라이언트에 리스(lease)를 준다. 클라이언트가 리스 시간 안에 연락하지 않으면 서버는 그 클라이언트가 죽었다고 보고 잠금을 거둔다. 위임은 다른 클라이언트가 그 파일을 쓰지 않는 동안 한 클라이언트가 캐시만으로 읽고 쓰게 해 주는 허락이다.
마운트할 때 세션을 맺는다. 요청마다 슬롯·순번을 달아, 응답을 잃어 다시 보낸 요청도 서버가 한 번만 처리한다(4.1의 정확히 한 번).
NFS의 캐시 약속은 닫았다 열면 보인다(close-to-open)이다. 한 클라이언트가 파일을 닫으면 쓴 내용을 모두 서버로 보내고, 다른 클라이언트는 다음에 열 때 서버에 속성을 물어 새 내용을 본다. 두 클라이언트가 파일을 열어 둔 채 동시에 고쳐 쓰는 앱(로그 파일을 여럿이 이어 쓰는 경우 등)은 바이트 범위 잠금 없이는 서로의 쓰기를 늦게 보거나 덮어쓴다.
보안 기본값도 알아 둘 것이 있다. 가장 흔한 인증 방식(AUTH_SYS)은 클라이언트가 보낸 사용자 번호(UID)를 그대로 믿는다. 클라이언트 한 대의 관리자 권한을 얻으면 아무 UID로나 행세할 수 있다는 뜻이다. 그래서 내보내기(export)를 믿는 주소로만 제한하고, 민감한 곳은 Kerberos 인증과 암호화(sec=krb5p)를 쓴다.
SMB: 윈도의 파일 공유
SMB(Server Message Block)는 윈도의 파일 공유 프로토콜이다. \\server\share 경로나 네트워크 드라이브가 SMB다. 리눅스와 NAS에서는 Samba가 같은 프로토콜을 구현해, 집 NAS 대부분이 윈도·맥 클라이언트에 SMB로 공유를 내준다. 클라이언트와 서버는 연결할 때 둘 다 지원하는 가장 높은 판(dialect)을 고른다. 윈도 8·Server 2012가 SMB 3.0, 윈도 10 1607·Server 2016부터 SMB 3.1.1이다(Microsoft SMB 개요).
SMB 3이 바꾼 것은 크게 셋이다. 첫째, 암호화다. 공유나 서버 단위로 켜면 오가는 데이터를 AES로 암호화하고, SMB 3.1.1에서는 AES-128-GCM이 기본으로 협상되며 윈도 11·Server 2022부터 AES-256도 쓴다. 3.1.1의 사전 인증 무결성(pre-authentication integrity)은 연결 협상 메시지를 해시로 묶어, 중간자가 낮은 판으로 끌어내리는 공격을 막는다(SMB 보안 강화). 둘째, 멀티채널이다. NIC가 여럿이면 세션 하나를 여러 TCP 연결로 나눠 대역폭을 더하고 한 줄이 끊겨도 이어 간다. 셋째, RDMA로 커널을 거치지 않고 메모리끼리 옮기는 SMB Direct다.
옛 판은 끄는 것이 원칙이다. SMB 1.0은 윈도 10·Server 1709부터 기본으로 설치되지 않는다. 2017년 WannaCry 랜섬웨어가 퍼진 통로가 SMB 1.0의 취약점(EternalBlue)이었다. 445번 포트를 인터넷에 열어 두지 않는 것도 기본이다. 인터넷 너머에서 써야 하면 VPN이나, 최신 윈도 서버가 지원하는 SMB over QUIC(UDP 443, TLS 1.3)을 쓴다.
블록 프로토콜: iSCSI, Fibre Channel, NVMe-oF
SAN은 블록 명령을 네트워크에 실어 나른다. iSCSI는 디스크 명령 체계인 SCSI를 TCP/IP에 싣는다(RFC 7143). 요청하는 쪽(서버)이 이니시에이터(initiator), 디스크를 내주는 쪽이 타깃(target)이고, 타깃은 iqn.2026-10.com.example:db1 같은 이름과 TCP 3260번 포트로 찾는다. 타깃 안의 볼륨 하나하나가 LUN(Logical Unit Number)이다. 보통 이더넷 스위치를 그대로 쓰니 싸고 흔하지만, 스토리지 트래픽은 따로 된 VLAN이나 망으로 떼고 CHAP 인증을 켠다.
Fibre Channel(FC)은 처음부터 스토리지용으로 만든 전용 망이다. 받는 쪽이 비울 수 있는 버퍼 수(credit)만큼만 보내는 흐름 제어로 패킷을 버리지 않는다(무손실). 장비 주소는 WWN이고, 스위치의 존(zone)과 배열의 LUN 마스킹으로 어느 서버가 어느 볼륨을 볼지 정한다. 지연이 짧고 예측 가능하지만 HBA 카드·스위치·운영 지식이 따로 든다.
NVMe over Fabrics(NVMe-oF)는 SCSI 대신 NVMe 명령을 그대로 네트워크에 싣는다. NVMe는 SSD를 위해 만든 명령 체계라 큐를 수만 개 두고 병렬로 처리한다. SCSI로 번역하는 층이 없으니 원격 SSD도 로컬에 가까운 지연을 낸다. NVM Express가 PCIe, RDMA, TCP 전송 규격을 따로 낸다(NVMe 규격 목록). NVMe/TCP는 보통 이더넷에서 그대로 돌고, NVMe/RDMA(RoCE v2)는 더 빠르지만 스위치를 무손실로 맞춰야 한다. FC 위의 NVMe(FC-NVMe)도 있다.
여럿이 함께 쓰기와 잠금
SAN의 LUN 하나를 서버 두 대에 붙이는 것은 기술적으로 쉽다. 문제는 그 위의 파일 시스템이다. ext4나 XFS 같은 일반 파일 시스템은 자기만 디스크를 쓴다고 가정하고 빈 블록 목록과 메타데이터를 메모리에 캐시한다. 두 서버가 각자 "900번 블록이 비었네" 하고 서로 다른 파일을 쓰면 하나가 덮어써지고, 결국 파일 시스템 전체가 망가진다. AWS도 블록 볼륨 하나를 최대 16대에 붙이는 EBS Multi-Attach 문서에서 XFS·EXT4는 여러 서버의 동시 접근을 위한 것이 아니니 클러스터 파일 시스템을 쓰라고 적는다.
클러스터 파일 시스템은 노드끼리 분산 잠금 관리자(DLM)로 "이 영역은 지금 내가 고친다"를 합의하고, 잠금을 넘겨줄 때 캐시를 비운다. 리눅스의 GFS2와 OCFS2, VMware의 VMFS가 그렇다. 응답 없는 노드가 계속 쓰지 못하게 저장장치 쪽에서 끊는 펜싱(fencing)도 필요하다. SCSI·NVMe의 예약(reservation) 명령이 그 수단이다.
파일 공유는 이 일을 서버가 맡는다. NFSv4와 SMB는 바이트 범위 잠금을 프로토콜에 두고, 서버가 하나뿐인 파일 시스템을 관리하니 클라이언트끼리 블록을 다툴 일이 없다. 다만 POSIX의 잠금은 권고(advisory)라서, 잠금을 확인하지 않는 프로그램은 막지 못한다. 여러 서버가 같은 데이터를 써야 하는데 앱을 고칠 수 있다면, 대개는 공유 디스크보다 데이터베이스나 오브젝트 스토리지에 조정을 맡기는 편이 쉽다.
지연과 대역폭: 네트워크가 병목이 될 때
네트워크 스토리지의 속도는 디스크보다 선이 정하는 경우가 많다. 1GbE는 이론상 125MB/s, 실제로 110MB/s 남짓이라 요즘 HDD 한 대의 순차 속도(약 250~280MB/s)에도 못 미친다. 10GbE(1,250MB/s)도 PCIe 4.0 NVMe SSD 한 대(약 7,000MB/s)의 5분의 1 정도다. 집 NAS의 디스크를 SSD로 바꿔도 1GbE에 묶여 있으면 체감이 거의 없다. 회선 속도와 병목 구간 이야기는 네트워크 노트에 있다.
작은 입출력에서는 대역폭보다 지연이 문제다. 요청 하나가 끝나야 다음을 보내는 앱(큐 깊이 1)은 지연이 곧 상한이다. 왕복 1ms면 초당 1,000번, 4KiB씩이면 약 4MB/s밖에 안 된다. 같은 1ms라도 요청 32개를 동시에 띄우면 32배가 된다. 로컬 NVMe의 4KiB 읽기가 수십~100µs인데 네트워크 스토리지는 프로토콜 처리와 왕복이 더해지니, 데이터베이스처럼 작은 동기 쓰기가 많은 일은 네트워크 지연에 민감하다. 그래서 고성능 SAN은 커널 네트워크 스택을 건너뛰는 RDMA나 전용 망을 쓰고, 이더넷이면 점보 프레임(MTU 9000)과 전용 NIC로 부담을 줄인다.
집 NAS와 데이터센터
집이나 작은 사무실의 NAS는 디스크 몇 개를 담은 작은 서버다. Synology 같은 완제품이나 TrueNAS 같은 NAS용 OS가 하는 일은 비슷하다. 디스크를 RAID로 묶어 볼륨을 만들고(Btrfs나 ZFS), 공유 폴더를 SMB·NFS로 내주고, 맥의 Time Machine 백업을 받는다. 그리고 쓰기 시 복사 파일 시스템 덕에 정해진 시각마다 스냅숏을 찍는다.
스냅숏은 실수로 지운 파일과 공유 폴더를 통째로 암호화하는 랜섬웨어를 되돌리는 데 강하다. 그러나 같은 장비 안에 있으니 장비가 통째로 망가지거나 도난당하면 함께 사라진다. 스냅숏은 백업이 아니다. 그 차이와 RAID 이야기는 중복과 분산 스토리지 노트에서 이어 간다. NAS에 디스크를 고를 때는 SMR 방식 HDD를 피하는 편이 좋다. 리빌드처럼 오래 쓰는 작업에서 크게 느려질 수 있다(저장장치 노트의 CMR·SMR 절).
데이터센터의 스토리지는 같은 일을 고장에 견디게 겹으로 한다. 스토리지 배열은 컨트롤러를 둘 두어 하나가 죽어도 다른 쪽이 이어받고, 서버는 다중 경로(multipath)로 두 스위치를 거쳐 배열에 닿는다. 용량이 모자라면 장비를 갈아 끼우는 대신 노드를 더해 넓히는 스케일아웃(scale-out) NAS나 분산 스토리지를 쓴다. 중복 제거·압축·씬 프로비저닝(thin provisioning, 쓴 만큼만 실제 공간을 잡기)으로 같은 디스크에 더 담고, 다른 데이터센터로 복제해 재해에 대비한다.
- RFC 8881: NFS Version 4.1 — IETF
- RFC 1813: NFS Version 3 — IETF
- RFC 7530: NFS Version 4 — IETF
- RFC 7862: NFS Version 4.2 — IETF
- RFC 7143: iSCSI — IETF
- SMB file sharing overview — Microsoft Learn
- SMB security enhancements — Microsoft Learn
- NVM Express specifications — NVM Express
- Amazon EBS Multi-Attach — AWS
- GFS2 — Linux kernel documentation
- TrueNAS Documentation — TrueNAS