배경

AWS를 사용하다보면 가장 많이 사용하는 서비스 중 하나로 S3가 있다.

하지만 S3는 일반적인 파일 시스템과는 구조가 다르기때문에 불편한 점이 있었고 업무적으로 개인적으로 사용할 때 Object Storage인 S3를 일반적인 파일 시스템처럼 사용하고 싶다는 생각이 들 때가 있었다.

마침 회사 일을 진행하다가 S3를 실제 파일 시스템처럼 마운트해서 사용하고 싶다는 니즈가 있었고 러서치를 하게 됐다.

 

AWS S3를 마운트하기 위한 패키지 종류

s3fs-fuse

초기에 goofys가 나오기 전까지 가장 많이 사용됐던 패키지로 알고있다.

github의 스타 숫자가 6.2k나 될 정도로 많은 사람들이 사용하던 패키지이지만 치명적인 단점이 하나 있다.

속도가 .. 너무 느리다.

실제 프로덕션 환경에서 조금 느린걸 감안해도 괜찮은 부분에 넣기에도 부담스러울 정도여서 개발단계에서 가볍게 사용하는 용도가 아니면 쓰기 힘들어보인다.

 

goofys

다음 goofys는 Go언어로 작성된 고성능 POSIX 방식의 Amazon S3 파일 시스템이다.

s3fs보다 빠른 속도를 자랑한다고 벤치마크를 통해 광고하는 글을 봤던 기억만 있었다.

실제로 필자가 사용해본 경험으로도 체감상 goofys가 압도적으로 빨랐다.

Goofys를 이용해 마운트 하기

여러가지 시행착오 끝에 이 글은 Goofys를 사용하게 되었고 업무에서 사용해보면서 익힌 사용법을 적으려 한다.

 

Go 언어 설치

처음에 golang을 설치하는게 생각보다 까다로웠다.

그렇게 찾다보니 쉽고 안정적으로 설치할 수 있는 오픈소스를 찾게 되었는데 update-golang이라는 저장소다.

https://github.com/udhos/update-golang

 

GitHub - udhos/update-golang: update-golang is a script to easily fetch and install new Golang releases with minimum system intr

update-golang is a script to easily fetch and install new Golang releases with minimum system intrusion - GitHub - udhos/update-golang: update-golang is a script to easily fetch and install new Gol...

github.com

 

위 저장소는 공식 문서에 나와있는 가이드대로 설치 스크립트를 만들어놨고 쉽게 시행착오 없이 설치가 가능하게 해놨다.

 

git clone https://github.com/udhos/update-golang
cd update-golang
sudo ./update-golang.sh

sudo echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc

 

GOPATH 설정

mkdir $HOME/go

export GOPATH=$HOME/go

go package가 설치될 디렉토리를 먼저 생성 후에 GOPATH를 환경 변수에 추가해준다.

필자는 홈 디렉토리 하위에 바로 go라는 디렉토리를 생성했지만 이 경우는 다른 경로로 설정해도 무방하다.

그 후에 goofys 패키지를 설치한다.

 

Goofys 설치

sudo wget http://bit.ly/goofys-latest -O /usr/local/bin/goofys

sudo chmod 755 /usr/local/bin/goofys

goofys --version

다운로드 후에 실행 권한을 주고 goofys의 버전이 정상적으로 출력되면 설치가 성공적으로 된거로 보면 된다.

 

awscli 설치

sudo apt-get update -y
sudo apt-get install awscli -y

 

aws credentials 설정

goofys를 이용해서 s3를 마운트해서 이용할 정도라면 사실 엑세스 키와 시크릿 키를 발급하는 과정은 생략해도 된다고 생각한다

위에서 awscli를 정상적으로 설치했다면 configure명령어로 인증 키를 등록하는 과정이 진행되는데 발급받은 키 값들을 넣어주면 된다.

aws configure

