NAS 아키텍처

NAS 아키텍처는 Storage 개념이 강화되면서, 업무 문서 및 주요 자료들에 대한 공유 및 동시 수정을 지원하기 위해 시작된 아키텍처이다. 일반 Storage 들은 블록이나 Record 단위로 파일들이 기록되지만, NAS에서 데이터를 저장하고 사용하는 단위는 "파일"이다 (파일이란, 관련 데이터들을 묶어놓고 이름을 붙여놓은 논리적 단위이다).
NAS 의 강점은 쉬운 환경 조성에 있다. FC를 사용하는 SAN 과는 다소 다르게, 이더넷 허브를 기반으로 형성되기 때문에 지금 사용하고있는 LAN 환경에서 NFS 서버 / 클라이언트 프로그램만 있으면 간단하게 조성할 수 있고, PC에서 NFS 서버에 접근할 수 있다. 하지만 TCP/IP 기반이며 파일 단위로 제어하기 때문에 낮은 throughput 과 IOPS, 그리고 높은 latency 는 고질적인 단점으로 여겨진다.
이번 포스트에서는 NAS 아키텍처를 직접 만들고, NAS 아키텍처가 동작하기 위한 근본이 되는 프로토콜인 NFS 프로토콜을 간단히 알아보기 직접 사용해보면서 스토리지 기술들과 조금 더 친해져보자!
헷갈리는 용어 정리하고 가기..
| NAS (Network Attached Storage) | 분산 파일 시스템 | NFS (Network File System) |
| 공유 파일 시스템을 제공하기 위한 아키텍처 | NAS 아키텍처 위에서, 여러 서버에 걸쳐 동작하는 파일 시스템을 말한다. 파일을 여러 서버, 여러 디스크에 분산하여 저장하는 시스템이다. | NAS 아키텍처에서 사용하는, 동작하기 위한 프로토콜을 말한다 |
NFS 프로토콜
NAS 아키텍처가 동작하는 대표적인 프로토콜은 그 유명한 NFS 프로토콜이다. 이 NFS 프로토콜에 대해서 너무 복잡하게 생각하지 말자. HTTP 프로토콜 처럼, 그냥 파일에 대한 제어를 요청하는 NFS 클라이언트와, NFS 서버가 서로의 요청과 응답을 이해할 수 있는 약속이다. 보통 HTTP 를 우리가 만들 듯이 NFS 를 막 만드는 경험은 드물고 보통 만들어진 프로그램들을 사용하기 때문에, 당연히 알면 좋겠지만 스토리지 접하는 시점에서 당장 구체적으로 알 필요는 없는 것 같다. 다만 기본적인 정보는 알고 있자.
- NFS 프로토콜은 File System 에 대한 작업을 원격으로 요청하는 프로토콜이다
- 요청에는 파일 식별자, 요청 종류, (WRITE 경우) 데이터 등이 포함된다
- 요청 종류로는 읽기, 쓰기, 생성, 삭제, 디렉토리 목록 조회, 복사, 이름 변경 등등등 우리가 맨날 서버에서 하는 것들이 있다
- NFS 프로토콜은 OS에서 처리되도록 약속되어 있으며, NFS 서버 프로그램은 NFSD 데몬을 통해서 요청을 처리한다
(SSH 같은 프로토콜도 똑같은 것이다. 서버/클라이언트간 약속된 절차를 따르고, 데몬이 일을 수행해주는 구조이다)
NFS-Kernel-Server, NFS-common 프로그램 (NFS 서버 / 클라이언트)
NFS 프로토콜에 대한 실습을 해보기에 앞서, 실습에서 사용할 프로그램들을 통해 NFS 와 살짝은 더 친해져보자. NFS-Kernel-Server 프로그램은 NFS 서버의 역할을 하는 대표적인 프로그램이다. "서버"의 역할이기 때문에, NFS 서버 데몬인 nfsd 가 프로세스로 띄워지고 역할을 수행한다.
실제로 실무 Level 에서도 내부적인 공유 시스템을 간단하게 만들 때 사용되기도 한다. 이런 친구들이 NFS 요청 / 응답 다 만들어주기 때문에 우리는 그렇게 NFS 에 대해 당장 깊이 들어갈 필요 없다고 한 것이다.
NFS-Common 프로그램은 NFS 서버에서 공유하는 파일 시스템에 접근할 수 있는 실행 프로그램이다. 여러가지 명령어를 지원하며 명령어들로 process 를 실행하고 수행한다. NFS-Common 을 날 괴롭혔던 iptables 프로그램처럼 OS 수준에서 실행되는 프로그램이다.
NFS Client 는 유저 요청에 대해 지정된 NFS 서버의 기본포트 2049 에게 연결해서 요청하려고 한다. 포트는 L4 계층 식별자이며 NFS 는 OS 단에서 제어되기 때문에, 2049 포트로 진입하면 NFSD 데몬이 소켓으로 이 요청을 수신한다는 것을 알 수 있다. 아무튼 파일을 생성하는 요청을 예시로 과정을 알아보자.

