육장. 블록 스토리지 리소스를 제어하는 방법

YeongWoooo·2021년 9월 8일
0
post-thumbnail

AWS를 공부하는 입장에서 바라봤습니다! 이해를 위해 중간중간 견해나 비유가 들어갈 수 있습니다. 틀리거나 잘못된 부분이 있으면 언제든지 댓글 달아주시면 감사하겠습니다😀

들어가기

이제 블록 스토리지 리소스를 제어하는 API를 사용하는 방법과 내부적인 동작 원리에 대해 설명합니다. 오픈스택에서는 Cinder, AWS에서는 EBS(Elastic Block Store)가 블록 스토리지에 해당합니다. SSD나 HDD를 단독으로 사용할 수 없듯이, 블록 스토리지는 서버에 연결되어야만 사용할 수 있습니다. 평소에 EBS를 기본 설정대로 사용하다가 용량이 모자랐던 기억이 있어 꼭 알아둬야할 파트라고 생각합니다. 어떻게 서버와 스토리지를 연결하는지 알아보겠습니다.

1. 블록 스토리지 리소스의 제어를 위한 기본 API

블록 스토리지 리소스

블록 스토리지 리소스는 크게 스냅샷과 볼륨, 이 두 종류로 구분됩니다.

볼륨은 SSD, HDD와 같이 실제로 서버에 연결되는 디스크를 의미하고, 비휘발성의 특징을 가집니다. 서버가 꺼져도 데이터는 온전히 보전된다는 뜻입니다. 이런 디스크 중에도 이페머럴(ephemeral) 디스크라는 휘발성 뒤스크가 있는데, 이것은 가상 서버 타입을 선택할 때 함께 제공되기 때문에 서버 리소스 서비스에 기본적으로 포함되어 있습니다.

스냅샷은 마치 그 순간을 사진으로 찍어낸 것 처럼 어느 순간의 볼륨을 복제한 것입니다. 스냅샷으로는 서버에 직접 연결해서 사용할 수 없고, 볼륨으로 복원한 후에 서버에 연결해 사용할 수 있습니다. 스냅샷은 별도의 공간에 저장됩니다.

블록 스토리지와 API

앞서 서버도 API를 이용해 생성할 수 있었다면, 물론 블록 스토리지도 API를 통해 제어할 수 있습니다. 오픈스택에서는 'cinder'명령(볼륨 컨트롤)과 'nova'명령어(서버 컨트롤)로, AWS에서는 'EC2'명령으로 제어합니다. 이는 물리적으로 볼륨을 확장하거나 변경하는 것보다 훨씬 간단하고 효율적으로 변경할 수 있습니다. 그렇더라도 명령어 뒤의 내부 API들의 흐름을 알아야 더 잘 활용할 수 있을 것 같습니다.

블록 스토리지를 제어하기 위한 API의 처리 흐름

명령어를 호출해서 블록스토리지를 제어할 때, 어떤 순서로 진행될까요? 일반적인 순서로는 '볼륨 용량 확보' → '가상서버와 연결' 순으로 진행됩니다. 볼륨 엔드포인트로 인증 컴포넌트를 이용해 사용자 인증을 하고, 먼저 볼륨에 대한 설정을 합니다. 볼륨에 대한 설정이 완료되고 나면, 서버 엔드포인트로 사용자 재인증 후 해당 볼륨에 대한 서버작업이 이루어집니다. 볼륨과 서버가 붙는 작업을 '어태치(attach)'라고 합니다. 이 과정 모두 전 장에서 언급한 것 처럼 비동기로 이루어집니다. AWS에서는 EC2에 볼륨과 서버작업에 대한 API가 동일하기 때문에 해당 엔드포인트로 작업을 진행하면 됩니다.

주의할 점은 서버와 볼륨이 서로 다른 가용영역에 두고 연결하지 않는 것입니다. 가장 흔한 에러 유형으로 마치 각각 다른 본체에 CPU와 SSD를 꽂고 연결되기를 바라는 것과 같다는 생각이 들었습니다.

볼륨 타입

블록 스토리지의 백엔드는 물리적 디스크입니다. 시중에 나와있는 많은 SSD들이 특성과 기능이 다르듯이 디스크도 특성과 설정에 따라 I/O 특성도 달라집니다. 실제로 AWS에서 볼륨의 타입에 따라 I/O 성능이나 기능이 달라지는 경우가 있습니다. 이렇듯 클라우드 환경에서는 볼륨 타입을 명시적으로 선택할 수 있습니다.

볼륨 사이즈