AWS Access Key ID [None]: YOUR_ACCESS_KEY_ID
AWS Secret Access Key [None]: YOUR_SECRET_KEY_ID
Default region name [None]: ap-northeast-2
Default output format [None]: json

 

마운트 하기

이제 본격적으로 마운트를 해보자

사실 goofys를 이용해 마운트를 하는 글들은 많이 이미 있지만 아쉬운 부분들이 많았다.

fstab에 이용해 오토마운트를 할 때 유의점이나 마운트를 하는 경로에 따라서 생기는 사소한 부분들을 다뤄주지 않아서 분명 쉽게 될 줄 알았는데 에러가 생기고 머리아파하는 사람이 있을 것 같다.

 

일단 마운트를 하는 경로를 두 가지 기준으로 생각해야 한다.

내가 로그인 한 유저가 test라는 유저라고 해보자

  1. 내가 접속한 유저(test)의 홈 디렉토리 하위에 마운트하기
  2. 루트 소유의 디렉토리에 마운트하기
    • ex) mnt directory

 

여기서 1번의 경우는 접속한 유저가 소유한 홈 디렉토리의 하위 패스이기때문에 크게 문제가 될게 없다.

아무 생각없이 아무거나 긁어다가 붙여넣기를 해도 버킷의 이름과 키 값만 틀리지 않으면 잘 동작된다.

 

다만 문제가 되는건 2번의 경우다.

필자는 일반적으로 NAS와 같은 것들을 마운트 할 때 사용하는 mnt디렉토리에 마운트를 하려했고 시도했더니 바로 에러가 발생했다.

이유는 접속한 유저 test의 기준에서 root소유의 폴더에 마운트가 불가능했다.

그래서 다음과 같은 과정으로 해결했다.

 

mnt 디렉토리에 마운트하기

mnt 디렉토리의 경로는 /mnt 이다.

test라는 유저로 접속을 해서 파일을 생성하려하면 생성이 안되서 sudo 명령어를 붙여야 가능하고 그렇게 생성한 경우 소유자가 root가 된다. 그래서 일단 생성한 디렉토리의 소유자를 먼저 test로 바꿔줘야 한다.

cd /mnt

mkdir buckets

sudo chown test:test /mnt/buckets

간단하게 소유자를 바꿔준다면 일단 디렉토리의 권한 문제는 발생하지 않는다.

하지만 이 상태로 버킷을 마운트하고 사용하다보면 또 다른 문제가 생긴다.

필자의 경우 프로덕션에서 사용할 때 실행되고 있는 Node.js기반으로 돌고있는 어플리케이션과 기타 다른 솔루션들이 있었고 해당 프로세스들은 root계정으로 실행되고 있는 것들이 있었다.

 

그렇다면 이 경우에 버킷을 마운트 한 유저가 test이고 /mnt/buckets라는 폴더의 소유자도 test다.

처음에는 당연히 어떤 유저든 마운트만 되어있다면 접근이 가능하겠지란 생각이였지만 fuse.conf의 기본 옵션은 다른 유저들에게 허용을 해주지 않았다.

test 유저가 마운트 시킨 디렉토리를 다른 유저도 접근이 가능하게 하려면 fuse.conf의 옵션을 수정해줘야 한다.

 

sudo vim /etc/fuse.conf

user_allow_other 부분의 주석을 해제해준다.

 

이제 진짜 모든 설정이 거의 끝났고 마운트를 하면 된다.

단순하게 다음과 같이 하면 마운트가 성공적으로 된다.

goofys [버킷 이름] [디렉토리 경로]

 

버킷의 이름이 backend-resources 라는 이름이고 디렉토리 경로는 /mnt/buckets/backend 라면 다음과 같이 사용하면 된다.

goofys backend-resources /mnt/buckets/backend

 

주의점

일반적으로 사용할 때는 크게 문제가 되지 않는다고 생각하지만 필자의 경우 생각보다 다양한 문제가 생겼다.

 