Client PC 에서 NFS 서버에 마운트된 경로에서 hello.txt 란 파일을 만든다고 해보자. 이 때, hello.txt 파일이 생성되는 시점에, Client OS 는 당연히 로컬 파일 시스템 작업을 처리하기 때문에 디스크에 hello.txt 를 쓰려고 시도할 것이다. 하지만 NFS 클라이언트 프로그램이 있다면, OS 는 로컬 파일 시스템 작업을 할 때 "NFS 마운트 경로인지?" 를 추가적으로 확인하며, 맞다면 이를 NFS 클라이언트에게 서버에 요청하라고 전달하는 구조이다. 그럼 CREATE 요청과 data에 hello.txt 의 내용이 들어간채로 NFS 서버 2049 포트로 전달되며, 해당 서버의 OS에서 자신의 로컬에 작업을 진행하는 구조이다. NFS 클라이언트와 서버는 이렇게 동작한다고 일단 이해하면 충분하다. 실습해보자.
실습
NFS 에 목적에 맞게 실습하는 것이 가장 좋은데, 처음에 하면 NFS 프로토콜이며, Client/Server 며 마치 NFS 프로토콜을 사용해서 파일을 다운받는 느낌인 줄 알았다. 하지만 막상 그런류가 아니라, 정말 말그대로 원격으로 파일을 제어하는 방식이다. 따라서 다음과 같이 NAS 아키텍처를 그려보면 좋다.
참고로 내가 헷갈렸던 이유는.. 그냥 볼륨 붙이고 하는 느낌인데 어떤 것을 읽든 계속 설명 중에 "클라이언트의 요청" 이라는 말이 나오기 때문이다 (그냥 내가 많이 부족해서 그렇다). 여기서 말하는 클라이언트의 요청이란, NFS 클라이언트가 내부적으로 수행하는 모든 요청을 말한다. 즉, ls, cat, echo, rm 등 많은 요청들이 날라가고, 이를 NFS 포로토콜로 패킷을 만들어서 서버에 전송하는 형태를 우린 보고있는 것이기 때문에 요청이라고 표현한다. 아무튼 다음과 같이 실습을 해보자.

