홈랩 VM 서버 구축하기
참고: 이 글은 2017년에 구축한 VM 환경을 다룹니다.
2020년 버전은 “홈랩 VM 서버 구축하기 (2020년판)”을 참고하세요.
개요
저는 집에서 하는 개발 작업 대부분을 가상 머신(VM)에서 합니다. 메인 데스크톱 PC는 Windows 10 머신이라 지금까지는 항상 VirtualBox 안에서 VM을 실행해 왔습니다.
이 구성으로도 문제없이 동작했지만, 점점 불편한 점들이 눈에 띄기 시작했습니다. 검색하다가 Brian Moses가 VM 실행을 위한 전용 ‘홈랩’ 서버를 구축한 과정을 설명한 글을 찾았습니다. 이 아이디어가 정말 마음에 들어 저도 따라 해보기로 했습니다.
VM을 쓰는 이유
깔끔한 환경
제가 만드는 모든 소프트웨어는 특정 소프트웨어 환경에 의존합니다. 예를 들어 제 프로젝트인 ProsperBot 개발은 Go 툴체인, nginx, Redis에 의존합니다. 각 프로젝트의 의존성을 메인 데스크톱 PC 하나에 계속 설치하다 보면 서로 다른 웹 서버와 데이터베이스 서버, 충돌하는 라이브러리 버전으로 엉망이 됩니다.
보안: VM 격리
VM은 소프트웨어를 메인 시스템으로부터 격리해 보안 측면에서도 도움이 됩니다. 저는 새로운 도구나 앱을 시험해 보는 걸 좋아하는데, 앱이 악성일 가능성도 항상 있습니다(개발자가 악성 앱을 만들었을 수도 있고, 정상적인 앱이어도 공격자가 악성코드 유포를 위해 변조했을 수도 있습니다). 앱을 Windows 머신에 직접 설치했는데 악성코드에 감염되면 그대로 끝입니다. 아주 기초적인 악성코드라도 제 컴퓨터에서 실행되면 화면의 모든 내용을 기록하거나 Gmail, Facebook, GitHub을 장악하고, 모든 파일을 인질로 잡을 수도 있습니다.
VM 안에서 실행되는 악성코드는 일으킬 수 있는 피해가 훨씬 제한적입니다. VM에 소프트웨어를 설치했는데 몰래 키로거가 설치되더라도 메인 데스크톱이 아니라 해당 VM 내부의 키 입력만 기록할 수 있습니다. 물론 고도화된 악성코드는 VM을 탈출할 수도 있어 VM이 완벽한 방어책은 아니지만, 여전히 상당한 수준의 보호를 제공합니다.
왜 별도의 VM 서버가 필요한가?
지금까지 메인 Windows 데스크톱에서 VirtualBox로 가상 머신을 실행해 왔는데, 몇 가지 문제가 있었습니다.
- 메인 PC를 재시작할 때마다 실행 중인 모든 VM을 일일이 종료하거나 절전 상태로 만든 뒤, 재부팅 후에 다시 하나하나 켜야 합니다.
- 메인 PC는 한 달에 한 번 정도 다운되는데, VirtualBox는 충돌 복구에 매우 취약합니다. 재부팅하면 VM 이미지 파일이 잠겨 있다고 판단해 파일 시스템을 직접 만져서 문제를 해결해야 합니다.
전용 VM 서버가 있다면 아주 가벼운 Linux 서버 OS만 올려서 운영할 수 있습니다. 머신에서 실행되는 소프트웨어가 적을수록 재부팅이 필요한 빈도도 줄고 충돌 가능성도 낮아집니다.
흥미롭게 생각하는 P2P 프로젝트도 몇 가지 있습니다(예: OpenBazaar, BitSquare). 하지만 이런 프로젝트들은 서버를 항상 켜 두어야 합니다. VirtualBox로 시도해 본 적은 있지만, 앞서 언급한 번거로움 때문에 VM을 계속 유지하려는 의욕이 금방 사라졌습니다. VM을 한 번 띄워 두고 계속 실행해 둘 수만 있다면 이런 프로젝트를 실험하는 일이 훨씬 매력적으로 다가옵니다.
부품 선택
CPU
Brian의 블로그 글에서는 중고 Intel Xeon CPU의 저렴한 가격을 활용할 수 있다는 점에 흥분하고 있었습니다. 흥미로운 아이디어였지만, 저는 중고 서버 하드웨어의 고장 위험이 걱정되어 새 정품 CPU를 선호했습니다.
메인 PC에서는 CPU를 오버클럭해서 쓰고 있지만, 그 때문에 가끔 충돌이 발생하기도 합니다. VM 서버는 최대한 안정적으로 유지하고 싶었기 때문에 이번 시스템은 오버클럭하지 않기로 했습니다. 덕분에 오버클럭을 지원하는 언락 CPU나 메인보드, 고급 CPU 쿨러에 추가 비용을 들일 필요가 없어 부품 선택이 더 쉽고 저렴해졌습니다.
결국 AMD Ryzen 7 1700을 선택했습니다. 8코어 16스레드라 많은 VM을 돌리기에 적합하고, 최근 평판도 아주 좋은 제품입니다.
메인보드
저는 맨해튼의 꽤 작은 원룸 아파트에 살고 있어 물리적인 공간이 매우 귀합니다. 다행히 제 요구사항 덕분에 디스크 드라이브나 GPU, 고급 CPU 쿨러처럼 PC에서 부피를 많이 차지하는 부품을 상당수 생략할 수 있었습니다.
이런 조건 때문에 MicroATX 메인보드를 알아보게 되었고, 최종적으로 ASRock AB350M-HDV를 선택했습니다. 과거에 ASRock 보드를 써 본 경험이 좋았고, 이 제품도 안정적인 선택으로 보였습니다. 다만 메모리 지원이 망설여지는 부분이었는데, RAM 슬롯이 두 개뿐이라 16GB 스틱 두 개를 끼우면 더 이상 확장할 여지가 없기 때문입니다. 그래도 나중에 RAM이 부족해지면 그때쯤엔 32GB 스틱 두 개가 나와 있을 테니 그냥 두 개 다 교체하면 되겠지 하고 생각했습니다.
돌이켜보면 내장 그래픽이 있는 메인보드를 샀어야 했다고 생각합니다(아래 부품 리뷰를 참고하세요).
메모리
메인 PC는 RAM이 32GB이며 일상적인 사용 중에도(Windows 10에 여러 VM을 띄운 상태에서도) 15GB 정도를 사용하는 편입니다. 16GB로도 아마 충분하겠지만, 향후 2~3년을 생각하면 32GB가 안전한 상한선이라고 판단했습니다. G.SKILL Flare X Series 32GB (2 x 16GB)는 제 메인보드와 호환성이 검증된 RAM 중 가장 빠른 제품이라 선택했습니다.
디스크
Brian과 마찬가지로 저도 NAS를 가지고 있어 저장 공간은 충분한 상황이라, 로컬 스토리지는 호스트/하이퍼바이저 OS를 담을 작은 디스크 하나면 충분했습니다. 250GB Samsung 850 EVO를 선택한 가장 큰 이유는 M.2 인터페이스가 매우 깔끔하기 때문입니다. 메인보드에 칩 하나를 나사로 고정하면 끝이라 브라켓이나 SATA 케이블을 신경 쓸 필요가 없습니다. 250GB는 제게는 훨씬 넉넉한 용량이지만, M.2 SSD에서는 그 정도가 보급형 입문 용량인 것 같습니다.
케이스
케이스는 무엇보다 아주 작은 제품을 찾고 있었습니다. 서버를 눈에 띄지 않는 곳에 숨겨 둘 계획이라 예쁘거나 화려할 필요도 없었습니다. Rosewill Micro ATX SRM-01은 작고 저렴하면서도 실용적인 제품입니다.
그래픽
이 시스템은 대부분 헤드리스(headless)로 운영하면서 SSH/Ansible로 관리할 예정이지만, 초기 설치 때나 네트워크 설정을 잘못 건드렸을 때처럼 가끔은 화면 출력이 필요합니다. 처음에는 메인보드의 내장 그래픽을 쓸 수 있을 거라고 생각했지만, 실제로는 불가능했습니다(아래 부품 리뷰를 참고하세요).
GPU에 대한 요구사항이 딱히 까다롭지 않았기 때문에, 저렴하면서 평이 좋은 제품을 찾았고 EVGA GeForce 8400 GS를 선택했습니다.
99.99%의 시간 동안은 헤드리스로 관리할 텐데 이 시스템을 위해 모니터를 따로 사는 건 의미가 없었습니다. 나머지 0.01%의 시간에는 그냥 책상 밑으로 기어 들어가 메인 모니터의 HDMI 케이블을 주 데스크톱에서 VM 서버로 옮기면 됩니다.
네트워크 어댑터
원래는 1Gbps 네트워크만 사용하므로 메인보드에 내장된 1Gbps NIC를 그대로 쓰려고 했습니다. Ubuntu 16.04에서도 별다른 설정 없이 동작하긴 했지만, 곧 네트워크 속도가 10Mbps 정도로 제한되는 것을 알게 되었습니다. 좀 찾아보니 Ubuntu 16.04에 올바른 드라이버가 포함되어 있지 않아 별도의 apt-get 저장소를 추가해 r8168-dkms 패키지를 설치해야 한다는 것을 알았습니다. 그렇게 했더니 이번에는 재부팅 후 Ubuntu가 NIC를 아예 인식하지 못했습니다…
이쯤 되자 온보드 NIC를 만지작거리는 데 지쳐, Ubuntu에서 별도 설정 없이 지원된다고 알려진 PCI NIC(Broadcom BCM5751 NetXtreme)를 그냥 구입했습니다. 별다른 손질 없이 바로 1Gbps 속도를 냈기에 23달러를 내고 온보드 NIC 문제를 계속 파고드는 데 시간을 쓰지 않기로 했습니다.
참고로 온보드 NIC는 ESXi 6.5와 호환되지 않았지만, Broadcom NIC는 호환되었습니다.
최종 부품 목록
| 카테고리 | 부품 | 구매가 |
|---|---|---|
| CPU | AMD Ryzen 7 1700 | $323.66 |
| 메인보드 | ASRock AB350M-HDV | $69.99 |
| 디스크 | Samsung 850 EVO - 250GB | $99.99 |
| 메모리 | G.SKILL Flare X Series 32GB (2 x 16GB) F4-2400C15D-32GFXR | $224.99 |
| 파워 | EVGA 430 W1, 80+ WHITE 430W 100-W1-0430-KR | $29.99 |
| 그래픽 | EVGA 512-P3-1300-LR GeForce 8400 GS | $29.99 |
| 네트워크 | Broadcom BCM5751 Netxtreme | $22.95 |
| 케이스 | Rosewill Micro ATX SRM-01 | $21.99 |
| 총 비용 | $823.55 |
조립
모든 부품을 모았으니 이제 조립을 시작할 차례입니다!
조립 전 모든 부품의 모습입니다. 사진에 NIC와 GPU가 빠진 이유는 실제로 시스템을 구동해 보기 전까지는 그 부품들이 필요하다는 걸 몰랐기 때문입니다.
부품을 모두 조립한 서버의 모습입니다. 부품 수가 많지 않아 구성도 아주 단순합니다. 특히 유일한 디스크가 메인보드에 직접 연결된 M.2 SSD라 디스크용 전원 케이블이나 SATA 케이블을 정리할 필요가 없어 편리했습니다.
아파트 공간이 협소하다 보니 눈에 띄지 않는 곳에 숨길 수 있는 서버를 원했습니다. 책상 서랍 뒤, 책상 옆 공간에 두기로 했습니다. 메인 데스크톱만큼 손이 닿는 위치에 있으면서도 대부분 시야에서는 가려집니다.
조립 완료
호스트 OS 설치
VM 서버의 호스트 OS는 최대한 가벼워야 합니다. 하이퍼바이저를 호스팅하는 것 외에는 할 일이 거의 없기 때문입니다. 호스트에 소프트웨어를 많이 설치할수록 안정적인 서버를 위해 계속 업데이트해야 할 패키지도 늘어납니다.
몇 가지 Linux 배포판을 시도해 봤지만, 제 하드웨어에서 별다른 설정 없이 바로 동작한 것은 Ubuntu Server뿐이었습니다(16.04와 17.04 모두 성공적으로 테스트했습니다). 다른 배포판에서 설치가 실패한 원인은 Ryzen의 SMT 기능 때문이라고 생각합니다. BIOS에서 SMT를 비활성화한 뒤 다른 배포판을 설치하고 커널을 >= 4.10으로 업그레이드한 다음 SMT를 다시 활성화하면 해결될 수도 있겠지만, 어차피 가장 익숙한 배포판이기도 해서 그냥 Ubuntu 16.04 Server를 사용하기로 했습니다.
가상 머신 실행
KVM
하이퍼바이저로는 KVM을 사용했습니다. 비교적 성숙한 제품이고 사용자층이 넓어 문제가 생겼을 때 검색으로 지원 정보를 찾기에도 용이합니다. 기업용 하이퍼바이저 중에는 소프트웨어 자체는 무료라도 라이선스 키를 요구하는 경우가 있지만, KVM은 무료 오픈소스라 그런 문제가 없습니다.
Kimchi
저는 인프라를 웹 UI로 관리하는 것을 선호해서, HTML5로 구현된 KVM 관리 UI인 Kimchi를 설치했습니다.
Kimchi를 한마디로 표현하자면 “그럭저럭 괜찮다” 정도입니다. 일부 대시보드는 꽤 세련되어 보입니다.
Kimchi 웹 UI 스크린샷
브리지 네트워크 어댑터를 만드는 것처럼 커맨드라인에서는 다소 까다로운 작업을 정말 잘 처리해 주는 부분도 있습니다.
단점은 주로 UX에 있습니다. 간단한 작업을 하는 데도 클릭을 많이 해야 하고, 페이지가 갱신되는 순간(예: 게스트 VM 종료가 완료되는 시점) 컨텍스트 메뉴가 사라져 처음부터 다시 진행해야 하는 상황을 자주 겪습니다. 그렇다고 단점이 심각할 정도는 아니고, 쓰다 보니 이런 UX 버그를 피하도록 제 사용 방식을 조정하는 것도 점점 쉬워졌습니다.
후보였던 ESXi 6.5
사실 이 프로젝트를 시작할 때는 VMware의 무료 하이퍼바이저인 VMware vSphere Hypervisor를 사용할 계획이었습니다. 훨씬 성숙한 제품이고 사용자층도 넓어(아마도 지원 정보를 찾기 쉬울 것 같아) 좋은 선택으로 보였습니다. 하지만 제 메인보드의 NIC와 Ryzen CPU 모두와 호환되지 않았습니다. Broadcom NIC를 설치하고 BIOS에서 CPU의 SMT를 비활성화한 뒤에야 겨우 실행할 수 있었는데, 그때는 이미 Kimchi를 며칠간 사용하며 익숙해진 뒤였습니다.
vSphere가 Kimchi보다 훨씬 나은 경험을 제공하지는 않는 것 같았습니다. UI는 훨씬 세련되어 있지만, 한 번 실수하면 여러 단계로 이루어진 전체 과정을 처음부터 다시 시작해야 하는 어색한 흐름도 있었습니다. 커맨드라인에서 원하는 작업을 바로 수행하려고 셸에 접근하는 방법도 명확하지 않았습니다(분명 가능하겠지만, 답을 찾을 때까지 충분히 파고들지는 않았습니다).
결정적인 문제는 로그인할 때마다 60일 안에 VMware 등록 키를 입력하지 않으면 소프트웨어가 동작을 멈춘다는 경고가 크게 표시된다는 점이었습니다. VMware는 라이선스 키를 무료로 제공하지만, 라이선스 확인 절차가 전혀 없고 vSphere와 거의 대등한 경험을 제공하는 Kimchi가 있는데 굳이 등록 키를 신경 쓰고 싶지 않았습니다.
서버 프로비저닝 자동화
저는 Ansible을 아주 좋아해서 VM 서버를 자동으로 프로비저닝하는 Ansible 플레이북을 작성했습니다. 이 플레이북은 다음 작업을 수행합니다.
- Ryzen의 SMT 기능과 호환되는 버전으로 커널을 업데이트합니다
- KVM과 Kimchi를 설치합니다
- VM 이미지를 저장할 NFS 공유를 마운트합니다
Ansible을 설치한 뒤 아래 명령을 실행하면 동일한 플레이북으로 여러분의 서버도 프로비저닝할 수 있습니다.
VM_SERVER=vmaster # Replace with your VM server's hostname
echo "${VM_SERVER}" > hosts
wget https://mtlynch.io/files/provision-vm-host.yml
# Replace the extra-vars with the values for your NFS share
ansible-playbook provision-vm-host.yml \
--extra-vars "cifs_share=/nas-hostname/VMs" \
--extra-vars "cifs_username=foo" \
--extra-vars "cifs_password=bar"
선택 돌아보기
CPU 리뷰
가장 고민되는 선택은 CPU였습니다. 동작 속도는 매우 빠르지만, 다소 과한 선택이었을 수도 있습니다. CPU 집약적인 작업을 여러 VM에서 동시에 돌리고 다섯 개의 VM을 실행한 상태에서도 전체 CPU 사용률이 35%를 넘은 적이 없기 때문입니다.
Ryzen의 단점은 현시점에서 너무 최신 기술이라 호환성이 불안정하다는 점입니다. Fedora 25 Server, Debian 8.7, CentOS 7, ESXi 6.5를 설치해 봤지만 모두 Ryzen과 호환되지 않아 설치 도중 실패했습니다. BIOS에서 CPU의 SMT(멀티스레딩)를 비활성화하면 일부는 설치에 성공했지만, 그렇게 하면 16스레드에서 8코어로 줄어드는 셈이라 아쉬웠습니다. 성공적으로 설치된 OS는 Ubuntu뿐이었습니다(16.04와 17.04 모두 성공).
Ryzen 때문에 구매할 수 있는 RAM 선택지도 제한되었습니다. 메인보드는 DDR4 3200MHz까지 지원하지만, Corsair에는 해당 보드와 호환성이 검증된 메모리가 없습니다. G.SKILL은 호환 제품을 제공하지만, DDR4 2400MHz보다 빠른 제품은 없습니다.
메인보드 리뷰
메인보드 선택에는 대체로 만족합니다. 작고 컴팩트하면서도 모든 부품을 올리기에 충분한 공간을 제공합니다.
한 가지 후회되는 점은 온보드 비디오 지원을 꼼꼼히 읽지 않았다는 것입니다. “Onboard Video Chipset” 항목의 사양에는 이렇게 적혀 있었습니다.
Integrated AMD Radeon R7/R5 Series Graphics in A-series APU Supports HDMI with max. resolution up to 4K x 2K (4096x2160) @ 24Hz / (3840x2160) @ 30Hz
그래서 저는 “오, 자체 그래픽 카드가 있네. 설치할 부품이 하나 줄겠군”이라고 생각했습니다. 제가 이해하지 못했던 점은 이 문구가 “AMD A시리즈 APU가 있을 경우에만 그래픽을 지원한다”는 의미였다는 것입니다. APU는 AMD의 CPU/GPU 통합 칩인데, Ryzen은 APU가 아니므로 저에게는 온보드 그래픽이 제공되지 않았습니다.
다시 선택한다면 온보드 GPU가 있어 더 간단하다는 이유만으로 GIGABYTE GA-AB350M-Gaming 3를 선택할 것 같습니다.
RAM 리뷰
32GB는 처음에는 과해 보였지만, 다양한 용도로 VM을 하나둘 추가하다 보니 RAM 사용량이 18GB를 넘어서고 있어 16GB 대신 32GB를 선택하길 잘했다고 생각합니다.
파워 서플라이 리뷰
파워 서플라이는 시스템에 충분한 용량을 제공하며 소음도 꽤 조용합니다. 30달러라는 가격에 가성비도 좋습니다.
한 가지 단점은 논모듈러(non-modular) 케이블을 사용한다는 점입니다. 제 시스템은 워낙 최소 구성이라 24핀 메인보드 케이블과 8핀 CPU 케이블만 있으면 되는데, 나머지 케이블은 모두 불필요한 짐이 됩니다. 다만 케이스의 5.25인치 광학 드라이브 베이(제 경우 당연히 비어 있습니다)에 깔끔하게 숨길 수 있어 그나마 다행입니다.
다시 구성한다면 불필요한 파워 케이블을 없앨 수 있도록 세미 모듈러나 풀 모듈러 PSU를 고려할 것 같습니다.
결론
이 홈랩 VM 서버는 매우 잘 동작하고 있습니다. VM이 항상 실행 중이라는 걸 알 수 있어 VirtualBox에서 뭔가를 직접 띄울 필요 없이 바로 SSH로 접속하거나 브라우저에서 확인할 수 있다는 점이 매우 편리합니다.
예상치 못한 장점 중 하나는 게스트 OS에 CPU/RAM 자원을 할당할 때 더 이상 인색할 필요가 없어졌다는 점입니다. 메인 데스크톱은 8코어 i7에 RAM 32GB 사양이라, VM이 메인 OS의 자원을 고갈시킬까 봐 게스트 OS에는 보통 1 CPU + 1GB RAM만 할당하고 자원 부족이 보일 때만 늘리곤 했습니다. 홈랩 VM 서버에서는 모두에게 충분한 자원이 있습니다! 제 표준 게스트 OS 템플릿은 4코어와 4GB 메모리를 사용하며, 이는 대부분의 환경에서 충분한 상한선입니다. 덕분에 게스트 OS 자원을 일일이 수동으로 관리하는 데 들이는 시간을 줄일 수 있습니다.
다양한 개발 및 스테이징 환경이 필요한 소프트웨어 프로젝트를 진행한다면, VM에서 작업하고 전용 VM 서버 머신을 사용하는 것을 적극 추천합니다.
글을 무작위로 읽기










