Go, Vantage point
가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.
Github | https://github.com/overnew/
Blog | https://everenew.tistory.com/
티스토리 뷰
IaC(Infrastructure as Code)를 위해 사용할 수 있는 Vagrant에 대해 정리하고 실습해 보자.
코드형 인프라(Infrastructure as Code, IaC)는 수동 프로세스가 아닌 코드를 통해 인프라를 관리하고 프로비저닝하는 것을 말합니다.
IaC를 사용하면 인프라 사양을 담은 구성 파일이 생성되므로 구성을 편집하고 배포하기가 더 쉬워집니다. 또한 IaC는 매번 동일한 환경을 프로비저닝하도록 보장합니다. IaC는 구성 사양을 코드화하고 문서화함으로써 구성 관리를 지원하며, 따라서 구성 변경 사항을 문서화하지 않고 임시로 변경하는 일을 막을 수 있습니다.
- Red Hat 코드형 인프라(IaC)란? -
Vagrant
Vagrant는 소프트웨어 개발 프로세스를 단순화하고 표준화하는 데 사용되는 도구이다.
가상화 환경 구축
- Vagrant를 사용하면 가상 머신(예: VirtualBox, VMware 등)을 사용하여 개발 환경을 손쉽게 설정할 수 있습니다. 개발자는 가상 머신을 통해 독립된 환경을 만들어 프로젝트를 실행하고 테스트할 수 있습니다.
프로비저닝 및 설정 관리
- Vagrant는 가상 머신을 구성하고 프로비저닝하는 데 사용되는 설정 파일을 제공합니다. 이러한 설정 파일은 개발 환경의 소프트웨어 구성 요소를 정의하고 관리하는 데 사용됩니다. 이를 통해 개발 환경을 쉽게 재현하고 공유할 수 있습니다.
멀티 플랫폼 호환성
- Vagrant는 다양한 호스트 운영 체제(Windows, macOS, Linux)에서 작동하며, 다양한 가상화 플랫폼과 호환됩니다. 이는 개발자들이 자신이 원하는 운영 체제 및 가상화 솔루션을 선택할 수 있음을 의미합니다.
환경 일관성
- Vagrant를 사용하면 프로젝트의 모든 개발자 및 팀원이 동일한 개발 환경을 갖게 됩니다. 이는 버그를 예방하고 협업을 간소화하여 효율성을 높입니다.
스냅샷 및 롤백
- Vagrant는 가상 머신의 스냅샷을 생성하고 관리할 수 있습니다. 이는 개발자가 실험적인 변경 사항을 시도하고 필요한 경우 이전 상태로 롤백할 수 있도록 해줍니다.
Vagrant를 사용하면, 더 이상 각각의 VM에 직접 들어가 세팅 작업을 진행할 필요 없이, 코드를 통해 완전히 동일한 VM 환경을 구축하고 관리할 수 있다.
따라서 docker container처럼 VM도 아끼고 애정을 줄 필요없이, 삭제해 버리고 빠르게 다시 구축해 낼 수 있다.
IaC가 얼마나 효율적인지 직접 사용해 보면서 경험해 보자.
Vagrant 설치 window
아래 링크에서 윈도우 버전 설치.
https://developer.hashicorp.com/vagrant/install
설치 후 재시작을 하고, window cmd에서 vagrant --version으로 설치 확인.
Virtual Box도 미리 설치해 주자.
Vagrant 사용해 보기
Vagrant는 Vagrantfile의 코드를 통해 VM을 생성한다.
Vagrantfile은 루비 언어로 되어있다.
#간단히 Ubuntu VM을 하나 생성하는 Vagrantfile
Vagrant.configure("2") do |config| # "2"는 현재 vagrant 설정 형식 버전 2를 사용한다는 의미
config.vm.box = "ubuntu/focal64" # box 이름(이미지)는 로컬 혹은 vagrant cloud 에서 가져오게됨
config.vm.box_version = "20240223.0.0" # box 이미지의 버전 정보
config.vm.provision "shell", inline: "apt update" # 배포 중 실행
config.vm.provider "virtualbox" do |vb1| # 가상머신의 세부 설정 정보
vb1.memory = "2048"
vb1.cpus = "1"
end
end
이 파일이 존재하는 폴더로 이동하여 vagrant 명령어를 실행하게 된다.
만약 Vagrantfile이 없다면, vagrant init으로 Vagrantfile을 생성할 수 있다.
#vagrant file 실행
vagrant up
이러면 PC에 설치된 Virtual Box에 ubuntu VM을 설치해 실행한 것과 동일한 결과가 된다.
# VM 상태 확인
vagrant status
실행한 폴더 내에 vagrant 설정파일이 생긴다.
Virtual Box에서 확인해 보면, 생성된 VM이 보인다.
# ssh 환경 확인
vagrant ssh-config
SSH는 2222번으로 접속가능
#SSH 접속
vagrant ssh
vagrant file에 설정한 대로 생성이 되었다.
#VM ssh의 private key
생성된 폴더 내에 Private key가 생성되어 있어서, 이것을 활용하면 MobaXterm으로 접속가능 하다.
언제든지 다시 동일하게 생성 가능한 환경이기 때문에 부숴버려도 괜찮다.
vagrant destroy -f
VM2개 동시 배포
# Ubuntu VM 2개 동시 배포
Vagrant.configure("2") do |config|
config.vm.define "frontend" do |frontend|
frontend.vm.box = "ubuntu/focal64"
frontend.vm.box_version = "20240223.0.0"
frontend.vm.host_name = "front"
frontend.vm.provider :virtualbox do |spec|
spec.cpus = 1
spec.memory = 2048
end
end
config.vm.define "backend" do |backend|
backend.vm.box = "ubuntu/focal64"
backend.vm.box_version = "20240223.0.0"
backend.vm.host_name = "backend"
backend.vm.provider :virtualbox do |spec|
spec.cpus = 1
spec.memory = 2048
end
end
end
vagrant up으로 실행시키면, 두 개의 VM이 생성된다.
vagrant ssh-config
이제 한 개 이상이니까 HOST 이름을 넣어서 접속해서 구별하자.
vagrant ssh frontend(HOST 이름)
VM들은 특별한 세팅이 없다면 기본적으로 NAT가 네트워크 인터페이스로 장착되어 있다.
Docker가 설치된 Ubuntu 만들기
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.box_version = "20240223.0.0" #직접 특정 url의 docker 설치 sh 파일을 받아서 실행
config.vm.provision "shell", inline: "curl -fsSL https://get.docker.com -o get-docker.sh"
config.vm.provision "shell", inline: "sh get-docker.sh"
config.vm.provision "shell", inline: "usermod -aG docker vagrant" #vagrant라는 유저 만들어서 추가
config.vm.provision "shell", inline: "echo 'sudo su -' >> .bashrc"
config.vm.provider "virtualbox" do |vb1|
vb1.memory = "4096"
vb1.cpus = "2"
end
end
vagrant up으로 실행시키면 도커의 설치가 진행된다.
VM 상태 확인
이제 코드로 작성된 VM은 언제든지 새로 만들 수 있다.
따라서 기존의 VM이 정상적으로 동작하지 않으면, VM을 새로 올리면 되는데
이때 모니터링으로 사용하는 지표가 아래의 file들에서 확인된다.
# cpu의 상태 확인
cat /proc/cpuinfo | grep “core”
# 메모리 상태 확인
cat /proc/meminfo | grep “Mem”
포트 포워딩으로 Apache 웹서버 띄우기
Apache 서버 설치 후, VM을 통해 접근되도록 8080번 포트와 VM의 80번을 연결하는 코드를 작성.
#vagrantfile(portforwording)
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.box_version = "20240223.0.0"
config.vm.network "forwarded_port", guest: 80, host: 8080 # 포트포워딩
config.vm.provision "shell", inline: "apt update && apt install -y apache2 && systemctl enable apache2"
config.vm.provision "shell", inline: "echo BABO WebServer > /var/www/html/index.html" #간단한 html 생성
config.vm.provider "virtualbox" do |vb1|
vb1.memory = "2048"
vb1.cpus = "1"
end
end
실행하면 이런 창이 뜰 수도 있다.
생성된 VM의 NAT에 설정한 포트포워딩 규칙이 자동으로 들어가 있는 것을 확인할 수 있다.
새로운 랜카드 생성하기
private_network ip: "192.168.33.10를 통해 192.168.33.0/24 대역의 랜카드가 새로 생긴다.
#Private_Network
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.box_version = "20240223.0.0"
config.vm.network "private_network", ip: "192.168.33.10" #새로운 lan 카드 생성
config.vm.provision "shell", inline: "apt update && apt install -y apache2 && systemctl enable apache2"
config.vm.provision "shell", inline: "echo BABO2 WebServer > /var/www/html/index.html"
config.vm.provider "virtualbox" do |vb1|
vb1.memory = "2048"
vb1.cpus = "1"
end
end
Vagrant로 VM 하나에 Apache2와 Nginx 띄우기
두 개의 웹서버가 하나의 VM에서 동작해야 하므로 아파치는 8081 포트에서 동작하도록 바꾸어주자.
Apache2 기본 포트 변경 방법
/etc/apache2/sites-available/000-default.conf에서 80을 8081로 변경
/etc/apache2/ports.conf의 listen도 80에서 변경
이후 재시작하면 기본 port가 8081로 변경된다.
Sed command 활용
Vagrantfile을 이용하면, 우리는 편집기에 들어가 직접 파일을 수정하지 않고 command로만 주어야 한다.
이를 위해 사용하는 command가 sed이다.
Sed를 통해 설정 파일의 특정 문자열을 모두 다른 문자열로 치환시킬 수 있다.
sed -i 's/<대상 문자열>/<치환 문자열>/g' <대상 파일>
실행 결과
VM하나에 3개의 container 띄우기
여기서 3개의 컨테이너는 아래와 같다.
1. Bastion host (ubuntu os)
2. Apache webserver
3. Nginx webserver
각각을 Vagrant를 통해 shell command로 만들어 주기보다는 docker file을 사용하는 것을 선택했다.
미리 각각의 image의 dockerfile을 작성해 두고, vm에 옮긴 후 build시켜 실행한다.
dockerfile 작성 -> dockerfile 을 VM으로 이동 -> docker image build -> image run
이를 위해서 작업 중인 PC의 도커 파일을 vagrant로 만들어진 VM으로 이동시켜야 한다.
이때 사용하는 것이 Vagrant의 synced_folder이다.
Vagrant의 synced_folder
Vagrant의 `synced_folder`는 로컬 시스템과 가상 머신 간의 파일 및 디렉터리를 동기화하는 데 사용된다. 이는 로컬 시스템의 특정 디렉토리를 가상 머신 내의 특정 위치로 연결하여 변경 사항을 실시간으로 반영할 수 있게 해 준다. 이것은 마치 가상 머신 내부의 디렉터리가 로컬 시스템의 일부인 것처럼 작동한다. 따라서 파일을 수정하거나 추가하면 이 변경 사항이 가상 머신과 로컬 시스템 간에 자동으로 동기화된다.
config.vm.synced_folder "로컬 시스템 폴더 경로(상대 경로)", "VM의 절대 경로"
config.vm.synced_folder ".", "/dockerfiles" #현재 폴더를 vm의 /dockerfiles와 연동해서 사용
여기서 로컬 시스템 폴더 경로는 Vagrantfile이 존재하는 곳에서 부터의 상대경로 잡아주자.
폴더 구조
각각의 VM별로 폴더와 dockerfile을 만들어 준다.
Dockerfile 코드
apache
FROM httpd:latest
COPY index.html /usr/local/apache2/htdocs/index.html #apache index경로로
COPY image.png /usr/local/apache2/htdocs/image.png #이미지와 index 옮기기
Nginx
FROM nginx:latest
COPY index.html /usr/share/nginx/html/index.html #nginx index경로로
COPY image.png /usr/share/nginx/html/image.png
ENTRYPOINT ["nginx", "-g", "daemon off;"]
Bastion
FROM ubuntu:latest
EXPOSE 22/tcp #22번 포트 개방
CMD tail -f /dev/null
# 자동 종료 방지를 위해 특정 파일을 계속 읽어오게 만듬.
Vagrantfile
결과
vagrant ssh 로 접속해 보면 3개의 container가 포트 맵핑되어 동작 중이다.
각각의 web server로도 다른 포트로 접근할 수 있다.
또한 같은 docker의 bridge이기 때문에 서로 간의 통신이 가능하다.