NFS란 무엇인가? NFS개념

NFS는 클라이언트 컴퓨터가 로컬에 저장된 것처럼 네트워크를 통해 파일에 접근할 수 있도록 하는 분산 파일 시스템 프로토콜1인 Network File System의 약자이다. Sun Microsystems 사람에 의해 개발되었으며 이후 유닉스 및 리눅스 환경에서 파일 공유를 위해 널리 사용되는 프로토콜이 되었다.

NFS의 기본 개념은 서버가 네트워크상의 클라이언트에게 하나 이상의 디렉토리를 공유하는 것이라고 생각하면 된다.
클라이언트는 공유된 디렉토리를 자체 시스템에 마운트하고 로컬인 것처럼 해당 디렉토리 내의 파일에 접근할 수 있다.
따라서 여러 사용자가 시스템 간에 파일을 물리적으로 전송하지 않고도 네트워크를 통해 파일에 접근하고 공유할 수 있다.

조금 더 자세히 들어가 보면 NFS는 클라이언트 프로그램이 다른 컴퓨터의 서버 프로그램에서 서비스를 요청할 수 있도록 하는 RPC(원격 프로시저 호출) 프로토콜을 기반으로 하는데, NFS 프로토콜은 파일 열기/닫기, 데이터 읽기/쓰기, 파일 및 디렉토리 생성/삭제, 권한 및 소유권과 같은 파일 속성 관리와 같은 다양한 작업을 지원한다.

그림으로-표현한-NFS

그림으로 표현한 NFS

 

NFS 장단점

NFS 장점

NFS에는 FTP 및 Samba와 같은 기존 파일 공유 방법에 비해 몇 가지 이점이 있다.

  • 파일 액세스에 필요한 네트워크 요청 수를 줄이는 캐싱 메커니즘을 사용하므로 네트워크를 통해 파일에 더 빨리 접근할 수 있다.
  • 파일 잠금을 지원하므로 여러 사용자가 동일한 파일을 동시에 수정할 수 없으며 사용자가 파일을 공유하고 공동작업을 더 쉽게 수행할 수 있다.

NFS 단점

  • 기본적으로 암호화 또는 인증을 제공하지 않기 때문에 다른 파일 공유 프로토콜보다 보안 수준이 낮을 수 있다.
  • NFS는 특히 서버와 클라이언트가 여러 개인 대규모 환경에서 설정 및 구성이 어려울 수도 있다.

NFS 장단점 요약

NFS는 사용자가 네트워크를 통해 원격 서버에 저장된 파일에 접근할 수 있는 분산 파일 시스템 프로토콜이다.
빠르고 효율적인 파일 공유 기능을 제공하지만 보안 및 안정성을 보장하기 위해 신중한 구성이 필요하다.

NFS 버전 별 특징과 장단점

버전 출시년도 주요 특징 장점 단점
NFSv2 1985 단순한 프로토콜, RPC 기반 간단하고 가벼움 보안 부족, 오류 처리의 한계
NFSv3 1995 64비트 파일 오프셋, TCP 지원 빠른 전송 속도, 확장성 좋음 보안 취약성, 무결성 문제
NFSv4 2003 ACL 지원, 강화된 보안, 상태 관리 프로토콜 도입 강화된 보안, 무결성 확보, 세션 고정 기능 도입 복잡한 설정, 오버헤드 증가
NFSv4.1 2010 pNFS(파일 레이아웃) 도입, 병렬 I/O 지원 빠른 병렬 I/O, 서버 측 복제 및 부하 분산 가능 복잡한 구현, 호환성 문제
NFSv4.2 2016 RPC-over-RDMA, 서버 측 복제 개선 성능 향상, 빠른 데이터 전송, 대역폭 효율적 활용 구현의 복잡성, 호환성 문제, 채킹의 한계

NFS 시스템의 구조

NFS 시스템의 구조는 클라이언트, 서버 및 네트워크의 세 가지 주요 구성 요소로 나눌 수 있다.

  • 클라이언트(Client)
    • NFS 클라이언트는 네트워크를 통해 파일에 접근하는 사용자라고 이해하면 쉽니다. 클라이언트는 mount 명령을 사용하여 서버에서 내보낸 디렉토리를 자체 파일 시스템에 마운트 한다.
  • 서버(Server)
    • NFS 서버는 원격 접근하기 위해 네트워크를 통해 하나 이상의 디렉토리를 내보내는 시스템이다. 서버는 내보낸 파일 시스템을 관리하고 파일 작업에 대한 클라이언트 요청에 응답한다.
  • 네트워크(Network)
    • 네트워크는 클라이언트와 서버 간의 통신 채널을 제공하고, 네트워크는 LAN(Local Area Network) 2 또는 WAN(Wide Area Network) 3을 말한다.
