- 가상 머신 2개를 준비
- 하나는
NFS 서버, 다른 하나는NFS 클라이언트로 이용
# NFS 서버로 이용할 호스트에서 수행
# 패키지 업데이트
sudo apt update
# NFS 서버 설치
sudo apt install -y nfs-kernel-server# 공유할 디렉토리 생성
sudo mkdir -p /srv/nfs_share
# 디렉토리 소유자를 nobody:nogroup으로 변경
sudo chown nobody:nogroup /srv/nfs_share
# 모든 사용자가 읽기/쓰기/실행 가능하도록 권한 설정
sudo chmod 777 /srv/nfs_share
# 소유자 및 권한 확인
ls -ld /srv/nfs_share-
nobody:nogroup으로 소유자를 설정하는 이유- NFS는 클라이언트가 파일에 접근할 때 클라이언트의 UID/GID를 서버에 그대로 전달함
- 클라이언트마다 UID/GID가 다를 수 있으므로, 특정 사용자에 종속되지 않는 중립적인 계정인
nobody:nogroup으로 설정 nobody: 권한이 거의 없는 시스템 계정으로, 소유권 충돌을 방지하기 위해 사용nogroup: 특정 그룹에 속하지 않는 시스템 그룹
-
chmod 777과 함께 사용하여 어떤 클라이언트든 접근 가능하도록 설정하는 것으로, 실습 환경용 설정임
(실무에서는 보안상 권장하지 않음) -
실무에서의 권한 설정
- 특정 사용자/그룹만 접근할 수 있도록 소유자와 권한을 제한하여 설정
# 예: 서버와 클라이언트 모두 동일한 UID(1000)의 사용자가 접근하는 경우 sudo chown 1000:1000 /srv/nfs_share sudo chmod 755 /srv/nfs_share- 서버와 클라이언트의 UID/GID를 일치시키거나, Kerberos 인증(
sec=krb5)을 사용하여 사용자 인증을 강화함Kerberos: MIT에서 개발한 오픈소스 네트워크 인증 프로토콜로, 별도의 인증 서버(KDC)를 통해 사용자를 검증하여 UID 위조를 방지할 수 있음
/etc/exports에서*대신 허용할 클라이언트 IP 또는 대역을 명시적으로 지정
# 예: 특정 IP 대역만 허용 /srv/nfs_share 192.168.1.0/24(rw,sync,no_subtree_check)
# /etc/exports 파일에 공유 디렉토리 설정 추가
echo "/srv/nfs_share *(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports-
rw / rorw- NFS 서버 디렉토리에 대해 읽기/쓰기 허용ro- NFS 서버 디렉토리에 대해 읽기 전용으로 허용
-
sync / asyncsync- 클라이언트가 파일을 작성/수정/삭제하면 데이터를 디스크에 기록한 뒤 응답async- 클라이언트가 파일을 작성/수정/삭제하면 데이터를 메모리에만 저장한 뒤 응답
(성능 향상/데이터 손실 위험)
-
subtree_check / no_subtree_checksubtree_check- NFS 서버가 요청받은 파일이 실제 공유된 하위 디렉토리 내에 있는지 매번 검사
(보안 강화, 오버헤드 발생)no_subtree_check- 파일의 개별 위치를 매번 엄밀하게 검증하지 않고 파일 시스템 단위로 접근 허용
(성능 향상, 연결 안정성 유리)
-
no_subtree_check를 사용하는 이유- 가상화 환경에서는 디스크 I/O가 물리 서버보다 느릴 수 있으므로 성능 최적화에 유리함
- 또한, 가상 머신이 자주 생성/삭제되는 환경에서는 디렉토리 구조가 자주 변경될 수 있으므로
no_subtree_check를 사용하여 연결 안정성을 높이는 것이 좋음
# NFS 서버 재시작
sudo systemctl restart nfs-kernel-server
# 현재 export 설정 확인
sudo exportfs -v# NFS 클라이언트로 이용할 호스트에서 수행
# 패키지 업데이트
sudo apt update
# NFS 클라이언트 패키지 설치
sudo apt install -y nfs-common# 마운트할 디렉토리 생성
sudo mkdir -p /mnt/nfs_share
# NFS 서버의 공유 디렉토리를 클라이언트에 마운트
sudo mount [NFS Server IP]:/srv/nfs_share /mnt/nfs_share
# 마운트 확인
mount | grep nfs
ls -ld /mnt/nfs_share# 마운트된 디렉토리에 파일 생성 테스트
echo "Storage Virtualization" > /mnt/nfs_share/test.txt# NFS 마운트 해제
sudo umount /mnt/nfs_share
# 마운트 해제 확인
mount | grep nfs
ls -l /mnt/nfs_share-
생성한
test.txt파일은NFS 서버에 저장되어 있으므로, 마운트를 해제하면 해당 파일에 접근할 수 없음 -
NFS는 네트워크 기반 파일 시스템이므로 서버가 중지되거나 네트워크 연결이 끊기면 마운트된 디렉토리에 접근 시
지연 또는 오류 발생 가능 -
NFS는 클라이언트 재부팅 시 자동으로 마운트되지 않음
(/etc/fstab파일에 NFS 마운트 설정 추가하여 자동 마운트 가능) -
umount시device is busy오류가 발생하면 해당 디렉토리를 사용하는 프로세스가 존재하는 것이므로 종료 후 다시 시도 (lsof +D /mnt/nfs_share또는fuser -m /mnt/nfs_share로 확인 가능)
재부팅 후에도 NFS가 자동으로 마운트되도록 /etc/fstab에 설정을 추가할 수 있음
# /etc/fstab에 NFS 마운트 설정 추가
echo "[NFS Server IP]:/srv/nfs_share /mnt/nfs_share nfs defaults,_netdev 0 0" | sudo tee -a /etc/fstab
# 설정 확인
cat /etc/fstab# 재부팅 없이 fstab 기반으로 즉시 마운트 테스트
sudo mount -a
# 마운트 확인
mount | grep nfs-
/etc/fstab필드 구성:[장치] [마운트포인트] [파일시스템] [옵션] [dump] [fsck]nfs: 파일시스템 타입defaults: rw, suid, exec, auto, nouser, async 옵션을 포함하는 기본값- 마지막 두 필드
0 0: dump 백업 비활성화, 부팅 시 fsck 검사 비활성화
(NFS는 로컬 파일시스템이 아니므로 fsck 대상이 아님)
-
_netdev옵션을 추가하면 네트워크가 활성화된 이후에 마운트를 시도하도록 보장함- 이 옵션이 없으면 부팅 시 네트워크 준비 전에 마운트를 시도하여 실패할 수 있음
- 가상 머신 2개를 준비
- 하나는
iSCSI 서버, 다른 하나는iSCSI Initiator로 이용
# iSCSI 서버로 이용할 호스트에서 수행
# 패키지 업데이트
sudo apt update
# iSCSI 타겟 서버 설치
sudo apt install -y tgt# iSCSI 디스크 파일을 저장할 디렉토리 생성
sudo mkdir /srv/iscsi_disks
# 1GB 크기의 디스크 이미지 파일 생성
sudo dd if=/dev/zero of=/srv/iscsi_disks/disk01.img bs=1G count=1# iSCSI 타겟 설정 파일 작성
# [Target IQN]은 iqn.2026-05.kr.ac.dankook:[학번]과 같이 고유하게 설정할 것
# [Initiator IP]는 후에 iSCSI Initiator를 설치할 호스트의 IP 주소로 설정할 것
sudo tee /etc/tgt/conf.d/iscsi-target.conf <<EOF
<target [Target IQN]>
backing-store /srv/iscsi_disks/disk01.img
initiator-address [Initiator IP]
</target>
EOF# iSCSI 서비스 재시작
sudo systemctl restart tgt
# 타겟 설정 확인
sudo tgtadm --mode target --op showiSCSI의 IQN(iSCSI Qualified Name)은 고유한 식별자로, 전 세계적으로 중복되지 않아야 함
예:iqn.2026-05.com.boanlab:storage.disk1iqn: iSCSI 규격을 의미하는 고정 문자열 (필수)2026-05: 도메인 이름을 역순으로 표현한 날짜 (예: 2026년 5월)com.boanlab: 조직의 도메인 이름을 역순으로 표현한 부분 (예: boanlab.com)storage.disk1: 해당 타겟을 구분하기 위해 사용자가 정하는 이름
- iSCSI에서 Initiator가 Target에 접속할 때 사용하는 인증 방식
- Target이 Initiator에게 랜덤 Challenge를 보내고, Initiator는 공유된 비밀(password)로 응답값을 생성하여 전송
- 비밀번호 자체가 네트워크에 평문으로 전송되지 않으므로
initiator-address만으로 제한하는 것보다 보안성이 높음 - 단방향 CHAP: Target이 Initiator를 인증 (일반적)
- 상호 CHAP(Mutual CHAP): Target과 Initiator가 서로 인증
# 기존 타겟 설정 파일에 CHAP 인증 추가
sudo tee /etc/tgt/conf.d/iscsi-target.conf <<EOF
<target [Target IQN]>
backing-store /srv/iscsi_disks/disk01.img
initiator-address [Initiator IP]
incominguser [username] [password]
</target>
EOF
# iSCSI 서비스 재시작
sudo systemctl restart tgt
# 설정 확인
sudo tgtadm --mode target --op showincominguser [username] [password]: Initiator가 Target에 접속할 때 사용하는 자격증명- password는 12자 이상으로 설정 권장 (tgt 정책)
# CHAP 인증 방식 활성화
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] \
--op update -n node.session.auth.authmethod -v CHAP
# 사용자 이름 설정
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] \
--op update -n node.session.auth.username -v [username]
# 비밀번호 설정
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] \
--op update -n node.session.auth.password -v [password]# 기존 세션 로그아웃 후 재로그인 (CHAP 적용)
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] --logout
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] --login
# 세션 확인
sudo iscsiadm -m session- CHAP 설정 정보는
/etc/iscsi/nodes/디렉토리 하위에 저장됨 - 잘못된 자격증명으로 로그인 시도 시
Login failed오류 발생
# iSCSI Initiator로 이용할 호스트에서 수행
# 패키지 업데이트
sudo apt update
# iSCSI Initiator 설치
sudo apt install -y open-iscsi# 타겟 서버 검색
sudo iscsiadm -m discovery -t sendtargets -p [Target IP]
# 검색된 타겟에 로그인
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] --login# 타겟 서버에서 Initiator의 로그인 상태 확인
sudo tgtadm --mode target --op show# 연결된 블록 디바이스 확인
lsblk-
타겟 서버 호스트에서는
iSCSI 타겟이디스크 이미지 파일로 설정되어 있기 때문에, 실제 블록 디바이스로 나타나지 않음
(/srv/iscsi_disks/disk01.img파일로 존재) -
Linux의 저장장치 네이밍 규칙
sd(SCSI Disk): SATA, SAS, USB 장치 및 iSCSIvd(Virtio Disk): KVM/QEMU 같은 가상화 환경에서 Virtio 드라이버를 사용하는 가상 디스크nvme(NVMe Disk): NVMe SSD 장치sr(SCSI ROM): CD-ROM 또는 DVD-ROM 드라이브- 앞의 prefix를 붙인 후 알파벳과 숫자가 조합되어 디바이스 이름이 생성됨
(예:sda,sdb,vda,nvme0n1등)
-
iSCSI Multipath (다중 경로)
-
실무 환경에서 iSCSI는 단일 네트워크 경로로 연결하는 경우가 드물며,
Multipath I/O (MPIO) 를 통해 여러 경로를 동시에 구성하는 것이 일반적 -
Multipath를 사용하는 이유
- 고가용성(HA): 하나의 경로(NIC, 스위치, 케이블)가 장애가 나더라도 다른 경로로 자동 전환(Failover)
- 부하 분산: 여러 경로에 I/O를 분산시켜 처리량(Throughput) 향상
-
구성 예시
Initiator NIC1 ──── Switch A ──── Target Port1 ↕ (같은 디스크) Initiator NIC2 ──── Switch B ──── Target Port2- 위 구성에서
/dev/sdb,/dev/sdc두 개의 블록 디바이스가 생성되지만,
실제로는 동일한 디스크를 가리킴 multipath-tools를 사용하면 이를 하나의 논리 장치(/dev/mapper/mpathX)로 묶어 사용 가능
- 위 구성에서
-
# 연결된 디스크를 ext4 파일시스템으로 포맷
sudo mkfs.ext4 /dev/<디스크이름>
# 마운트할 디렉토리 생성
sudo mkdir /mnt/iscsi_disk
# 디스크를 마운트
sudo mount /dev/<디스크이름> /mnt/iscsi_disk
# /dev/<디스크이름>가 정상적으로 마운트되었는지 확인
mount | grep /dev/<디스크이름>
lsblk | grep <디스크이름># 마운트 포인트의 소유자를 현재 사용자(ubuntu)로 변경
sudo chown ubuntu:ubuntu /mnt/iscsi_disk
# 모든 사용자에게 읽기/쓰기/실행 권한 부여
sudo chmod 777 /mnt/iscsi_disk
# 마운트된 디스크에 파일 생성 테스트
echo "iSCSI Storage Virtualization" > /mnt/iscsi_disk/test.txt
# 생성된 파일 확인
cat /mnt/iscsi_disk/test.txt
# 마운트된 디스크의 사용량 확인
df -h /mnt/iscsi_disk# Initiator 호스트에서 수행
# 디스크 마운트 해제
sudo umount /dev/<디스크이름>
# 디스크 마운트 해제 확인
mount | grep /dev/<디스크이름>
lsblk | grep <디스크이름>
# iSCSI 타겟 세션에서 로그아웃
sudo iscsiadm -m node -T [Target IQN] -p [Target IP] --logout
# 디스크가 완전히 해제되었는지 확인
lsblk# 타겟 서버에서 Initiator의 로그인 상태 확인
sudo tgtadm --mode target --op showumount시device is busy오류가 발생하면 NFS에서 설명한 방법과 같이 해결
| 항목 | NFS | iSCSI |
|---|---|---|
| 공유 수준 | 파일 시스템 수준 | 블록 수준 |
| 접근 방식 | 파일/디렉토리 단위 접근 | 디스크 장치 단위 접근 |
| 클라이언트 파일시스템 | 서버의 파일시스템을 그대로 사용 | 클라이언트가 직접 포맷 및 파일시스템 구성 |
| 동시 접근 | 다수의 클라이언트가 동시에 마운트 가능 | 단일 클라이언트 전용 (기본적으로 공유 불가) |
| 프로토콜 | TCP/UDP (포트 2049) | TCP (포트 3260) |
| 인증 | IP 기반 접근 제어 | IP 기반 + CHAP 인증 |
| 성능 | 상대적으로 낮음 (메타데이터 오버헤드) | 상대적으로 높음 (블록 I/O 직접 접근) |
| 주요 용도 | 공유 데이터, 홈 디렉토리, 로그 공유 | 데이터베이스, VM 디스크 이미지, 고성능 스토리지 |
| 운영 복잡도 | 낮음 | 높음 |




















