디스크 그룹의 공간이 바닥나거나 장비를 교체해야 할 때, 볼륨을 다른 애그리게이트로 옮겨야 하는 순간이 옵니다. 문제는 그 볼륨을 지금 누가 쓰고 있다는 것 — 마운트를 끊고 옮기자고 할 수는 없습니다. ONTAP의 답이 volume move 인데, 문서마다 “무중단(nondisruptive)”이라고 적혀 있습니다. 정말인지 클라이언트에 I/O를 걸어놓고 옮겨봤습니다.
결과: NFS 클라이언트가 0.5초 간격으로 읽고 쓰는 동안 볼륨을 다른 노드의 애그리게이트로 옮겼고 — 이동 27초, 클라이언트 실패 0건, 지연 스파이크도 없었습니다. 컷오버 순간까지 틱이 한 번도 안 끊겼습니다.
이 글의 실습 환경
ONTAP Simulator 9.17.1 2노드 클러스터(cluster1-01/02), NFS 클라이언트는 Ubuntu Server 24.04(NFSv3 마운트)입니다. 옮길 볼륨은 실제 마운트되어 쓰이고 있는 nfs_vol1(1GB)입니다.
1. 출발지와 목적지 — 지금 어디에 있나
cluster1::> storage aggregate show -fields aggregate,node,availsize
aggregate node availsize
--------- ----------- ---------
N1_data cluster1-01 14.29GB <-- 목적지 (노드1)
N2_data cluster1-02 14.79GB <-- 현재 위치 (노드2)
cluster1::> volume show -vserver NFS_SVM -volume nfs_vol1 -fields aggregate,node
vserver volume aggregate node
------- -------- --------- -----------
NFS_SVM nfs_vol1 N2_data cluster1-02
노드2의 애그리게이트에 있는 볼륨을 노드를 건너 노드1로 옮깁니다. 같은 노드 안의 애그리게이트 간 이동보다 조건이 나쁜, 더 엄격한 시나리오입니다. 목적지에 볼륨 크기 이상의 여유만 있으면 됩니다.
2. 실험 설계 — 클라이언트가 증인이다
“무중단”의 판정자는 스토리지가 아니라 클라이언트입니다. 우분투에서 0.5초마다 쓰기(로그 한 줄 추가) + 읽기(4KB)를 반복하며 성공/실패를 기록하는 루프를 걸었습니다.
# NFS 마운트 위에서 0.5초 간격 읽기+쓰기, 실패는 FAIL로 기록
$ for i in $(seq 1 1440); do t=$(date +%H:%M:%S.%3N); if echo "$t tick $i" >> /mnt/ontap-nfs/io-during-move.txt && head -c 4096 /mnt/ontap-nfs/dataA.dat >/dev/null; then echo "$t OK $i"; else echo "$t FAIL $i"; fi; sleep 0.5; done
3. ⭐ 이동 — 명령 하나, 27초, 실패 0
cluster1::> volume move start -vserver NFS_SVM -volume nfs_vol1 -destination-aggregate N1_data
[Job 239] Job is queued: Move "nfs_vol1" in Vserver "NFS_SVM" to aggregate "N1_data".
cluster1::> volume move show -vserver NFS_SVM -volume nfs_vol1
Move Phase: initializing
Source Aggregate: N2_data
Destination Aggregate: N1_data
# 잠시 후
cluster1::> volume move show -vserver NFS_SVM -volume nfs_vol1
Detailed Status: Successful
Percentage Complete: 100%
Move Phase: completed
Duration of Move: 00:00:27 <-- 27초
Move State: done
그 27초 동안 클라이언트 로그는 이랬습니다. 이동이 끝난 시각(13:05:58) 앞뒤를 그대로 옮깁니다.
$ grep -c FAIL /tmp/movetest.log
0 <-- 실패 0건
13:05:56.628 OK
13:05:57.137 OK
13:05:57.642 OK
13:05:58.147 OK <-- 이 사이 어딘가에서 컷오버가 지나갔다
13:05:58.652 OK
13:05:59.157 OK
13:05:59.662 OK <-- 간격 0.5초 그대로. 멈춤 없음
틱 간격이 0.5초에서 흔들리지도 않았습니다. 클라이언트 입장에서 이동은 일어나지 않은 일입니다.
4. 왜 안 끊기나 — 접속 지점과 데이터 위치는 별개다
동작 원리는 두 조각입니다. 첫째, volume move 는 볼륨을 통째로 잠그고 옮기는 게 아니라 뒤에서 복제해두고 마지막에 아주 짧은 컷오버로 교체합니다 [문서확인]. 둘째가 더 중요한데 — 이동이 끝난 뒤 확인해보면:
# 볼륨은 노드1로 갔는데
cluster1::> volume show -vserver NFS_SVM -volume nfs_vol1 -fields aggregate,node
NFS_SVM nfs_vol1 N1_data cluster1-01
# 클라이언트가 접속하는 LIF는 여전히 노드2에 있다
cluster1::> network interface show -vserver NFS_SVM -fields curr-node,status-oper
NFS_SVM nfs_lif1 cluster1-02 up
클라이언트의 접속 지점(LIF·IP)은 그대로이고, 요청은 클러스터 내부 네트워크를 타고 볼륨이 있는 노드로 알아서 넘어갑니다. 클라이언트는 볼륨이 어느 디스크에 있는지 알 필요가 없는 구조라, 데이터가 이사를 가도 접속은 흔들리지 않습니다.
5. 실무에서 챙길 것
| 상황 | 기준 |
|---|---|
| 대용량 볼륨 | 복제 단계가 길어질 뿐 서비스는 유지된다. 컷오버는 복제가 따라잡은 뒤에만 시도된다 [문서확인] |
| 바쁜 시간대 | 이동은 되지만 복제가 백그라운드 I/O를 쓴다 — 피크 시간은 피하는 게 매너 |
| 컷오버가 계속 미뤄질 때 | volume move show 의 상태를 보고, 쓰기 부하가 너무 크면 한가한 때로 |
| 이동 후 성능 | LIF와 볼륨이 다른 노드에 있으면 내부 네트워크를 경유한다. 신경 쓰이면 LIF를 볼륨 따라 옮기거나(migrate) 원래부터 같은 노드로 이동 |
정리
| 하나만 기억한다면 |
|---|
volume move 의 “무중단”은 마케팅이 아니라 실측이다 — 쓰는 중인 볼륨을 노드 건너 옮기는 동안 클라이언트 실패 0건, 지연 변화 없음. 비결은 접속 지점(LIF)과 데이터 위치(애그리게이트)가 분리된 구조다. 옮기기 전 확인할 건 목적지 여유 공간 하나다. |
이 랩의 기반은 2노드 클러스터 구축 글이고, NFS 마운트는 NFS access denied 글에서 만든 구성입니다. 노드가 강제로 꺼졌을 때의 점검은 RDB 판정 글에 있습니다.
참고 문서 — ONTAP CLI — volume move start · ONTAP CLI — volume move show
모든 출력은 ONTAP Simulator 9.17.1 가상 랩에서 직접 실행한 결과입니다. 실제 장비에서는 볼륨 크기·부하에 따라 복제 시간이 크게 달라질 수 있습니다.


