NFS(Network File System)는 네트워크를 통해 디렉터리를 공유하는 시스템입니다. 최근 가정용 소규모 NAS(Network Attached Storage) 서버의 보급으로 일반 사용자들에게도 친숙한 개념이 되었습니다. NFS는 이러한 NAS 서버의 핵심 기술이라고 볼 수 있습니다.
리눅스에서 NFS 서버를 구성하면 여러 서버 간에 동일한 디렉터리를 공유하여 사용할 수 있습니다. 고성능이 요구되는 환경에서는 전용 NAS 스토리지 도입을 고려할 수 있지만, 비용이 상당히 높습니다. 일반적인 워크 로드 환경에서는 Red Hat에서 기본적으로 제공하는 NFS 서버만으로도 충분히 활용 가능하며, 실제 운영 환경에서도 널리 사용되고 있습니다.
이 글에서는 NFS 서버를 구성하여 ‘/test’ 디렉터리를 공유하고, 클라이언트에서 이 공유 디렉터리를 마운트하여 사용하는 간단한 실습을 진행하겠습니다.
환경
Red Hat Enterprise Linux 7
Red Hat Enterprise Linux 8
Red Hat Enterprise Linux 9
NFS 서버 구성
NFS 서버 구성은 세 가지 주요 단계로 이루어집니다
- 서비스 설치: 필요한 NFS 관련 패키지를 시스템에 설치합니다.
- 설정 파일 편집: NFS 설정 파일을 수정하여 공유할 디렉터리와 접근 권한 등을 지정합니다.
- 서비스 시작: 구성이 완료된 NFS 서비스를 활성화하고 시작합니다.
1. NFS 서버 설치
패키지는 기본적으로 레드햇 설치 이미지에서 제공합니다. CD를 이용한 레포 설정 부분은 LOCAL REPO에서 참조할 수 있습니다.
# yum install nfs-utils
...
Complete!
2. NFS 공유 디렉터리 설정
NFS 공유 디렉터리를 설정하는 과정은 두 단계로 구성됩니다
- 공유할 디렉터리 생성
- /test 디렉터리를 공유하기 위해 빈 디렉터리를 하나 생성합니다.
[root@server ~]# mkdir /test
- /etc/exports 파일을 편집
- NFS를 통해 공유할 디렉터리를 이 파일에 정의합니다.
- 여러 디렉터리를 공유할 경우, 각 디렉터리를 별도의 줄에 선언할 수 있습니다.
[root@server ~]# echo "/test *(rw)" >> /etc/exports
설정 후 ‘/etc/exports’ 파일의 내용을 확인합니다
[root@server ~]# cat /etc/exports /test *(rw,no_root_squash)
이 과정을 통해 NFS 서버에서 디렉터리를 공유할 준비가 완료됩니다. ‘rw’ 옵션은 읽기 및 쓰기 권한을 부여하며, ‘*’는 모든 클라이언트에 대한 접근을 허용합니다.
<NFS 설정 팁 1> 설정 파일 위치
NFS 서버 설정은 ‘/etc/exports’ 파일에만 국한되지 않습니다. ‘/etc/exports.d/’ 디렉터리도 중요한 역할을 합니다. 이 디렉터리 내의 ‘.exports’ 확장자를 가진 모든 파일도 NFS 서버에 의해 처리됩니다. 파일명은 자유롭게 지정할 수 있지만, 반드시 ‘.exports’ 확장자로 끝나야 합니다. 이러한 방식으로 NFS 설정을 더 유연하게 관리할 수 있으며, 여러 공유 설정을 별도의 파일로 구성할 수 있습니다.
설정의 적용 여부는 ‘exportfs -v’ 명령어를 통해 확인할 수 있습니다. 이 명령어를 실행하면 ‘/etc/exports’ 파일뿐만 아니라 ‘/etc/exports.d’ 디렉터리 내의 모든 ‘.exports’ 파일에서 정의된 내보내기 설정이 표시됩니다.
아래 예제를 보면 data.exports 파일의 내보내기가 잘 진행되고 있는 걸 확인할 수 있습니다.
[root@server ~]# cat /etc/exports.d/data.exports
/data *(rw)
[root@server ~]# exportfs -v
/data <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,root_squash,no_all_squash)
<NFS 설정 팁 2> exports 설정 파일
exports 파일 설정에 사용되는 몇 가지 예를 보겠습니다.
- 예제1
/test 172.20.0.104(rw)
- /test 디렉터리를 내보냅니다.
- 이 디렉터리에 접근 가능한 클라이언트는 172.20.0.104로 제한합니다.
- 마운트한 클라이언트는 read, write이 가능합니다.
- 예제2
/test 172.20.0.0/24(rw)
- 예제 1과 동일하지만 이 디렉터리에 접근 가능한 클라이언트를 172.20.0.0/24 대역으로 제한합니다.
- 예제3
[root@server ~]# cat /etc/exports /test 192.168.155.76(rw) 192.168.155.92(ro) [root@server ~]# exportfs -v /test 192.168.155.76(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash) /test 192.168.155.92(sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,root_squash,no_all_squash)
- ‘/test’ 디렉터리를 공유합니다.
- 192.168.155.76 IP 주소를 가진 클라이언트에게는 읽기 및 쓰기(rw) 권한을 부여합니다.
- 192.168.155.92 IP 주소를 가진 클라이언트에게는 읽기 전용(ro) 권한을 부여합니다.
- 예제4
/test 192.168.155.76(rw,no_root_squash)
- 192.168.155.76 IP 주소를 가진 클라이언트에게 공유됩니다.
- 해당 클라이언트에 읽기 및 쓰기(rw) 권한을 부여합니다.
- ‘no_root_squash’ 옵션이 적용되어 있습니다.
‘squashing’은 ‘압축하다’, ‘짓누르다’라는 의미로, 소프트웨어 맥락에서는 ‘제한하다’로 해석됩니다. NFS에서 기본 설정인 ‘root_squash’ 옵션은 root 사용자의 권한을 nobody로 변경하여 루트 권한을 제한합니다. 반면, ‘no_root_squash’ 옵션을 사용하면 마운트 된 디렉터리에서 root 사용자의 권한을 유지할 수 있습니다. NFS는 UID와 GID를 기반으로 사용자의 디렉터리 접근 권한을 결정합니다. 이는 클라이언트와 서버 간 사용자 식별에 중요한 역할을 합니다. 추가적인 NFS 옵션에 대한 자세한 정보는 man 페이지를 참조하시기 바랍니다.
[root@server ~]# man exports
3. NFS 서버 시작 및 활성화
[root@server ~]# systemctl start nfs-server
[root@server ~]# systemctl enable nfs-server
## 확인
[root@server ~]# systemctl status nfs-server
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
Active: active (exited) since Tue 2024-04-30 10:27:51 KST; 2 days ago
...
4. NFS 방화벽 활성화 (Optional: 리눅스 방화벽 사용하는 경우)
[root@server ~]# firewall-cmd --add-service=nfs --permanent
success
[root@server ~]# firewall-cmd --reload
success
5. NFS 서버 에서 공유되는 디렉터리 확인
exportfs -v
명령어를 사용하면 현재 서버에서 NFS를 통해 공유 중인 디렉터리 정보를 확인할 수 있습니다. 서버가 정상적으로 실행되고 있다면 아래와 같은 정보가 표시됩니다.
[root@server ~]# exportfs -v
/test <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)
위 명령어의 출력 결과는 다음과 같은 구조로 이루어져 있습니다.
- ‘/test’는 공유된 디렉터리를 나타냅니다.
- ‘<world>’는 NFS 서버에서 허용하는 클라이언트 IP 주소를 의미합니다. ‘<world>’인 경우 모든 클라이언트에 대한 접근을 허용합니다. 이는 서버 측에서 클라이언트를 제한할 수 있는 방법으로, 방화벽 설정과는 별개입니다.
- 괄호 안의 항목들은 마운트 옵션입니다. 서버에서 “rw”(읽기 및 쓰기) 옵션만 지정했지만, 나머지는 기본값으로 설정되었습니다.
일반적으로 NFS 서버에서는 특별한 요구사항이 없다면 기본 옵션을 사용합니다. 이는 대부분의 경우 충분한 기능을 제공합니다.
여기까지의 과정으로 NFS 서버 측의 설정이 완료되었습니다. ‘/test’ 디렉터리가 성공적으로 NFS를 통해 공유되도록 구성되었습니다. 다음 단계는 클라이언트 측 설정입니다
클라이언트 설정
클라이언트 역시 RHEL(Red Hat Enterprise Linux)을 기준으로 설명합니다. 위의 NFS 서버에서 공유한 디렉터리를 마운트 해서 사용하면 됩니다.
1. 패키지 설치
서버와 마찬가지로 마운트를 하는 클라이언트도 nfs-utils 패키지가 있어야 마운트를 할 수 있습니다. 다만 서비스를 기동 시킬 필요는 없습니다.
- nfs-utils 패키지 설치
# yum install nfs-utils
...
Complete!
2. NFS 볼륨 마운트 설정
NFS 서버에서 공유한 디렉터리를 마운트하는 방식은 크게 두 가지로 나뉩니다. 재부팅 후 자동으로 마운트를 할지 말지 경우에 따라 방법을 달리할 수 있습니다.
재부팅 후 마운트를 유지하지 않아도 되는 경우에는 mount
명령어로 진행하면 됩니다. 예를 들어, Active-Standby 방식의 이중화 솔루션이나 특정 프로그램이 실행될 때만 마운트 하는 경우, 또는 테스트나 임시로 사용할 때 유용합니다. 그 외의 대부분의 경우에는 /etc/fstab
을 통해 재부팅 후에도 마운트를 유지할 수 있도록 설정합니다.
A. mount 명령어로 NFS 볼륨 마운트
- 마운트
[root@client ~]# mkdir /test
[root@client ~]# mount -t nfs 192.168.155.88:/test /test
마운트가 성공적으로 되었는지 확인하려면 ‘df -h’ 명령어를 사용할 수 있습니다.
[root@client test]# df -h /test
Filesystem Size Used Avail Use% Mounted on
192.168.155.88:/test 27G 15G 13G 53% /test
- 마운트 해제
[root@client ~]# umount /test
B. 재부팅 후에도 마운트 유지 (/etc/fstab 파일 수정)
재부팅 후에도 마운트를 유지하려면 /etc/fstab
파일에 등록하면 됩니다. 이 파일은 시스템이 부팅될 때 자동으로 마운트 될 디렉터리를 지정하는 역할을 합니다. 이를 통해 매번 수동으로 마운트 할 필요 없이, 시스템이 시작될 때 자동으로 NFS 볼륨이 마운트 되도록 설정할 수 있습니다.
- fstab 설정
[root@client ~]# vim /etc/fstab
...
192.168.155.88:/test /test nfs defaults,_netdev 0 0
/etc/fstab
파일에 NFS 마운트 정보를 등록하면 재부팅 후에도 자동으로 마운트가 유지됩니다. 각 줄에 하나의 마운트 정보를 입력해야 하며, 이 파일을 수정할 때는 주의가 필요합니다. 잘못된 설정이 있으면 시스템 부팅 시 문제가 발생하여, 부팅이 안 되고 emergency
모드로 빠질 수 있습니다. 이는 물리 서버의 경우, 직접 서버 앞에 가서 문제를 해결해야 하는 상황을 초래할 수 있습니다.
따라서 /etc/fstab
파일을 수정한 후, 설정이 올바른지 확인하는 가장 좋은 방법은 해당 파일을 이용해 마운트 하는 것입니다. 이는 재부팅을 재현하는 것과 같은 효과를 제공합니다. mount 명령을 이용한 테스트 방법 2가지를 아래 소개합니다.
방법1) 전체 마운트 시도
“mount -a” 명령어는 /etc/fstab 파일에 나열된 모든 파일 시스템을 마운트 합니다. 이미 마운트 된 항목은 무시되므로 안전하게 실행할 수 있습니다.
[root@client ~]# mount -a
[root@client ~]#
[root@client ~]# df -h | grep test
192.168.155.88:/test 27G 15G 13G 53% /test
명령어 실행 결과 위와 같이 아무런 에러 메세지도 나오지 않았다면 정상입니다.
방법2) 특정 디렉터리만 마운트 시도 이번에는 mount 명령어 뒤에 /test 디렉터리를 지정했습니다. 이렇게 디렉터리만 지정하는 명령은 /etc/fstab 파일에 해당 디렉터리에 대한 마운트 정보가 기록되어 있을 때 사용됩니다. 즉, 아래 명령어는 /etc/fstab 파일을 참고하여 마운트를 수행하게 됩니다.
[root@client ~]# mount /test
[root@client ~]#
[root@client ~]# df -h | grep test
192.168.155.88:/test 27G 15G 13G 53% /test
위 방법 역시 오류가 나지 않았고 정상적으로 마운트 되어 있는 모습을 확인할 수 있습니다.
만약 아래처럼 문제가 발생한다면 시스템 부팅이 되지 않을 수 있으니 조치해야 합니다. 문제를 재현하기 위해 일부러 오류를 발생시켰습니다.
[root@client ~]# mount -a
mount.nfs: mount point /test does not exist
마운트 옵션
위에서 기재한 /etc/fstab 파일을 다시 살펴보면 defaults,_netdev 항목이 보입니다. 이 부분은 마운트 옵션을 기재하는 부분입니다. 만약 아무 옵션도 사용하지 않을 경우라면 defaults 하나만 넣으면 해당 버전의 리눅스 커널 버전의 기본값으로 설정됩니다.
192.168.155.88:/test /test nfs defaults,_netdev 0 0
위 설정은 마운트 옵션으로 _netdev 옵션 하나만 추가되었으며 나머지는 기본값으로 설정됩니다. _netdev 옵션은 네트워크 관련 파일 시스템의 경우 사용하며, 부팅 중 네트워크 연결이 활성화될 때까지 마운트를 지연시키는 역할을 합니다. 따라서 NFS와 같은 네트워크가 필요한 볼륨에 권장되는 옵션입니다. 아래는 man 페이지의 설명을 참조한 것입니다.
[root@client ~]# man mount
...
_netdev
The filesystem resides on a device that requires network access (used to prevent the system from
attempting to mount these filesystems until the network has been enabled on the system).
옵션을 주지 않으면 default 값이 적용된다고 했는데 적용된 옵션 값은 mount 명령을 통해서 확인할 수 있습니다. mount 명령 뒤에 아무것도 입력하지 않으면 현재 마운트 된 모든 디렉터리의 자세한 정보가 표시됩니다.
[root@client ~]# mount | grep test
192.168.155.88:/test on /test type nfs4 (rw,relatime,vers=4.2,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.155.92,local_lock=none,addr=192.168.155.88,_netdev)
위에 /test 디렉터리의 기본값들을 확인할 수 있습니다. 별도의 권고 값이 없으면 기본값을 사용하는 게 권장입니다.
<important>
기본값이 권장이지만 마운트 시에 버전은 신경 써야 될 부준 중에 하나입니다. 크게 NFSv3과 NFSv4가 있는데 NFSv4를 지원하지 않는 어플리케이션이 많습니다. 따라서 어플리케이션에서 어떤 버전을 사용하는지 확인 후 맞는 버전으로 설정해야 합니다. /etc/fstab 설정 예시는 아래와 같습니다.
192.168.155.145:/test /test nfs defaults,vers=3 0 0
마치며
NFS를 설치하고 사용하는 방법에 대하여 알아봤습니다. 운영환경에서 많이 사용하고 있는 기능이므로 알아두면 도움이 됩니다. 버전에 대한 부분은 이야기할 게 많아서 다음 글에서 자세히 다루도록 하겠습니다.