슬슬 본론에 다가서고 있습니다. 잠시 시간을 거슬러 올라가면, 예전에 Vagrant를 소개한 적이 있었습니다. Vagrant는 VirtualBox나 KVM처럼 상대적으로 복잡한 소프트웨어를 깔끔하게 감싸주는 래퍼(wrapper) 역할을 하는 가상화 솔루션으로, 상당히 큰 야망을 지닌 도구입니다. 게다가 Docker 컨테이너 지원과 클라우드 서버 환경까지 제공하기 때문에 한 단계 높은 수준의 활용도 가능합니다.
이번에는 이 모델을 확장해 조금 다른, 그리고 아주 '클라우드다운' 사용 사례를 살펴보겠습니다. 지난 실습에서 사용했던 CoreOS 역시 클라우드 열풍에 편승하는 주요 플레이어 중 하나로, 훌륭한 클러스터 기능과 자동화 기능을 제공합니다. 오늘은 클러스터를 구성하는 방법을 배우고, 네트워킹 부분도 함께 다룰 것입니다. 네트워킹은 의외로 소홀히 다뤄지는 영역이며, 공식 문서에서조차 충분히 설명되지 않는 경우가 많습니다. 그럼 함께 따라와 주세요.
디스커버리 토큰(Discovery Token) 설정
지난번에는 Windows 환경에서 PowerShell을 통해 Vagrant를 일부러 시도하며 '여러 방식으로도 가능하다'는 점을 보여줬지만, 이번 실습은 Linux에서 진행합니다. 더 정확히는 Xubuntu Vivid입니다.
공식 가이드를 따르면 Vagrant용 CoreOS 설정은 어렵지 않습니다. 하지만 온라인 문서가 암시하는 것만큼 간단하지도 않습니다. 빨리 시작하고 싶다는 조급함이 문서 곳곳에서 느껴지기도 합니다.
저장소를 클론(clone)하면 여러 파일이 준비되는데, Vagrant를 초기화하고 실행하려면 일부 파일을 수정해야 합니다. 가장 먼저 할 일은 user-data.sample 파일을 편집한 뒤 user-data로 이름을 변경하는 것입니다. 특히 토큰(token) 부분이 핵심입니다:
#cloud-config
coreos:
etcd:
# generate a new token for each unique cluster from
https://discovery.etcd.io/new?size=3
# specify the intial size of your cluster with ?size=X
# WARNING: replace each time you 'vagrant destroy'
discovery: https://discovery.etcd.io/<token>
기본적으로 CoreOS는 실행 중인 인스턴스들이 서로를 식별할 수 있도록 고유 식별자인 '토큰'을 사용합니다. 동일한 토큰을 가진 모든 호스트는 같은 스웜(swarm)에 속하게 되며, etcd라는 공유 설정 및 디스커버리 서비스를 통해 중앙 집중식으로 관리할 수 있습니다.
https://discovery.etcd.io/new?size=<size>
위 URL에 원하는 클러스터 크기를 지정해 접속하면 새 토큰을 발급받거나 기존 토큰을 사용할 수 있습니다. 기본 구성은 호스트 3개입니다. 생성된 토큰을 기록해 두었다가 다음과 같이 설정 파일에 추가하세요:
https://discovery.etcd.io/21e4099c23b52a8403640c2d48cdca6f
이 토큰이 왜 중요한지는 뒤에서 다시 확인하게 될 것입니다.
클러스터 구성
두 번째 단계는 Vagrant가 시작될 때 몇 개의 CoreOS 인스턴스를 실행할지 정의하는 것입니다. 전체적으로 간단한 설정 작업입니다. 클론한 Git 디렉터리 안의 config.rb.sample 파일을 수정한 뒤 config.rb로 이름을 바꾸면 됩니다. 여기서는 좀 더 특별한 구성을 위해 4개의 인스턴스로 진행해 보겠습니다.
# Size of the CoreOS cluster created by Vagrant
$num_instances=X
클러스터 시작
이제 Vagrant를 실행할 수 있습니다. 온라인 저장소를 클론했다면 현재 디렉터리에 이미 기본 Vagrantfile이 존재하므로, vagrant init 명령은 실패하게 됩니다:
vagrant init
`Vagrantfile` already exists in this directory. Remove it before
running `vagrant init`.
또한 VirtualBox 등 해당 가상화 소프트웨어가 설치되어 있지 않으면 프로그램을 시작할 때 또 다른 오류가 발생합니다. 이런 사소한 문제들은 미리 해결해 두는 것이 좋습니다.
vagrant up
The provider 'virtualbox' that was requested to back the machine
'core-01' is reporting that it isn't usable on this system. The
reason is shown below:
Vagrant could not detect VirtualBox! Make sure VirtualBox is properly installed. Vagrant uses the `VBoxManage`
binary that ships with VirtualBox, and requires this to be available on the PATH. If VirtualBox is installed,
please find the `VBoxManage` binary and add it to the PATH environmental variable.
이 과정을 성공적으로 마쳤다면 Vagrant가 실행되며 CoreOS 인스턴스들을 하나씩 생성하기 시작합니다. 시간이 다소 걸릴 수 있으며, 규모가 큰 클러스터를 구성하려면 충분한 네트워크 대역폭과 메모리가 필요합니다.
vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
Bringing machine 'core-02' up with 'virtualbox' provider...
Bringing machine 'core-03' up with 'virtualbox' provider...
Bringing machine 'core-04' up with 'virtualbox' provider...
==> core-01: Box 'coreos-alpha' could not be found. Attempting to find and install...
core-01: Box Provider: virtualbox
core-01: Box Version: >= 308.0.1
==> core-04: Importing base box 'coreos-alpha'...
==> core-04: Matching MAC address for NAT networking...
==> core-04: Checking if box 'coreos-alpha' is up to date...
==> core-04: Setting the name of the VM: coreos-vagrant_core-04_1431799934824_55775
==> core-04: Fixed port collision for 22 => 2222. Now on port 2202.
==> core-04: Clearing any previously set network interfaces...
==> core-04: Preparing network interfaces based on configuration...
core-04: Adapter 1: nat
core-04: Adapter 2: hostonly
==> core-04: Forwarding ports...
core-04: 22 => 2202 (adapter 1)
==> core-04: Running 'pre-boot' VM customizations...
==> core-04: Booting VM...
==> core-04: Waiting for machine to boot. This may take a few minutes...
core-04: SSH address: 127.0.0.1:2202
core-04: SSH username: core
core-04: SSH auth method: private key
core-04: Warning: Connection timeout. Retrying...
==> core-04: Machine booted and ready!
==> core-04: Setting hostname...
==> core-04: Configuring and enabling network interfaces...
==> core-04: Running provisioner: file...
==> core-04: Running provisioner: shell...
core-04: Running: inline script
모든 시스템이 생성된 후에는 vagrant status 명령을 실행해 기존 머신들과 현재 상태에 대한 정보를 한눈에 확인할 수 있습니다.
네트워킹
이제 정말 흥미로운 부분입니다. 가상 머신 4대가 준비되었는데, 어떻게 접속해야 할까요? Docker를 테스트할 때 비슷한 고민을 했었고, 그때 해결책을 찾았듯이 여기서도 같은 논리가 적용됩니다.
먼저, vagrant ssh 명령으로 실행 중인 각 머신에 접속할 수 있습니다. 이 명령은 키 처리 등을 알아서 담당해 줍니다. 단, 반드시 클론한 디렉터리 안에서 실행해야 하며, 그렇지 않으면 오류가 발생합니다:
vagrant ssh core-02 -- -A
A Vagrant environment or target machine is required to run this
command. Run `vagrant init` to create a new Vagrant environment. Or, get an ID of a target machine from
`vagrant global-status` to run this command on. A final option is to change to a directory with a Vagrantfile
and to try again.
올바른 디렉터리에서 실행하면 정상적으로 동작합니다.
그런데 ifconfig를 실행해 보면 모든 머신이 동일한 IP 주소를 가진 것처럼 보이며, 머신 간 라우팅이 되지 않습니다. 게다가 VirtualBox 인터페이스는 172.0.0.1 대역에서 동작하기 때문에 상황이 더 복잡해집니다. Docker에서 겪었던 상황과 유사합니다.
VirtualBox 내부 네트워크 범위를 사용하고 방화벽 규칙과 라우팅을 직접 조정할 수도 있습니다. 하지만 이 방법은 어떤 가상 머신이 어떤 IP 주소를 사용하는지 실시간으로 파악하기 어렵다는 단점이 있습니다. 즉, 숫자를 임의로 추측할 수 없으며, 올바른 정보를 얻을 수 있는 더 우아한 방법들이 존재합니다.
localhost를 통한 접속
기억하실지 모르겠지만, 시작 과정에서 Vagrant는 각 가상 머신마다 localhost 기반 SSH를 서로 다른 포트(2200번대부터 시작)로 설정합니다. 따라서 클라이언트에 SSH로 접속해야 한다면 다음 방법을 사용할 수 있습니다:
ssh 127.0.0.1 -p 2202
The authenticity of host '[127.0.0.1]:2202 ([127.0.0.1]:2202)' can't be established.
ED25519 key fingerprint is 32:a0:57:58:b3:55:fc:03:c8:89:7d:7c:cc:6f:85:9d.
Are you sure you want to continue connecting (yes/no)?
IP 주소를 통한 어디서든 접속
그러나 위 방법은 VM 간 통신에는 적합하지 않으므로 다른 방법이 필요합니다. 바로 이 지점에서 디스커버리 토큰이 빛을 발합니다. 클러스터가 실행 중이라면 앞서 발급받은 URL에 다시 접속해 보세요. 이번에는 다소 투박하지만 유용한 JSON 데이터가 채워져 있는 것을 확인할 수 있습니다.
키(key)와 값(value)에 주목하세요. 각 항목에는 172.17.8.103 같은 IP 주소가 포함되어 있으며, 이 출력 결과에서 파싱할 수 있습니다. 훌륭합니다. 이제 내부 주소를 알아냈으므로, 이를 이용해 클라이언트에 직접 접속할 수 있고, 더 중요하게는 피어(peer) 간 통신도 가능하게 만들 수 있습니다.
남은 문제는 core 사용자의 비밀번호를 모른다는 점입니다. 따라서 vagrant.d 하위 디렉터리에 있는 제공된 키를 사용하면 됩니다. 키를 등록한 후에는 끊김 없이 seamless하게 접속할 수 있습니다. 이 내용은 첫 번째 가이드에서 이미 다룬 바 있습니다.
포트 포워딩
지금까지 박스(box) 설정 자체를 깊게 다루지는 않았지만, 이제 실행 중인 인스턴스들의 IP 주소를 알았으니 본격적으로 창의적인 구성을 시작할 수 있습니다. 예를 들어, 서비스를 구동하는 가상 머신에 매우 유용한 포트 포워딩(port forwarding)이 그 대표적인 예입니다.
필요한 변경 사항은 Vagrantfile 안에 디렉티브(directive) 형태로 추가하면 됩니다. Dockerfile과 마찬가지로 여러 설정을 위한 여러 구성을 둘 수도 있습니다. 예를 들어 HTTPS 포트를 포워딩하려면 다음과 같이 작성합니다:
config.vm.forward_port 443, <host port>
Docker 관련 글을 읽어보셨다면 매우 쉽게 이해할 것입니다. 호스트 포트와 클라이언트 포트만 지정하면 끝입니다. 박스마다 여러 개의 선언을 추가할 수도 있습니다. 나아가 시스템을 완전히 제어해야 한다면 방화벽 규칙을 수동으로 구성할 수도 있습니다. 물론 이것은 맛보기에 불과하며, 앞으로 이 주제를 더 깊이 다룰 예정입니다.
물론 다음 단계는 Docker를 결합하는 것입니다. 우연이 아니겠지만 기본 포트 대역도 비슷하기 때문에, 클러스터, 컨테이너, 병렬 실행 등 다양한 흥미로운 개념을 실험할 수 있습니다. 이를 위해 Vagrant는 플러그인을 제공하며, 이는 별도 글에서 자세히 다루겠습니다. 작업이 끝나면 인스턴스를 destroy하면 됩니다.
추가 자료
Dedoimedo에서 제공하는 추가 학습 자료입니다:
- CoreOS 퀵스타트 가이드 – 다소 방대할 수 있습니다
- etcd와 유사한 기능을 제공하는 supervisord 튜토리얼
- KVM & VirtualBox 나란히 운영하기 위한 설정 팁
결론
Vagrant와 CoreOS는 흥미롭고 도발적이며 반항기 어린 아이디어로 보입니다. 실무 환경에서 얼마나 큰 가치를 지닐지는 아직 확신이 서지 않습니다. 다만 실제 작업의 복잡한 세부 사항을 숨겨주는 래퍼 기술들이 계속 성장하며 인기를 얻고 있다는 것은 분명한 사실입니다. 모두가 프런트엔드와 오케스트레이션 도구를 원하지만, 문제는 시장이 너무 변덕스럽고 표준이 없다는 점, 그리고 사람들이 Python, Ruby, JSON 같은 도구를 사용한다는 점입니다. 하지만 그건 그거고요.
이번에도 미지의 영역 한 조각을 정복했습니다. 이제 여러분은 Vagrant와 CoreOS 모두에 대해 어느 정도 익숙해졌을 것입니다. 다행스러운 일입니다. 다음 편에서는 이러한 클러스터 서비스들을 직접 다뤄볼 예정이니까요. 그리고 이것은 시작에 불과합니다.
기억하세요, 저는 모든 것을 다뤄야 합니다. 앞으로 몇 달간 Fleet, Kubernetes, Mesos, etcd를 비롯한 수많은 멋진 프로젝트를 탐험할 것입니다. CoreOS 등을 클라우드 프로바이더와 연동하고, 분산 및 병렬 파일시스템을 실험하고, Jenkins나 Ansible 같은 자동화 도구를 다루는 등 용어 나열만으로도 눈이 돌아갈 것 같은 화려한 주제들이 계속됩니다. 기대해 주세요.
그럼, 즐거운 코딩 되세요.