NFS 구조

NFS 구조

 

조금 더 알아보기 RPC란 무엇인가?

RPC는 원격 프로시저 호출(Remote Procedure Call)의 약자로, 한 컴퓨터에서 실행 중인 프로그램이 네트워크 통신의 낮은 수준의 세부 사항을 처리하지 않고도 원격 컴퓨터에서 절차나 기능을 실행할 수 있도록 하는 프로토콜이다.

RPC를 사용하면 프로그램이 로컬 함수 또는 프로시저인 것처럼 원격 컴퓨터의 함수 또는 프로시저를 호출할 수 있고,
프로그램은 원격 컴퓨터에 기능 실행 요청을 보내고 원격 컴퓨터는 기능의 결과를 다시 보낸다.
이렇게 하면 다른 컴퓨터에서 실행 중인 여러 프로그램이 동일한 컴퓨터에서 실행되는 것처럼 함께 작동할 수 있다.

RPC는 애플리케이션이 네트워크를 통해 서로 통신해야 하는 분산 컴퓨팅 환경에서 일반적으로 사용되며, RPC를 사용하는 응용프로그램의 예로는 네트워크 파일 시스템, 원격 데이터베이스 액세스 및 웹 서비스가 있다.

RPC는 클라이언트가 서버에 요청을 보내고 서버가 결과로 응답하는 클라이언트와 서버 모델을 기반으로 한다.
클라이언트와 서버 간의 통신은 일반적으로 TCP/IP와 같은 표준화된 프로토콜을 사용하여 네트워크를 통해 수행하게 된다.

조금 더 알아보기 RCBIND란 무엇인가?

RCBIND(Remote Procedure Call Bind)는 클라이언트가 네트워크에서 RPC(Remote Procedure Call) 서비스를 동적으로 검색하고 연결할 수 있도록 해주는 서비스이고, 클라이언트가 서버의 RPC 서비스에 접근하려면 서비스가 수신 중인 포트 번호를 알아야 한다.
RCBIND는 포트매퍼라는 중앙 데이터베이스를 쿼리하여 클라이언트가 이 정보를 동적으로 얻을 수 있는 방법을 제공하는 역할을 하며, 
포트 매퍼는 서버에서 RPC 서비스 목록과 해당 포트 번호를 유지 관리한다.
클라이언트가 특정 RPC 서비스에 대한 요청을 포트매퍼에 보내면 포트매퍼는 해당 서비스와 연결된 포트 번호로 응답한다.

RCBIND는 NFS(Network File System) 및 NIS(Network Information Service)와 같이 RPC에 의존하는 네트워크 서비스를 위해 유닉스 및 리눅스 환경에서 일반적으로 사용된다.

NFS 동작원리

NFS(네트워크 파일 시스템) 운영 원칙은 클라이언트와 서버 모델을 기반으로 한다.
클라이언트는 네트워크를 통해 서버에서 파일 또는 디렉토리에 대한 접근을 요청하고 서버는 요청된 데이터로 응답한다.

NFS 작업의 단계

  • 서버의 디렉토리 공유
    • NFS 서버가 네트워크의 클라이언트에 하나 이상의 디렉토리를 공유하고, 관리자는 NFS 서버 구성 파일에서 공유할 디렉터리를 지정한다.
  • 클라이언트에서 서버의 디렉토리 마운트
    • NFS 클라이언트는 mount 명령을 사용하여 서버에서 내보낸 디렉토리를 자체 파일 시스템에 마운트 한다.
      mount 명령은 서버의 호스트 이름 또는 IP 주소, 내보낸 디렉토리의 이름 및 클라이언트의 마운트 지점을 지정한다.
  • 요청 데이터
    • 서버가 공유한 디렉터리가 마운트 되면 클라이언트가 로컬인 것처럼 디렉터리 내의 파일에 접근할 수 있고, 클라이언트는 파일 읽기, 쓰기, 만들기, 삭제 또는 수정과 같은 파일 작업에 대한 요청을 서버로 보낸다.
  • 원격 프로시저 호출(RPC)
    • 클라이언트는 RPC(원격 프로시저 호출) 프로토콜을 사용하여 서버에 요청을 보내고, RPC 프로토콜을 사용하면 클라이언트가 서버의 함수 또는 프로시저를 로컬인 것처럼 호출한다.
  • 파일 접근 권한
    • 서버는 클라이언트로부터 RPC 요청을 수신하고 공유한 디렉토리에서 요청된 파일 작업을 수행한다.
      서버는 요청된 작업의 결과를 클라이언트에 다시 공유한다.
  • 캐싱
    • 성능을 향상하기 위해 NFS 클라이언트는 파일 데이터를 로컬로 캐시 한다. 클라이언트는 파일 데이터의 복사본을 메모리에 보관하므로 접근할 때마다 서버에서 데이터를 검색할 필요가 없으며, 클라이언트는 권한, 소유권 및 타임스탬프와 같은 파일 속성을 캐시 할 수 있다.
  • 일관성
    • NFS는 동일한 파일에 접근하는 여러 클라이언트에서 데이터 일관성을 유지하기 위해 파일 잠금 메커니즘을 사용한다. 파일 잠금을 사용하면 여러 클라이언트가 동일한 파일을 동시에 수정할 수 없으므로 한 번에 하나의 클라이언트만 파일을 수정할 수 있다.
  • 보안
    • 인증 및 암호화와 같은 보안 기능을 제공하도록 NFS를 구성할 수 있다. 예를 들어 NFS 버전 4는 Kerberos 인증 및 TLS(Transport Layer Security) 암호화를 지원하여 네트워크를 통해 전송되는 데이터를 보호한다.