한 NFS 서버에 Client 한 대가 파일을 넣으면, 다른 Client 에서는 해당 파일이 실시간으로 조회되는 모습을 실습해보자. 서버는 10.166.1.1 의 IP, Client 는 각자 10.166.2.1~2 의 IP 를 가지고 있다.
우선 NFS Server 역할 할 node 에 nfs-kernel-server 를 설치해보자. nfs-kernel-server 는 데몬 프로세스 이기 때문에, 바로 프로세스가 띄워져 있지는 않다. 다만, ps aux | grep nfsd 를 통해서 실행중인 데몬 프로세스들을 확인할 수 있다.
# Server 10.166.1.1
$ mkdir /nfs-server/share
$ sudo chown nobody:nogroup /nfs-server/share
$ sudo apt update
$ sudo apt install nfs-kernel-server -y ---------- nfs 서버 시스템 설치
...
$ ps aux | grep nfsd -------- 데몬 프로세스 정상 실행중인지 확인
root 2109086 0.0 0.0 0 0 ? S 18:18 0:00 [nfsd]
root 2109087 0.0 0.0 0 0 ? S 18:18 0:00 [nfsd]
root 2109088 0.0 0.0 0 0 ? S 18:18 0:00 [nfsd]
nogroup:nobody 권한 설정은 "익명 사용자에게 해당 경로에 대한 접근을 허용하는 것" 이다. 실제 실무 Level 에서는 더 fine-grained 한 user, group 권한 control 이 필요할 것이다. 가령, 클라이언트가 user1 으로 nfs 서버에 연결하면, 이 user1 의 UID, GID 를 확인하여 해당 사용자의 권한을 확인한는 등... (상위 모듈과의 연계 필요)
계속 해보면, /etc/exportfs 파일은 nfs-kernel-server 가 NFS 프로토콜을 사용하여 공유시킬때 참조하는 파일이다. 다음과 같이 설정해 주자.
$ sudo vim /etc/exportfs
### (파일 맨 밑에 아래와 같이 추가, 공백 있으면 안된다)
/nfs-server/share 10.166.2.1(rw,sync,no_subtree_check) 10.166.2.2(rw,sync,no_subtree_check)
...
# 설정 적용 후 재시작해준다
$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
느낌이 바로 오겠지만, 내가 만든 경로를 "NFS 공유 경로" 로 설정하는 일이다. 그리고 Client PC 들에게 해당 경로를 공유시키겠다는 설정을 적용하고, 옵션들을 넣어주는 것이다. 위에서 설정한 옵션들은 다음과 같고, 더 많은 옵션들이 있다.
- rw : 읽고 쓰는 권한을 말한다
- sync : 동기식 모드로, CREATE 하는 요청을 받았을 경우 실제로 생성한 후에 응답하는 방식이다 (async 는 일단 대답하고 만듬)
- no_subtree_check : no 없이 적용하면, 하위 경로들에 대한 제어시 실제로 존재하는지 매번 검증해서, 비용이 크다고 한다 (보통 no)
이제 NFS 서버는 준비가 되었다. 준비해둔 Client 두 대에는 nfs-common 을 설치한다. 그리고 위에서 제공한 NFS 서버의 경로와 mount 해줄 경로를 각각 준비한다( /nfs-client/share, /nfs-client2/share). 그리고 mount 명령어를 실행하면 된다.
# Client PC - 10.166.2.1 / 10.166.2.2
$ sudo apt install nfs-common -y -------- 1, 2 번 Client 에 모두 설치
...
$ sudo mount 10.166.1.1:/nfs-server/share /nfs-client/share ------- 1번 Client 에서 실행
$ sudo mount 10.166.1.1:/nfs-server/share /nfs-client2/share ------- 2번 Client 에서 실행
이제 2번 Client 에서 파일을 생성해보고, 1번 Client 에서 해당 경로를 lookup 해보겠다
# Client PC 2 (10.166.2.2)
$ cd /nfs-client2/share
$ echo "Hello From NFS Client2!" > hello.txt
...
# Client PC 1 (10.166.2.1)
$ cd /nfs-client/share
$ cat hello.txt
Hello From NFS Client2!
이처럼 PC2에서 실행한 TXT 파일 Create 명령이 NFS-Client 프로그램을 통해 NFS 서버로 요청되었고, NFS 서버는 자신의 로컬 마운트 경로에 hello.txt 를 생성하였다. PC1에서는 마운트된 경로를 조회하고 특정 파일까지 조회하면 READ 명령이 다시 한번 NFS 서버로 날라가, 결과를 반환하고 콘솔에 출력해주는 모습을 볼 수 있다.
NFS 프로토콜과 이를 지원하는 프로그램들에 대해서 알아보았다. NFS 프로토콜을 기반으로 한 AWS의 EFS, NCP의 NAS Storage 와 같은 서비스로 실제 유저들이 많이 사용하는 유료 클라우드 서비스이며, 이와 같은 원리와 모습을 근간에 두고 있다. AWS 의 EFS 를 봐도, EFS 서버와 내 EC2 따위의 특정 경로를 마운트하는 과정을 필요로 한다. 그리고 당연히 EFS에 마운트한 경로를 사용하는 EC2는 NFS 클라이언트를 설치해야한다 (AWS EFS 클라이언트 관련 Docs)

참고자료
https://tech.gluesys.com/blog/2019/12/02/storage_1_intro.html
글루시스 기술 블로그
A simple yet classy theme for your Jekyll website or blog.
tech.gluesys.com
'CS 이론 > Storage' 카테고리의 다른 글
| [iSCSI] iSCSI 프로토콜을 통해 SAN 아키텍처 이해해보기 (0) | 2025.05.17 |
|---|---|
| [LVM] LV 분할하여 Ubuntu /var 용량 확장하기 (1) | 2024.11.25 |