(자료화면은 vagrantfile을 sublime Text3에서 작성하던 화면~)
하하하 테스트 정말 오래 걸리네요
이게 테스트를 하려면 한번 쳐다보고 10분 지나고 이런 경우가 꽤 있다 보니...
설치를 하고 실행하는 것은 데모 동영상으로 진행할까 합니다.
요약
vagrantfile이 ini파일 처럼 구성할 파일들을 code로 정의해 놓으면, 해당 구성 정보에 맞게 vagrant가 virtualbox(또는 Hyper-V, Docker, VMware, AWS, KVM등) 아주 다양하게 올려줍니다.
즉, 지속적으로 사용해야 하는 환경을 반복 구성하는데 최적화 되어 있습니다.
또는 템플릿 형식처럼, 배포하는 것에도 쓰여질수가 있겠죠? UI만 잘 입히면요. :)
위키 참조 : https://en.wikipedia.org/wiki/Vagrant_(software)
설치 및 실행
1. virtualbox 설치
oracle Virtual Box (https://www.virtualbox.org/) 에서 적합한 윈도우 버전을 다운받습니다.2. vagrant 설치
https://www.vagrantup.com/ 에서 Download를 눌러서 파일을 다운 받고 실행한다. 그리고 설치를 다 마치고 나면, 정상적으로 설치되었는지 확인을 위해 'cmd'를 실행하고 버전을 확인해 보자.C:\Users\pagai>vagrant --version
Vagrant 1.9.5
3. 설치할 OS 다운로드
기본적으로 계속 사용할 OS들이 vagrant에 잘 패키지 되어 있는데, 이는 다운로드 해서 사용한다.현재 다운로드 되어 쓸수 있는 것들은 'vagrant box list' 명령어로 확인가능하다.
(이미 꽤 반복 작업을 해서 여러개 나오는겁니다..보통은 없습니당)
C:\Users\pagai>vagrant box list
16.04 (virtualbox, 0)
16.04_docker (virtualbox, 0)
centos/7 (virtualbox, 1705.02)
precise32 (virtualbox, 0)
ubuntu/trusty64 (virtualbox, 20170619.0.0)
우리는 우분투 이미지와 센트를 쓸겁니다.
센트는 Ansible-server용으로
우분투는 Ansible-Node용으로 사용할 것입니다.
이미지 다운로드는 신기하게 명령어가 'add'를 씁니다. 그래서 명령어가 다음과 같습니다.
vagrant box add <다운받을 이미지 이름 or 경로>
그리고 이미지 찾기는 여기서 가능합니다.
https://app.vagrantup.com/boxes/search
남들이 많이 쓰는게 좋다는 지론때문입니다.
중간에 사람 얼굴이 있는데..제작자인가? 싶은데... 외국인은 대머리도 멋있네요.
vagrant 대신에 homestead를 쓰는 경우도 종종 있더라고요 나중에 시간이 되면 두개를 비교해 볼 필요도 있을 것 같습니다아~!
4. 설치후 vagrantfile 구성
이미지가 준비되었다면, vagrant init --force(만약에 기존에 만든게 있어서 오류가 난다면)
을 실행해 어떻게 설치할지 결정하는 초기 파일을 만들수 있지만, 어짜피 제시하는 코드(내가 만든 코드) 를 가지고 할 것이기때문에 초기화 할 필요는 없다.
그래도 궁금하다면, 파일이름도 있고 하니...vagrant init --force를 실행하고 현재의 경로에 vagrantfile이 생성된 것을 확인하자.
이제 부터 나올 것들은 코드인데.. vagrant는 기본적으로 'ruby'라는 언어로 되어 있다. 하지만~! 하지만~! 별로 쫄것이 없는게..복잡한 것은 안 쓴다.
그냥 python에 비하면, do가 쓰여지면, 아래에 들여쓰기가 생겨야 하고(하위 메뉴처럼) end로 마감되어야 한다. 오류를 보면 쉽게 알수 있는 내용이다.
5. 실행
'vagrant up'을 실행하기 전에 vagrantfile을 아래의 내용에서 카피해서 생성해야 하고, 같은 디렉터리에 Bootstrap.sh, Ansible_env_ready.yml 도 생성해 두어야 한다.그리고 중요한거 하나 'vagrant plugin install vagrant-vbguest를 실행해야만 Host에 있는 디렉토리와 sync할때 에러가 나지 않는다.
실행 데모는 다음과 같다.
6. 코드 설명
하나하나 더 설명할수는 없지만, Ansible-Server를 한번 설명하면 나머지는 쉽게 알수 있으리라고 생각한다. 이 글을 보시는 분들은 분명히 대단하신 분들일꺼다 :)[ 앤서블 서버 ]
config.vm.define:"ansible-server" do |cfg|
cfg.vm.box= "centos/7" # VM을 만들고자 하는 운영체제를 선택
cfg.vm.provider:virtualbox do |vb| # VM에 직접적인 그러니까 버추얼박스에 설정을 진행
vb.name= "HoonJo-Ansible-Server"
vb.customize ["modifyvm", :id, "--cpus", 2]
vb.customize ["modifyvm", :id, "--memory", 2048]
end
cfg.vm.host_name="ansible-server" # 실제 VM에 호스트이름 linux에서 hostname 치면 나오는 것
# 호스트와 VM간에 파일 교환을 위한 건데, 기본 설정이 rsync로 되어 있어서 windows의 경우 변경을 안해주면 오류가 남
cfg.vm.synced_folder ".", "/vagrant", type: "virtualbox"
# eth0은 내부 NAT로 고정되어 있고, eth1번을 인터넷과 연결하도록 public으로 설정
cfg.vm.network "public_network", ip: "172.30.1.10"
# 개별 네트워크들의 기본 fowarded_port는 guest 22, host: 2222인데 중복되면 에러가 발생함
# 이것의 목적은 vagrant ssh <hostname>을 했을때 경로를 포워딩 해줌
cfg.vm.network "forwarded_port", guest: 22, host: 30110, auto_correct: false, id: "ssh"
# centos7/rhel7은 default route를 설정하는 명령어가 좀 다름...-_-;
cfg.vm.provision "shell",
inline: "ip route replace default via 172.30.1.254 dev eth1"
#앤서블 자체를 설치하고 hosts 이름들을 설정함
cfg.vm.provision "shell",
path: "bootstrap.sh"
#윈도에서는 앤서블이 지원하지 않기 때문에 직접 실행을 할수가 없어서 카피한 다음에 셸로 실행함
cfg.vm.provision "file", source: "Ansible_env_ready.yml", destination: "Ansible_env_ready.yml"
#앤서블 개발환경을 위한 앤서블 플래이북 파일임 (기존에 설명함)
cfg.vm.provision "shell",
inline: "ansible-playbook Ansible_env_ready.yml"
end
7. 실제 코드
[ vagrantfile ]
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
# Ansible 테스트 서버
config.vm.define:"ansible-server" do |cfg|
cfg.vm.box= "centos/7"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Server"
vb.customize ["modifyvm", :id, "--cpus", 2]
vb.customize ["modifyvm", :id, "--memory", 2048]
end
cfg.vm.host_name="ansible-server"
cfg.vm.synced_folder ".", "/vagrant", type: "virtualbox"
cfg.vm.network "public_network", ip: "172.30.1.10"
cfg.vm.network "forwarded_port", guest: 22, host: 30110, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
inline: "ip route replace default via 172.30.1.254 dev eth1"
cfg.vm.provision "shell",
path: "bootstrap.sh"
cfg.vm.provision "file", source: "Ansible_env_ready.yml", destination: "Ansible_env_ready.yml"
cfg.vm.provision "shell",
inline: "ansible-playbook Ansible_env_ready.yml"
end
# Ansible 테스트 노드 1번
config.vm.define:"ansible-node01" do |cfg|
cfg.vm.box= "ubuntu/trusty64"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Node01"
vb.customize ["modifyvm", :id, "--cpus", 1]
vb.customize ["modifyvm", :id, "--memory", 1024]
end
cfg.vm.host_name="ansible-node01"
cfg.vm.synced_folder ".", "/vagrant", disabled: true
cfg.vm.network "public_network", ip: "172.30.1.11"
cfg.vm.network "forwarded_port", guest: 22, host: 30111, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
run: "always",
inline: "route add default gw 172.30.1.254"
cfg.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
# Ansible 테스트 노드 2번
config.vm.define:"ansible-node02" do |cfg|
cfg.vm.box= "ubuntu/trusty64"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Node02"
vb.customize ["modifyvm", :id, "--cpus", 1]
vb.customize ["modifyvm", :id, "--memory", 1024]
end
cfg.vm.host_name="ansible-node02"
cfg.vm.synced_folder ".", "/vagrant", disabled: true
cfg.vm.network "public_network", ip: "172.30.1.12"
cfg.vm.network "forwarded_port", guest: 22, host: 30112, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
run: "always",
inline: "route add default gw 172.30.1.254"
cfg.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
# Ansible 테스트 노드 3번
config.vm.define:"ansible-node03" do |cfg|
cfg.vm.box= "ubuntu/trusty64"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Node03"
vb.customize ["modifyvm", :id, "--cpus", 1]
vb.customize ["modifyvm", :id, "--memory", 1024]
end
cfg.vm.host_name="ansible-node03"
cfg.vm.synced_folder ".", "/vagrant", disabled: true
cfg.vm.network "public_network", ip: "172.30.1.13"
cfg.vm.network "forwarded_port", guest: 22, host: 30113, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
run: "always",
inline: "route add default gw 172.30.1.254"
cfg.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
# Ansible 테스트 노드 4번
config.vm.define:"ansible-node04" do |cfg|
cfg.vm.box= "ubuntu/trusty64"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Node04"
vb.customize ["modifyvm", :id, "--cpus", 1]
vb.customize ["modifyvm", :id, "--memory", 1024]
end
cfg.vm.host_name="ansible-node04"
cfg.vm.synced_folder ".", "/vagrant", disabled: true
cfg.vm.network "public_network", ip: "172.30.1.14"
cfg.vm.network "forwarded_port", guest: 22, host: 30114, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
run: "always",
inline: "route add default gw 172.30.1.254"
cfg.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
# Ansible 테스트 노드 5번
config.vm.define:"ansible-node05" do |cfg|
cfg.vm.box= "ubuntu/trusty64"
cfg.vm.provider:virtualbox do |vb|
vb.name= "HoonJo-Ansible-Node05"
vb.customize ["modifyvm", :id, "--cpus", 1]
vb.customize ["modifyvm", :id, "--memory", 1024]
end
cfg.vm.host_name="ansible-node05"
cfg.vm.synced_folder ".", "/vagrant", disabled: true
cfg.vm.network "public_network", ip: "172.30.1.15"
cfg.vm.network "forwarded_port", guest: 22, host: 30115, auto_correct: false, id: "ssh"
cfg.vm.provision "shell",
run: "always",
inline: "route add default gw 172.30.1.254"
cfg.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
end
[ Bootstrap.sh ]
#!/usr/bin/env bash
yum install epel-release -y
yum install ansible -y
#hosts file
echo "172.30.1.11 node01" >> /etc/hosts
echo "172.30.1.12 node02" >> /etc/hosts
echo "172.30.1.13 node03" >> /etc/hosts
echo "172.30.1.14 node04" >> /etc/hosts
echo "172.30.1.15 node05" >> /etc/hosts
#ansible hosts file
echo "[Nodes]" >> /etc/ansible/hosts
echo "node01" >> /etc/ansible/hosts
echo "node02" >> /etc/ansible/hosts
echo "node03" >> /etc/ansible/hosts
echo "node04" >> /etc/ansible/hosts
echo "node05" >> /etc/ansible/hosts
#환경설정 초기 파일 구성 for vagrant ONLY
mkdir /home/vagrant/.vim
touch /home/vagrant/.vimrc
touch /home/vagrant/.bashrc
[ Ansible_env_ready.yml ]
---
- name: Ansible_vim
hosts: localhost
remote_user: vagrant
gather_facts: no
tasks:
- name: Install vim-enhanced
yum:
name: vim-enhanced
state: present
- name: Download ansible-vim
shell: "curl -fLo /home/vagrant/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
- name: configure vimrc
lineinfile:
dest: /home/vagrant/.vimrc
line: "{{ item }}"
with_items:
- "set autoindent"
- "set cindent"
- "set number"
- "set smartcase"
- "set smarttab"
- "call plug#begin('~/.vim/plugged')"
- "Plug 'pearofducks/ansible-vim'"
- "call plug#end()"
- name: configure bashrc
lineinfile:
dest: /home/vagrant/.bashrc
line: "{{ item }}"
with_items:
- "alias vi='vim'"
- "alias ans='ansible'"
- "alias anp='ansible-playbook'"
- name: install vim-Plugin
shell: "vim -E -c 'PlugInstall' -c 'source /home/vagrant/.vimrc' -c 'qa' || true"
ignore_errors: yes
- name: Change .vim permission
shell: chown -R vagrant:vagrant /home/vagrant/.vim
- name: bash reload
shell: "source /home/vagrant/.bashrc"
수정 (2017.07.03)
- vagrant user에 맞게 경로를 좀 더 세밀하게 수정하였습니다.
추가 정보 :
윈도우 환경에서는 ssh가 기본적으로 제공되지 않기 때문에 vagrant ssh가 실행되지 못함따라서 저는 git에서 사용하고 있는 ssh를 환경변수/시스템 에 포함시켜주었음
putty를 선호한다면 다음을 참고하세여~(저는 해야 할게 많아서 안함)
https://github.com/nickryand/vagrant-multi-putty
힌트 & 팁 :
1. 개발할때?그리고 이런 개발을 하다보면, 자주 반복적으로 vagrant halt, vagrant destroy -f, vagrant up 세단계를 계속 써야 하는데. 이를 배치파일을 만들어서 돌리면 편하다.
[ vag_reconf.bat ]
@echo off
setlocal
set /p name=어느 vagrant를 재 구성 및 시작하시겠습니까? 모두는 그냥 enter를 입력 하세요: || set name=default
if %name%==default (
vagrant halt && vagrant destroy -f && vagrant up
) else (
vagrant halt %name% && vagrant destroy %name% -f && vagrant up %name%
)
변경(2017.07.03) :
모두 껐다 키는 것은 효율적이지 않고, 필요한 부분만 조율 가능하도록 변경했습니다.
수정 후에 앤서블 서버가 동작하는 영상은 다음과 같습니다.
2. 윈도우에서 앤서블을 쓰고 싶지 않나요?
cygwin을 이용해서 가능하도록 만들어 주는 방법입니다.
하지만 꼭 이렇게까지 써야할지는 물음표~
참고 사이트:
vagrant의 바이블https://www.vagrantup.com/docs/index.html
참고할만한 정보들이 있음 (bridge network 참조)
https://friendsofvagrant.github.io/v1/docs/bridged_networking.html
init --force 옵션
https://stackoverflow.com/questions/23325109/vagrant-errorvagrantfile-already-exists-in-this-directory/23326656
default-gateway 제거
https://superuser.com/questions/752954/need-to-do-bridged-adapter-only-in-vagrant-no-nat
rsync 이슈
https://stackoverflow.com/questions/34176041/vagrant-with-virtualbox-on-windows10-rsync-could-not-be-found-on-your-path
에러를 찾아볼 소스 파일 (vagrant.git)
https://searchcode.com/codesearch/view/71587663/
vagrant configuration file 참조
http://perfspy.blogspot.kr/2016/02/one-thing-to-rule-them-all-ansible-on.html
http://www.barrymorrison.com/2015/Apr/10/vagrant-ansible-or-how-to-make-your-life-better-as-a-developer/
리눅스처럼 윈도우에서 실행 시간 알고 싶을때
https://blog.update.sh/archives/209
vagrant plugin uninstall
https://stackoverflow.com/questions/30336351/does-vagrant-destroy-also-remove-vagrant-plugins
만약에 플래이북을 직접 실행이 가능한 리눅스 환경이라면?
https://stackoverflow.com/questions/20952689/ansible-ssh-forwarding-doesnt-seem-to-work-with-vagrant
전반적으로 vagrant와 ansible을 잘 설명해 놓은 곳
https://adamcod.es/2014/09/23/vagrant-ansible-quickstart-tutorial.html
ssh-keygen을 편하게 ansible로
https://coderwall.com/p/_ryxma/generate-ssh-keys-with-ansible