Network File System 구조

Network File System 구조

조금 더 알아보기 XDR이란 무엇인가?

XDR(eExternal Data Representation)은 분산 컴퓨팅 환경에서 데이터를 직렬화 및 역직렬화하는 데 사용되는 표준 데이터 인코딩 형식이고,  기본 하드웨어 또는 소프트웨어 플랫폼에 관계없이 네트워크를 통해 전송되고 다른 컴퓨터에서 재구성될 수 있도록 프로그래밍 언어 독립적인 방식으로 데이터 구조를 변환하기 위한 규칙의 집합을 정의한다.

XDR 인코딩은 정수, 부동 소수점 숫자, 문자열, 배열, 구조 및 조합을 포함한 광범위한 데이터 유형을 지원하고, 서로 다른 시스템 간의 상호 운용성을 보장하기 위해 이러한 데이터 유형을 인코딩 및 디코딩하는 방법을 지정한다.

일반적으로 SunRPC 및 ONC RPC와 같은 RPC(원격 프로시저 호출) 프로토콜과 함께 사용된다.

NFS Server 구축

NFS 패키지 설치

아래 명령어를 입력하여 공유한 폴더가 있는 서버에 NFS 패키지를 설치한다.

yum -y install nfs-utils

공유한 폴더 생성

공유가 될 대상폴더를 만들어준다. 기존에 존재하는 폴더를 공유할 예정이라면 만들지 않아도 된다.

mkdir /nfs_share

공유한 폴더 등록

NFS로 폴더로 등록하기 위해서 vi 또는 vim 편집기를 이용하여 /etc 위치에 export라는 파일을 수정한다.

  • rw
    • 디렉토리를 읽기, 쓰기 접근 가능
  • ro
    • 읽기 가능
  • sync
    • 파일 시스템이 변경되면 즉시 동기화
  • noaccess
    • 접근 거부
  • no_root_squash
    • 클라이언트 시스템의 root가 서버의 root와 동일한 권한을 갖게 된다.
  • root_squash
    • 클라이언트의 root가 서버의 root 권한을 획득하는 것을 차단
  • no_all_squash
    • root를 제외하고 서버와 클라이언트의 사용자들을 하나의 권한을 가지도록 설정한다.
  • all_squash
    • root를 제외하고 서버와 클라이언트의 사용자를 동일한 권한으로 설정한다.
vi /etc/export

#편집기로 접속 한 후 아래에 내용 삽입 후 저장
/nfs_share    *(rw,sync,no_root_squash)

#특정 대역대에만 공유를 허용할 시 예시
/nfs_share    192.168.63.0/24(rw,sync,no_root_squash)

#/etc/export 파일 변경 내용 반영
exportfs -r

#/etc/export 내용 반영 확인
exportfs -v

#확인시 출력 내용 예시
/nfs_share      192.168.68.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)

NFS 서비스 시스템 시작 및 상태확인

#서비스 자동 시작 등록
systemctl enable nfs-server

#서비스 시작
systemctl start nfs-server

#서비스 상태 확인
systemctl status nfs-server

● nfs-server.service - NFS server and services
   Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; vendor preset: disabled)
   Active: active (exited) since Thu 2022-10-20 10:17:56 EDT; 2min 10s ago
  Process: 32144 ExecStartPost=/bin/sh -c if systemctl -q is-active gssproxy; then systemctl reload gssproxy ; fi (code=exited, status=0/SUCCESS)
  Process: 32128 ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS (code=exited, status=0/SUCCESS)
  Process: 32127 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
 Main PID: 32128 (code=exited, status=0/SUCCESS)
    Tasks: 0
   CGroup: /system.slice/nfs-server.service