볼륨 사이즈는 볼륨을 생성할 때 결정합니다. 오픈 스택과 AWS의 경우 GB단위로 설정 가능하며 블록 디바이스의 특성상 가상 서버의 OS에서 파일 시스템으로 인식되는 용량까지만 사용 가능합니다. 실제로 300GB의 블록 스토리지를 할당해놓고 자꾸 서버가 꺼지는 오류가 있어 알아보니 파일시스템에서 8GB만 할당해서 사용했던.... 이슈를 목격한 적이 있습니다.

그리고 볼륨은 디바이스 단위로 연결되기 때문에 OS에서 여러 디바이스를 사용한 소프트웨어 RAID(복수 배열 독립 디스크. Disk Array라고도 불림)를 구성할 수 있습니다. RAID는 여러개의 하드디스크에 일부 중복된 데이터를 담아서 나눠서 저장하는 기술입니다.

또한 볼륨의 용량은 무한이 아닙니다. 오픈스택의 경우 백엔드 스토리지의 남은 용량에 따라 증설 용량이 제한됩니다. AWS의 경우 EBS는 Magnetic타입을 제외하고는 하나의 EBS 볼륨당 16TB 용량이 상한 값으로 설정되어있습니다.

스루풋, IOPS, SR-IOV

가상서버와 블록 스토리지는 네트워크로 연결되어 있습니다. 그래서 백엔드 스토리지의 성능도 물론 중요하지만, 네트워크의 성능 또한 중요합니다. 이때 성능이 어느정도인지 가늠하기 위한 지표로는 스루풋(초당 전송 대역), IOPS(초당 Input과 Output의 횟수)를 사용합니다.

AWS의 경우 IOPS가 볼륨 타입에 따라 달라집니다. Magnetics타입은 평균 100 IOPS정도이고, SSD타입은 GB단위의 용량의 3배가 기본이라 최대 10,000 IOPS입니다. 보통 IOPS를 늘리고 싶다면, 용량을 많이 할당하는 방법을 사용합니다. 단 3TB를 넘으면 상한에 이르기 때문에 병렬적으로 분할하는 것이 더 유리합니다.

스루풋은 볼륨에서는 변경할 수 없고 볼륨 타입에 따라서 달라집니다. 볼륨을 대량으로 연결시킴으로써 전체적인 스루풋을 향상시킬 수는 있지만 서버 측의 네트워크에 병목현상이 나타날 수 있습니다. AWS의 EC2는 인스턴스 유형에 따라 최대 스루풋이 결정됩니다. 그러므로 병목현상이 일어난다면 EC2의 인스턴스 유형을 상위 유형으로 늘려주는 것이 좋습니다.

블록 스토리지는 네트워크를 경유하기 때문에, 시스템의 구성 방식이 원인이 되어 병목이 발생할 수도 있습니다. 성능을 개선해야할 때 서버 측에서 SR-IOV(Single Root I/O Virtualization)을 활용할 수 있습니다. 기존에는 하이퍼바이저가 순차적으로 처리하기 때문에 병목현상이 생길 수 있지만, 하이퍼 바이저를 건너 뜀으로써 PCI가 하드웨어 수준에서 병렬 처리를 하기때문에 병목현상을 해결할 수 있습니다.

스냅샷, 백업, 클론

이전에 언급했던 스냅샷에 대해서 더 자세히 알아보겠습니다. 사진을 순간 찍은 것 처럼, 특정 시점에 볼륨에 기록된 블록 단위의 데이터를 보존하는 것으로 저장 속도가 굉장히 빠른 것이 특징입니다. 백업은 볼륨에 저장된 데이터를 내구성이 높은 오브젝트 스토리지에 보존하는 것이고, 클론은 볼륨을 직접 복제하는 것입니다.

AWS에서는 스냅샷을 생성하면 내부적으로 S3서비스에 저장되어 백업을 하는 것과 같은 효과를 냅니다. 그리고 같은 볼륨에 대해 스냅샷을 생성하면 변경사항만 S3에 보내지므로 더 빨리 스냅샷을 생성할 수 있습니다. 과금에서도 추가된 볼륨에 대해서만 책정을 합니다. 다음 링크에서는 볼륨의 클론 방법을 알려주고 있습니다.

스냅샷과 이미지의 관계

