시작 전
Why ?
- AWS를 처음 배울 때 많이 사용하는 프리티어가 속한 t2 인스턴스 타입은 EBS 생성시 EBS 디바이스 이름이 /dev/xvd*의 형식으로 생성된다. ( ex. /dev/xvdb , /dev/xvde )
하지만 비교적 최근에 출시된 t3, r5, c5와 같은 인스턴스 타입은 Nitro 시스템 기반으로 EBS 생성시 NVMe 블록 디바이스로 표시된다. ( ex. /dev/nvme1n1 , /dev/nvme2n1 )
문제는 순서다. /dev/xvdb와 같은 볼륨은 생성시 부여하는 디바이스 이름과 순서가 일치하기 때문에 서버에 접속하지 않고도 자동으로 Mount 작업을 쉽게 해줄 수 있다.
- 하지만
nvme1n1
,nvme2n1
과 같은 형식으로 생성되는 EBS의 경우 순서가 맞지 않을 뿐더러, 새로운 볼륨이 추가되는경우 순서가 뒤바뀌는 상황도 발생한다.
콘솔, CLI 환경에서는 여전히 디바이스 이름을/dev/xvda
,/dev/xvdb
와 같은 형식으로 부여하기 때문에xvda = nvme0n1, xvdb = nvme1n1
과 같이 규칙성이 있다면 불편함이 없겠지만, 각각 10, 20, 30, 40, 50gb의 볼륨을 xvdb,xvdc,xvdd,xvde,xvdf로 생성했을 때 nvme*n0의 순서는 랜덤이라는 것이다.
- 해당 EBS들을 적절하게 연결하기 위해서 나는 매번 서버에 접속해서
mkfs
,lsblk
,blkid
,nvme-cli
등의 명령어를 통해 직접 콘솔과 비교해서 마운트를 해줘야했고 그게 번거로워서 자동화 하는 방법을 찾게됐다.
- AWS를 처음 배울 때 많이 사용하는 프리티어가 속한 t2 인스턴스 타입은 EBS 생성시 EBS 디바이스 이름이 /dev/xvd*의 형식으로 생성된다. ( ex. /dev/xvdb , /dev/xvde )
NVMe
- NVMe가 뭐길래 이렇게 불편한데 사용하는걸까?
- 위키피디아의 NVMe 설명 : 한마디로 기존 볼륨보다 성능이 좋기 때문에 사용한다. NVMe는 PCI 익스프레스(PCIe) 버스에 부착된 비휘발성 기억 매체 접근을 위한 논리 장치 인터페이스 사양이다.
"NVM"은 "비휘발성 메모리"(non-volatile memory)를 뜻하며, 보통 솔리드 스테이트 드라이브(SSD) 형태로 출시되는 플래시 메모리를 가리킨다. 설계 상, NVM 익스프레스는 현대의 SSD에서 볼 수 있는 여러 수준의 병렬화를 허용하며 이로써 호스트 하드웨어와 소프트웨어에 의해 완전히 이용될 수 있다. 그 결과, NVM 익스프레스는 입출력 부하를 줄이고 길이가 긴 다중 명령 큐, 감소된 레이턴시를 포함하여 이전 논리 장치 인터페이스에 비해 다양한 성능 개선을 이루게 된다.
NVM 익스프레스 장치는 표준 크기의 PCI 익스프레스 확장 카드와, U.2 단자(이전 이름: SFF-8639)를 통해 4 레인의 PCI 익스프레스 인터페이스를 제공하는 2.5인치 폼 팩터 장치로 존재한다. 내부적으로 마운트된 컴퓨터 확장 카드를 위한 SATA 익스프레스 스토리지 장치와 M.2 사양 또한 NVM 익스프레스를 논리 장치 인터페이스로서 지원한다.
- 불편한 NVMe 형식의 EBS를 자동으로 마운트 할 수 있는 방법을 알아보자.
EBS 자동 마운트
시나리오
- EBS 생성
- 이 포스팅에서 EBS는 다음과 같이 생성했다.
### EBS ### 디바이스 이름 | 용량 | 경로 /dev/sdh 11gb /test/gb11 /dev/sdi 22gb /test/gb22 /dev/sdj 33gb /test/gb33 /dev/sdk 44gb /test/gb44
- 이 포스팅에서 EBS는 다음과 같이 생성했다.
nvme*n1
형식의 디바이스를/dev/sdb*
형식으로 맵핑해서 링크를 만드는 스크립트
이 스크립트를 통해non_ebs_mapping=("/dev/sdb1" "/dev/sdc1" "/dev/sdd1" "/dev/sde1" "/dev/sdf1" "/dev/sdg1") #알파벳 숫자 즉 26번 반복 (적게 해도 무관하다) for i in `seq 0 26`; do nvme_block_device="/dev/nvme$n1" # nvme*n1중 존재하는 블럭만 조건문 실행 if [ -e $nvme_block_device ]; then # ebs 정보를 통해 블럭디바이스 이름과 매핑한다. mapping_device=$(/usr/sbin/ebsnvme-id $ --block-dev) # EBS만 걸러내야 한다. 즉 non_ebs_mapping를 사용해 걸러준다. if [[ -z "$mapping_device" ]]; then mapping_device="$" fi # 간혹 /dev/sde 와같은 형식이 아닌 /sde와 같은 형식으로 나오는 경우 /dev/*로 수정 # EBS를 직접 생성하면서 Attach하는 경우에 이런 경우가 있었던 것 같다. if [[ "$mapping_device" != /dev/* ]]; then mapping_device="/dev/$" fi # 매핑 디바이스 경로가 이미 존재하는 경우 스킵한다. if [ -e $mapping_device ]; then echo "path exists: $" # 경로가 존재하지 않으면 심볼릭 링크를 생성해준다. else echo "symlink created: $ to $" ln -s $nvme_block_device $mapping_device fi fi done
nvme0n1
부터nvme26n1
까지 조사한 후 존재하는 모든 EBS의 nvme 볼륨에 대한 실제/dev/sd*
디바이스 이름으로 링크를 생성해준다. (/dev/sde
를 부르면 실제론 nvme1n1이 불러와지는 효과)- 해당 스크립트를 실행할 때 /usr/sbin/ebsnvme-id 파일이 필요하다. 해당 파일에서 디바이스 이름을 읽어오기 때문
- 생성된 링크에 라벨링을 통해 볼륨에 라벨을 지정한다. ( 라벨 → 링크 → 볼륨 원본 )
- 라벨 정보로
/etc/fstab
에 등록하여 마운트
- 이 모든 작업을 EC2를 생성할 때 자동으로 진행하기
- EBS 생성
Userdata 작성
#!/bin/bash #이 스크립트는 EBS 마운트에 관한 Userdata 스크립트만 다룬다. #내용 이외의 다른 내용은 사용자가 알아서 추가해야함 #파일 시스템 생성 (4개만 테스트해서 그냥 작성했지만 수가많아지면 반복문 작성도 가능하다.) mkfs -t xfs /dev/nvme1n1 mkfs -t xfs /dev/nvme2n1 mkfs -t xfs /dev/nvme3n1 mkfs -t xfs /dev/nvme4n1 # 깃허브에서 nvme를 식별할 2개의 파일 다운 # 파이썬 파일 실행을 위한 파이썬 설치 zypper install -y python wget https://gist.githubusercontent.com/wwdcr2/131ae0d087c78ec242f55737b9e53ac8/raw/07772083fa1c2e567ed422eb401ac7783487d1c7/ebsnvme-id -P /usr/sbin wget https://raw.githubusercontent.com/wwdcr2/LinuxFile/master/nvme-to-block-mapping -P /usr/sbin/ # 설치한 파일들의 권한 설정 chmod 755 /usr/sbin/ebsnvme-id chmod 755 /usr/sbin/nvme-to-block-mapping # 스크립트 실행 및 /usr/sbin/nvme-to-block-mapping # 생성된 /dev/sd* 링크에 라벨을 붙인다. xfs_admin -L ebs1 /dev/sdh xfs_admin -L ebs2 /dev/sdi xfs_admin -L ebs3 /dev/sdj xfs_admin -L ebs4 /dev/sdk # 라벨을 통해 EBS를 fstab에 등록한다. echo "LABEL=ebs1 /test/gb11 xfs defaults,nofail 1 0" >> /etc/fstab echo "LABEL=ebs2 /test/gb22 xfs defaults,nofail 1 0" >> /etc/fstab echo "LABEL=ebs3 /test/gb33 xfs defaults,nofail 1 0" >> /etc/fstab echo "LABEL=ebs4 /test/gb44 xfs defaults,nofail 1 0" >> /etc/fstab # 마운트 될 디렉터리를 생성한다. mkdir -p /test/gb11 mkdir -p /test/gb22 mkdir -p /test/gb33 mkdir -p /test/gb44 #마운트 mount -a
결과
df -hT
명령어로 확인해보면 Size와 Mount 경로가 일치하는 것을 볼 수 있다.
- 또한 순서대로 생성함과 무관하게
/dev/nvme*n1
는 랜덤하게 생성됨을 확인할 수 있다.
결과
- 수동작업이 시간이 엄청나게 오래 걸리는 것은 아니지만 수동 작업은 언제나 실수를 부를 수 있다.
- UUID를 통해 마운트 작업을 하다보면 생각보다 머리가 아프고 볼륨이 같은 EBS 끼리는 또 구분하느라 귀찮은데, 이 문제를 생성시에 마운트하는 작업으로 간단히 해결해서 효율이 늘어날 것으로 예상된다.
- 서버 생성 후 추후에 볼륨을 추가하더라도 스크립트 실행을 통해 간단하게 새로운 볼륨을 마운트할 수 있을 것이다.
Uploaded by Notion2Tistory v1.1.0