대표적으로 크게 애먹었던 부분인 express로 작성한 어플리케이션에서 파일을 만들어서 마운트 된 경로로 생성해서 S3로 업로드하는 과정이였다.

 

그 과정에서 예를 들어 html파일을 업로드했다고 한다면 S3의 해당 파일로 들어가보면 파일의 컨텐트 타입이 application/octet-stream으로 고정되는 현상이였다.

 

aws sdk를 많이 사용하다보니 s3에 업로드할 때 컨텐트 타입이 명시가 되지 않아서 기본 값으로 들어갔다는 문제인건 알겠는데 업로드를 하는 주체는 내가 아니고 goofys이다보니 패키지가 지원을 안해주면 걷어내야 하는 상황이였다.

 

찾다보니 나와 같은 이슈를 겪은 사람이 이미 있었고 goofys를 마운트할 때 다양한 옵션들을 제공해줬고 옵션 중 해결 방법이 있었다.

goofys -o allow_other --uid=1001 --debug_fuse --debug_s3 --use-content-type --file-mode=0777 --dir-mode=0777 [버킷 이름] [디렉토리 경로]

디버깅을 위한 옵션과 다른 유저에게도 허용하는 옵션 그리고 파일과 디렉토리의 권한을 설정하는 부분 등이 있었고 현재 문제를 해결해 줄 옵션은 --use-content-type이란 옵션이 있었다.

 

해당 옵션을 마운트시킬 때 인자로 전달하면 타입을 지정해서 업로드를 했다.

 

마지막 여러 옵션들을 활용해서 마운트를 시키면 크게 발생할 이슈는 많지 않을거로 생각된다.

 

부팅 시 오토 마운트를 위해 fstab에 등록하기

위의 설명까지가 마운트에 대한 설명이였고 다음은 부팅 시에 오토 마운트에 대한 부분이다.

 

사실 이 부분이 가장 애먹었던 것 같다.

 

공식문서라고 말할만한게 없고 깃헙의 리드미에 너무 간략하게 적혀있다.

 

아래와 같은 설명이 전부인데 이것만 보고 어떻게 쓰라는건지 감이 잘 안왔고 또 열심히 삽질을 하는 수밖에 없었다.

goofys#bucket   /mnt/mountpoint        fuse     _netdev,allow_other,--file-mode=0666,--dir-mode=0777    0       0

 

여러 시행착오 끝에 알아낸 사용법은 다음과 같다.

 

앞서 마운트를 하는 단계에서 당연히 했겠지만 aws의 인증정보 설정이 되지 않았다면 반드시 다시 진행해야 하고 가장 핵심은 유저 아이디와 그룹 아이디였다.

 

위에서 일반적으로 마운트를 하는 단계에서는 신경쓰지 않아도 되었던 정보지만 fstab에 등록할 때는 어떤 유저인지 어떤 그룹인지를 정확하게 명시해야 했다.

 

유저와 그룹 아이디를 알아내는 방법은 굉장히 쉽다.

id라는 명령어를 입력해서 확인하면 된다.

 

이제 아이디 값도 알아냈으니 vim을 이용해서 /etc/fstab을 수정하면 된다.

아래처럼 새로 기입을 하고 저장한다.

LABEL=cloudimg-rootfs   /        ext4   defaults,discard        0 1

/usr/local/bin/goofys#[버킷 이름] [디렉토리 경로] fuse _netdev,allow_other,--use-content-type,--debug_s3,--debug_fuse,--dir-mode=0777,--file-mode=0777,--uid=[접속한 유저의 유저 아이디],--gid=[접속한 유저의 그룹아이디] 0 0

 

다음 명령어로 마운트가 정상적으로 되는지 테스트해보고 재부팅해서 한번 더 확인해보고 마운트가 정상적으로 된다면 성공적으로 설정됐다.

sudo mount -a

 

여기까지가 프로덕션에서 goofys를 사용해보며 자잘하게 생긴 문제들에 대한 대처법이였다.

 

 

 

복사했습니다!