Oct 20 10:17:56 nisser systemd[1]: Starting NFS server and services...
Oct 20 10:17:56 nisser systemd[1]: Started NFS server and services.

NFS Firewall 방화벽 등록

firewall 방화벽을 사용 중이라면 아래와 같이 방화벽을 등록해 주고 이용하지 않는다면 systemctl stop firewalld 명령어로 중지시키고 systemctl disable firewalld 명령어를 사용하여 비활성화한다.

firewall-cmd --permanent --zone=public --add-service=nfs
firewall-cmd --permanent --zone=public --add-service=mountd
firewall-cmd --permanent --zone=public --add-service=rpc-bind
firewall-cmd --reload

NFS IPTABLES 방화벽 등록

iptables 방화벽을 사용 중이라면 아래와 같이 서비스가 사용하는 포트를 허용해주어야 한다. 만일 iptables 방화벽을 사용 중이지 않는다면 systemctl stop iptables로 서비스를 중지하고 systemctl disable iptable로 명령어를 사용하여 비활성화한다.

iptables -I INPUT -p tcp --dport 111 -j ACCEPT
iptables -I INPUT -p udp --dport 111 -j ACCEPT
iptables -I INPUT -p tcp --dport 2049 -j ACCEPT
iptables -I INPUT -p udp --dport 2049 -j ACCEPT
iptables -I INPUT -p tcp --dport 20048 -j ACCEPT
iptables -I INPUT -p udp --dport 20048 -j ACCEPT
iptables -I INPUT -p tcp --dport 32769 -j ACCEPT
iptables -I INPUT -p udp --dport 32769 -j ACCEPT

#위 규칙을 등록하고 반드시 방화벽 규칙을 저장하여야 하고 재시작을 해야한다.
service iptables save
systemctl restart iptables

 

NFS 서버 구축 스크립트

아래는 NFS 서버를 구축하기 위한 스크립트이며, 자신의 환경에 맞게 수정하여 활용하면 된다.

#!/bin/bash

# NFS 서버 설치
sudo yum install -y nfs-utils

# 마운트 포인트 변수 설정
nfs_share_path="/srv/nfs_share"

# 내보낼 디렉터리 생성 및 권한 설정
sudo mkdir -p $nfs_share_path
sudo chown nobody:nogroup $nfs_share_path
sudo chmod 777 $nfs_share_path

# NFS 설정 파일 수정 (/etc/exports)
echo -e "$nfs_share_path *(rw,sync,no_subtree_check)" | sudo tee /etc/exports

# 선택할 수 있는 공유 옵션 목록 출력
echo -e "\n공유 옵션을 선택하세요:"
echo "1. 읽기 전용 (Read-Only)"
echo "2. 읽기/쓰기 (Read-Write)"
echo "3. 읽기 전용 + 서버에서 비동기적으로 변경 사항 감지 (Read-Only + Async)"
read -p "번호를 입력하세요 (기본값: 1): " share_option

# 사용자 입력에 따라 공유 옵션 설정
case $share_option in
2)
echo -e "$nfs_share_path *(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports
;;
3)
echo -e "$nfs_share_path *(ro,async,no_subtree_check)" | sudo tee -a /etc/exports
;;
*)
# 기본값은 읽기 전용
;;
esac

# NFS 서버 재시작
sudo systemctl restart nfs-server

# 방화벽 설정 (기본적으로 필요한 포트 열기)
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --reload

echo "NFS 서버가 구축되었습니다."

 

Client NFS 설치

yum -y install nfs-utils

Client NFS Mount 가능 상태확인

  • showmount -e
    • 현재 공유되고 있는 파일 시스템의 목록을 표시한다.
  • showmount -a
    • 공유한 파일 시스템을 마운트 한 모든 클라이언트를 표시한다.
  • showmount -d
    • 현재 공유 있는 디렉터리를 표시합니다.
#파일 시스템의 목록을 표시하며, 아래는 명령어 사용 예시이다.
showmount -e server_ip
showmount -e server_hostname

Client NFS Mount

아래 중 원하는 방식으로 수동 마운트 하여 연결하면 서버의 공유 디렉토리를 접근할 수 있게 되며 호스트 이름으로 마운트 할 경우 반드시 클라이언트에 호스트 이름이 등록되어 있어야 한다.

#서버의 IP로 연결할 경우
mount server_ip:/nfs_share /mnt

