Vagrantfile
jest czytelna i można nią
zarządzać tak jak głównym kodem projektuVagrantfile
gwarantuje, że użytkownicy
różnych systemów operacyjnych zbudują takie samo środowiskoVagrantfile
można wykorzystać zarówno do
szybkiego stworzenia lokalnych instancji do testów, jak i do tworzenia
instancji u różnych dostawców w chmurzeZainstaluj Vagrant i VirtualBox
Wykonaj:
$ vagrant init archlinux/archlinux
Zapoznaj się z wygenerowanym plikiem
Vagrantfile
Wykonaj:
$ vagrant up
Kiedy zbuduje się maszyna wirtualna, podłącz się do niej przez SSH i sprawdź nazwę dystrybucji:
$ vagrant ssh
[vagrant@archlinux] $ cat /etc/os-release
Domyślnie w maszynie wirtualnej pod ścieżką /vagrant
znajdziesz podmontowany lokalny katalog:
[vagrant@archlinux] $ ls /vagrant
[vagrant@archlinux] $ date > /vagrant/test.txt
[vagrant@archlinux] $ logout
$ cat test.txt
W Vagrantfile
można skonfigurować również
podmontowanie innych ścieżek albo kopiować pliki bezpośrednio:
$ vagrant upload /path/to/local/file /path/in/virtual/machine
Wirtualną maszynę można zniszczyć komendą:
$ vagrant destroy
Listę dostępnych obrazów można znaleźć tutaj: https://app.vagrantup.com/boxes/search
Po stworzeniu maszyny wirtualnej można połączyć się przez SSH i przygotować całe środowisko ręcznie (np. zainstalować Apache)
Jednak takie podejście jest nieskalowalne, podatne na błędy i niezgodne z ideą infrastruktury jako kodu
Vagrant umożliwia tzw. provisioning, czyli przygotowanie środowiska zgodnie z wymaganiami użytkownika
Najbardziej podstawowy mechanizm provisioning to uruchomienie zadanego skryptu powłoki
Przygotuj skrypt o nazwie provision.sh
:
#! /bin/sh
sudo pacman -Sy --noconfirm apache
sudo systemctl enable --now httpd
echo '<h1>Hello World from Vagrant!</h1>' > /srv/http/index.html
Uwaga! Skrypt będzie uruchomiony w sposób nieinteraktywny, więc
musisz dodać przełączniki -y
(do apt-get
w
Debian/Ubuntu) lub --noconfirm
(do pacman
w
Arch), itp.
Dodaj do Vagrantfile
linie:
.vm.provision :shell, :path => "provision.sh"
config.vm.network :forwarded_port, :guest => 80, :host => 8080, :host_ip => "127.0.0.1" config
Jeżeli zniszczyłeś maszynę przy pomocy
vagrant destroy
, to jej nowe utworzenie zastosuje
wprowadzone zmiany
Jeżeli natomiast maszyna wirtualna jeszcze istnieje, to można wymusić zastosowanie reguł provision przy pomocy:
$ vagrant provision
Lub:
$ vagrant reload --provision
(w tym przypadku skorzystaj vagrant reload --provision
,
bo linia config.vm.network ...
wymaga restartu
maszyny)
Sprawdź czy działa przekierowanie portów:
$ vagrant port
Sprawdź wynik w przeglądarce http://localhost:8080
Domyślnie skrypt wykona się tylko podczas tworzenia maszyny
wirtualnej lub podczas uruchomienia procesu bezpośrednio przez
vagrant reload --provision
lub
vagrant provision
Aby to zmienić, można w Vagrantfile
przy
config.vm.provision
dodać opcję
run: "always"
W pliku Vagrantfile
może znajdować się wiele wpisów
config.vm.provision
- kolejność ich uruchamiania będzie
odpowiadać kolejności występowania w pliku
file
shell
Vagrant wspiera wiele innych
mechanizmów provisioningufile
z parametrami
source
i destination
, który pozwala kopiować
pliki lub katalogifile
tworzy niezależne kopie plikówfile
działa na prawach zwykłego użytkownika
(np. vagrant
), więc jeśli chcemy umieścić plik w
lokalizacji systemowej potrzebne będzie połączenie mechanizmu
file
z shell
aby przenieść i zmienić prawa
dostępu do plikówansible
Ansible to kompleksowe rozwiązanie do automatycznej konfiguracji i zarządzania maszynami wirtualnymi (lokalnie lub w chmurze)
Ansible opiera się na deklaratywnym opisie pożądanego stanu systemu
Wykorzystywany w tym celu jest zwięzły format YAML
Sposób działania:
Jest to bardzo ogólny schemat działania:
Przykładowo, pożądanym stanem może być:
istnieje plik /tmp/file
plik /tmp/file ma zawartość: Hello World from Ansible!
plik /tmp/file ma prawa dostępu 0644
Albo:
w systemie zainstalowany jest apache2
usługa httpd jest uruchomiona
Deklaratywny charakter sprawia, że reguły Ansible można stosować wielokrotnie
Kolejne uruchomienia sprawdzą czy pożądany stan zachodzi i mogą zakończyć się sukcesem bez wykonywania żadnej operacji
Większość modułów Ansible ma tę cechę, ale nie wszystkie
Przykładowo moduł script
ma parametry
creates
i removes
, które określają, że
określony plik ma istnieć lub nie. Można jednak użyć modułu
script
by bezwarunkowo wykonać skrypt
Vagrant pozwala uruchamiać Ansible na dwa sposoby:
type: "ansible"
type: "ansible_local"
Jeżeli w swoim głównym systemie operacyjnym możesz zainstalować Ansible, zalecany jest pierwszy sposób
Plik zawierający konfigurację Ansible nazywa
się playbook
playbook
składa się z listy zadań, które uruchamiane
są kolejno od góry do dołu
Każde zadanie może mieć pole name: ...
służące do
dokumentacji
Każde zadanie określa również moduł oraz jego konfigurację
Stwórz plik playbook.yml
:
- hosts: all
become: yes
tasks:
- name: apache is installed
community.general.pacman:
name: apache
state: present
update_cache: yes
- name: httpd service is enabled
ansible.builtin.service:
name: httpd
state: started
- name: hello world content is ready
ansible.builtin.lineinfile:
path: /srv/http/index.html
create: yes
line: <h1>Hello World from Vagrant with Ansible!</h1>
W Ansible możemy grupować zarządzane maszyny i definiować zadania
na poziomie grup, ale w przypadku pracy z Vagrant, wystarczy
hosts: all
Vagrant uruchamia Ansible provisioning na poziomie
zwykłego użytkownika, więc musimy wskazać, że potrzebna jest eskalacja
uprawnień poprzez become: yes
(można to ustawić na poziomie
pliku Vagrantfile
lub na poziomie każdego z zadań z
osobna)
Wykorzystane zostały tutaj trzy moduły:
Zmień konfigurację Vagrantfile
:
- config.vm.provision :shell, :path => "provision.sh"
+ config.vm.provision :ansible, :playbook => "playbook.yml"
Usuń wirtualną maszynę (vagrant destroy
) i stwórz
nową od początku(vagrant up
)
Sprawdź wynik w przeglądarce http://localhost:8080
Możesz ponownie uruchamiać vagrant provision
i
zauważyć, ze zadania Ansible będą w stanie ok
zamiast
changed
W Vagrantfile
można umieścić konfigurację więcej niż
jednej maszyny wykorzystując config.vm.define
np. tak:
.vm.define "web" do |web|
config.vm.box = "..."
webend
.vm.define "db" do |db|
config.vm.box = "..."
dbend
W przykładzie powyżej, wewnątrz bloku można umieścić dokładnie takie same konfiguracje jak wcześniej np. dotyczące otwartych portów czy provisioningu
Jeżeli mechanizm ten jest wykorzystywany, komendy
vagrant
zmieniają nieznacznie działanie:
vagrant up
zbuduje i uruchomi wszystkie maszynyvagrant ssh
wymaga dodatkowego parametru będącego nazwą
maszynyW przypadku takiej konfiguracji, dla zachowania bezpieczeństwa warto umieścić wirtualne maszyny w lokalnej sieci prywatnej i przekierowywać tylko wybrane porty do maszyny gospodarza
Najczęściej przypisuje się maszynom statyczne adresy IP i w
ramach provisioningu konfiguruje się mapowanie w pliku
hosts
, np.:
.vm.network :private_network, :ip => '192.168.20.21'
node1.vm.provision :shell, :inline => <<-SHELL
node1 sed -i '$ a 192.168.20.21 node1' /etc/hosts
sed -i '$ a 192.168.20.22 node2' /etc/hosts
SHELL
(analogicznie dla node2
)
shell
do
provisioninguansible
do
provisioningudb
,
backend
, frontend
). Jedynie
frontend
powinien przekierować port, a reszta komunikacji
powinna odbywać się w ramach sieci prywatnej. Zawartość każdej z maszyn
powinna powstać przy pomocy Ansible