이미지에서 기동하는 방식과 스냅샷에서 기동하는 방식은 얼핏 보면 서로 비슷해 보입니다. 이미지는 서버를 기동할 때 사용되고, 스냅샷은 볼륨을 본 떠 만든 것인 만큼 볼륨을 기동할 때 사용됩니다. 단순히 루트 볼륨 하나로 서버를 기동하면 스냅샷을 이용해서 기동한 경우와 다를 바 없지만, 이미지를 사용한 방법은 여러 개의 스냅샷을 함께 다루며 블록 디바이스와의 매핑 관계도 정의할 수 있습니다.

블록 스토리지의 내부 구성

볼륨을 생성할 때 처리되는 내용은 '서버가 생성되는 과정'과 다를 바 없습니다. 서버 대신 볼륨을 대입하면 대부분 비슷합니다. 하지만 서버와 볼륨을 연결하는 과정(attach)은 다른 방식으로 동작합니다. 어떻게 연결하는 지 과정을 함께 알아보겠습니다.

가상 서버와 블록 스토리지의 연결

가상 서버와 볼륨을 연결하는 API가 호출될 때 오픈스택 내부에서 벌어지는 작업들은 다음과 같습니다.

  1. 가상 서버와 블록 스토리지의 연결 요청
  2. 메시지 큐에 요청메세지 추가
  3. 스케쥴러가 하이퍼바이저를 선택 후, 하이퍼바이저가 연결처리
  4. 블록 스토리지와 연결 준비
  5. 실제 연결 처리

서로 다른 인프라 리소스 간의 자동 협상

더 깊게 하이퍼바이저가 요청을 접수한 부분부터 더 자세히 살펴보겠습니다. 순서는 다음과 같습니다.

  1. 볼륨예약: 예약을 먼저 걸어 락을 겁니다. 해당 볼륨을 선점해 다른 곳에서 이중으로 쓰이지 않게 처리합니다.
  2. 연결준비
  3. 실제 접속 처리
  4. 연결 성공 통보

클라우드 내부에서도 사용되는 API

앞의 예를 보면 인프라의 리소스들이 추상회되어 있고 필요로 하는 기능들이 API로 제공됨에 따라 프로그램 간의 연계도 쉬운 것을 알 수 있습니다. 오픈스택을 사용하지 않더라도 별도의 프로그램을 사용해서 조작할 수 있지만, 오히려 유지보수가 어렵기 때문에 오픈스택 기능을 활용하는 것이 더 좋습니다.

블록 스토리지 리소스를 조작할 때의 주의사항

API를 사용해 스토리지의 기능이 추상화되는 것은 관리 포인트가 줄어들기도 하지만, 오히려 특정 스토리지의 고유 기능은 사용하지 못한다는 단점이 있습니다. 보통 일반적으로 가지고 있는 기능을 추상화해서 제공하기 때문에 특정 기능이 있을 경우 사용할 수 없습니다. 하지만 스토리지가 가지고 있는 고도의 기능들은 OS의 파일 시스템이나 논리 볼륨 기능으로도 대체가 가능합니다.

블록 스토리지 리소스의 컴포넌트

지금까지 블록 스토리지 관련 리소스들은 상관관계를 가지고 있습니다. 여기서 이미지는 여러 서버를 만들 수 있고, 한 서버는 여러 볼륨을 선택할 수 있습니다. 그리고 볼륨에서 여러 개의 스냅샷을 생성할 수 있습니다. 이렇게 트리형태의 구조가 만들어집니다. 이렇게 이미지로 형상화하면서 이해를 하면 클라우드 환경을 관리하는데 큰 도움이 됩니다.

그 외의 스토리지 기능

앞서 말씀 드렸듯이 하나의 서버에 여러 개의 볼륨을 사용할 수 있습니다. 그렇다면 거꾸로 하나의 볼륨을 여러 서버가 공유해서 사용할 수는 없을까요? 물론 해결책이 있습니다. 바로 NFS입니다. AWS에서는 NFS 서비스에 해당하는 것은 EFS(Elastic File Services)입니다. 각 가용 영역에 접속 인터페이스를 두고 스토리지를 분산 배치할 수 있기 때문에 내구성이 높습니다.

마무리

하고 있던 외주작업이 볼륨 이슈가 있어서 이것저것 찾아보던 와중에 반가운 내용이었습니다. 할당 후 연결까지의 과정이 어떻게 진행이 되는지 알 수 있어서 유익했습니다. 백업과 클론같은 다양한 기술들을 알게된 것 같아 나중에 한번 적용해보면 좋을 것 같다는 생각이 들었습니다!

참고

  • 그림으로 배우는 클라우드 인프라와 API의 구조 - 히라야마 쯔요시 저
profile
개발 재밌다!

0개의 댓글