#서버의 호스트 이름으로 연결할 경우
mount server_hostname:/nfs_share /mnt

Client NFS Auto Mount

매 순간 관리자가 마운트 작업을 하는 것을 번거롭고 비효율적인 작업이다. 그렇기에 아래와 같이 /etc/ 디렉토리 안에 fstap 파일에 아래와 같이 기재해 두면 서버가 재부팅되더라도 자동으로 NFS를 마운트 하게 된다.

vi /etc/fstab

#편집기 접속 후 아래 와 같이 기재하면 자동 마운트 등록
server_ip:/nfs_share    /mnt/nfs_share    nfs    defaults    0 0

#호스트 이름을 사용하여 마운트 할 경우 아래와 같이 진행
server_hostname:/nfs_share    /mnt/nfs_share    nfs    defaults    0 0

Client NFS Mount 상태확인

#IP로 mount 되었을 경우
df -h

Filesystem                Size  Used Avail Use% Mounted on
/dev/sda1                 8.0G  1.7G  6.3G  22% /
tmpfs                     99M     0    99M   0% /dev/shm
server_ip:/nfs_share      100G   10G   90G  10% /mnt/nfs_share

#Host로 mount 되었을 경우
df -h

Filesystem                Size  Used Avail Use% Mounted on
/dev/sda1                 8.0G  1.7G  6.3G  22% /
tmpfs                     99M     0    99M   0% /dev/shm
hostname_ip:/nfs_share    100G   10G   90G  10% /mnt/nfs_share

NFS Server nfs.conf 설정 방법

NFS 서버의 서부설정 하기 위해서는 Centos7 기준 /etc/nfs.conf 파일을 수정해야 한다. vi /etc/nfs.conf로 파일 편집을 시도하여 아래와 같이 바꿔야 할 포트를 수정한다거나 그 외 설정이 가능하다.

  • nfsvers
    • 사용할 기본 NFS 버전을 지정한다. 예를 들어 NFS 버전 4를 사용하려면 nfsvers=4를 설정한다.
  • mountd_port
    • NFS 마운트 데몬(rpc.mountd)이 NFS 마운트 요청을 수신하는 포트 번호를 지정한다.
      기본값은 20048이다.
  • statd_port
    • NFS 상태 데몬(rpc.statd)이 상태 요청을 수신하는 포트 번호를 지정한다.
      기본값은 40048이다.
  • lockd_tcport
    • NFS 잠금 데몬(rpc.lockd)이 TCP를 통해 잠금 요청을 수신하는 포트 번호를 지정한다.
      기본값은 32803이다.
  • lockd_udport
    • NFS 잠금 데몬(rpc.lockd)이 UDP를 통해 잠금 요청을 수신하는 포트 번호를 지정한다.
      기본값은 32769이다.

/etc/sysconfig/nfs와 /etc/nfs.conf 차이점과 개념

/etc/sysconfig/nfs는 다양한 NFS 관련 데몬의 환경 변수 및 명령줄 옵션을 설정하는 데 사용되고 /etc/nfs.conf는 NFS 작업에 대한 시스템 전체 기본값을 설정하는 데 사용된다.

※ 아래의 경로 및 파일은 Centos7 운영체제를 기준으로 작성되었습니다.

  •  /etc/sysconfig/nfs
    • /etc/sysconfig/nfs 파일에는 NFS 서버 및 해당 구성 요소의 동작을 구성하는 데 사용할 수 있는 다양한 옵션이 포함되어 있다. 이 파일은 시작 시 nfs 서비스 스크립트로 읽으며 다양한 NFS 관련 데몬에 대한 환경 변수 및 명령줄 옵션을 설정하는 데 사용된다.
  • /etc/nfs.conf
    • /etc/nfs.conf는 NFS 서비스의 기본 구성 파일이다. 기본 NFS 버전, 기본 파일 잠금 방법 및 기본 마운트 옵션과 같은 NFS 서비스에 대한 일반 설정이 포함되어 있다. 이 파일은 시작 시 NFS 데몬에 의해 읽히며 NFS 작업에 대한 시스템 전체 기본값을 설정하는 데 사용된다.
  1. 프로토콜은 장치 또는 시스템 간의 통신을 제어하는 규칙 및 절차의 집합입니다
  2. LAN(Local Area Network)은 건물이나 캠퍼스와 같은 작은 지리적 영역 내의 장치를 연결하는 컴퓨터 네트워크이다. )
  3. WAN(Wide Area Network)은 넓은 지리적 영역에 걸쳐 있고 도시, 국가 또는 심지어 대륙에 걸쳐 장치를 연결하는 컴퓨터 네트워크이다. )