Back to top

Vagrant - kilka słów o.

VAGRANT WILL CHANGE HOW YOU WORK głosi slogan ze strony https://www.vagrantup.com - kto za? Kto przeciw? Ja nie mam zamiaru zaprzeczać, że Vagrant to bardzo fajna idea i choć nasz pierwszy kontakt nie należał do udanych (nie do końca przemawiała do mnie stojąca za tym narzędziem motywacja), to jednak z biegiem czasu było już tylko lepiej. Sam wspomniany powyżej slogan nie jest jednak, moim zdaniem, trafiony. Vagrant nie wprowadza żadnej nowej technologii - standaryzuje tylko wykorzystanie aktualnie już istniejących (wszystko co możesz otrzymać za pomocą Vagranta, możesz uzyskać również bez jego wykorzystania). Ok, temat jest ciekawy - dziś o Vagrancie - zaczynamy!

Na początek trochę danych o samym projekcie, strona projektu została już wspomniana we wstępnie, źródła dostępne są w serwisie Github. Pobierzmy repozytorium (trochę zabawy z gitem - widziałem to w jakiejś książce ostatnio i spodobało mi się):

$ git clone https://github.com/mitchellh/vagrant

Ilość developerów którzy wspomogli projekt:

$ git shortlog -s -n | wc -l
     856

To chyba niezła sumka, jak wygląda pierwsza dziesiątka pod względem commitów:

$ git shortlog -s -n | head
  5976	Mitchell Hashimoto
  1114	Seth Vargo
   202	Chris Roberts
   173	Gilles Cornu
   116	Fabio Rehm
    85	John Bender
    78	Shawn Neal
    68	Teemu Matilainen
    30	Max Lincoln
    26	Matt Wrock

I jeszcze ogólna liczba rewizji na branch-u master:

$ git log --oneline | wc -l
    9394

Czyli Mitchell Hashimoto i Seth Vargo mają prawie 90% udział w projekcie. Teraz jeszcze trochę o megabajtach:

$ du -sh .
 28M	.
$ du -sh .git
 20M	.git

Wielkość źródeł to 8MB (20 MB zajmuje repozytorium Gita) - te dane mogą ogólnie dać nam jakiś pogląd o skali projektu.

Dla porównania - repozytorium VirtualBox-a (mam nadzieję, że to właściwe repozytorium :)) - zwiera około 60 tys. rewizji i około 500 MB danych (po odjęciu wielkości katalogu .git), niestety repozytorium jest importowane i (celowo, bądź po prostu nie dało się inaczej) wszystkie rewizje zostały przypisane do jednego użytkownika... Mimo wszystko skala projektu wydaje się o conajmniej rząd większa.

Książka "Vagrant, Up and Running" autorstwa Mitchella Hashimoto (wydana w 2013 roku) jest z pewnością godną polecenia pozycją opisującą omawiane narzędzie dość dokładnie, choć pierwszych 17 stron, stanowiących wstęp do tematu, było, szczerze mówiąc, dla mnie, dość trudną lekturą. Pełno tu tych górnolotnych stwierdzeń rodem z podręcznika "dobrego sprzedawcy", które czasami... mijają się z prawdą, bądź są jakimiś pobożnymi życzeniami autora, przedstawianymi jak aksjomaty IT. Czasami naprawdę - krew się gotuje. Więc, choć ogólnie książka jest zupełnie ok (szczególnie w części technicznej) to trochę  powalczę w kolejnych akapitach z niektórymi sformułowaniami z pierwszych 17 stron - to taka moja mała misja - troska o "poprawność" :) Istnieje już jedno "niedomówienie" w postaci "Systemu Operacyjnego Linux" (kto wie czym jest GNU?) - po co więcej? Bądźmy czujni! Oczywiście, przy okazji komentowania, mam nadzieję przedstawić trochę bliżej mój sposób postrzegania tego narzędzia. Oto cytaty:

str 2. "Prior to Vagrant, the preferred method of working on a web application was to install and configure all the sorftware you needed (e.g. Apache, MySQL, RabbitMQ, etc.) locally on your development machine." - hmm... nie ma sensu licytować się kto czego wcześniej używał, choć krótko wtrącę tylko, że moje "złe" z Vagrantem początki - wspomniane we wstępie - wynikały właśnie z tego, iż używanie Vagranta (opartego w ówczesnej wersji o VirtualBox-a) było dla mnie niedorzecznością w systemie GNU/Linuksowym, w którym mogłem używać Lxc. Czy jestem wyjątkiem? Czy to rzeczywiście Vagrant wprowadził wirtualizację do developmentu? Można dyskutować :) Po drugie, moim zdaniem, provider typu "localhost" w Vagrancie jest chyba tylko kwestią czasu - o ile już nie ma jakiegoś sposobu na właśnie taką konfigurację (być może, będzie można z niego korzystać tylko w GNU, ale, dlaczego nie?..). Nie lubię patrzeć na Vagranta jako na narzędzie do wirtualizacji - nie do końca pasuje mi to do misji jaką widzę przed tym narzędziem, o czym poniżej.

str 4. "Never again can developers forget to shut down a stray server process and waste precious compute resources." - eee.... środowisko zbudowane przy pomocy Vagranta będzie działać doputy dopóki go ręcznie nie wyłączymy, dlaczego w tym przypadku nie mielibyśmy o tym zapominać (mi osobiście często się to zdarza :)). Ponadto jeżeli używamy zestawu Vagrant + Docker + VirtualBox z obrazem boot2docker (przykładowy opis takiej konfiguracji) - to polecenie "vagrant halt" (i podobne) w ogóle nie wpływa na uruchomioną VirtualBox-ową wirtualkę z obrazem boot2docker - niezależnie od "vagrant halt" trzeba ją wyłączyć ręcznie przez GUI VirtualBox-a - będziecie o tym pamiętać? Dla mnie więc zdanie to (czy raczej - ten argument) kompletnie nie ma sensu.

str5. "VirtualBox is free, but there are also many commercial alternatives (e.g, VMware, Parallels, etc.). Each of these can be used to mimic what Vagrant does." - ... to mimic what Vagrant does... eeee... pogubiłem się ;)

str 6. "If you're working in a team environment, laptops are usually distributed with Vagrant preinstalled (or, if not, it should be one of the first software components to be installed)." - ciekawe :-D

str 6. "No more nightmares setting up Linux services on Windows!" - to chyba jakiś skrót myślowy... chyba zbyt duży... Choć brzmi nieźle... marketingowo.

Ok, to tylko kilka cytatów - zdaję sobie sprawę, że nie wszystkie (żaden!?) będą wydawać się "naciągane" również wam - cóż, życie. Ogólnie Vagrant to, jak pisałem, idea całkiem słuszna i wartościowa (moim zdaniem)! A już zupełnie na koniec tych narzekań - powyższe cytaty czasami kojarzą mi się z sytuacją w której ktoś próbuje wypromować "narzędzie" vl.sh, o "kodzie":

	#!/bin/sh
	ls -lF

próbując przy tym wszystkich przekonać, że ls może co prawda "symulować" działanie vl.sh, jednak vl.sh jest dużo lepsze, bo listuje zwartość katalogów w prosty, szybki i przejrzysty sposób! No, ale to tylko taki mocno przejaskrawiony przykład tego z czym kojarzą mi się czasami cytaty jak powyższe.

Czym więc Vagrant jest? Mi osobiście najbardziej odpowiada definicja następująca:

Vagrant is a tool for creating, managing, and distributing portable development environments.

Czyli Vagrant jest narzędziem do tworzenia, zarządzania i dystrybucji przenośnych środowisk developerskich. Super. Autorem tej definicji jest również Mitchell Hashimoto, można usłyszeć ją z jego ust podczas np. tej prezentacji, na konferencji Joe Dev on Tech w 2012 (czyli przed wydaniem podręcznika, podręcznik w trakcie prezentacji jest zapowiadany, hmmm... dziwne, że nie znalazłem w nim tej definicji).

W powyższej definicji jest wszystko co mi się w Vagrancie podoba i do czego tak naprawdę Vagranta używam - chodzi właśnie o zarządzanie środowiskami deweloperskimi. Moim zdaniem Vagrant nie jest nowym pomysłem na wirtualizację (patrz przejaskrawione wtrącenie o "vl.sh" powyżej), nie można go również porównywać z np. Dockerem. Takie porównania przeważnie dotyczą porównania Dockera z tandemem Vagrant + VirtualBox, ale przecież Vagrant może również (bezpośrednio) współpracować z Dockerem, czyli możliwym jest również tandem Vagrant + Docker (będę o tym pisał więcej, choć chyba już w osobnym artykule) - a to sprawia, że Vagrant to jednak narzędzie zupełnie innego typu niż Docker czy VirtualBox! Oczywiście, Vagrant był w przeszłości związany jedynie z VirtualBox-em i być może część tych porównań pochodzi właśnie z tych "starych" czasów, nie jest więc moją intencją tutaj wytykanie autorom tych porównań ich niezasadności, chciałbym jedynie zaznaczyć, iż Vagrant nie do końca musi być ciągle postrzegany w ten właśnie - "stary" - sposób. Udało mi się ostatnio przygotować środowiska deweloperskie, na OS X, przy wykorzystaniu zarówno VirtualBox-a, jak i natywnej instalacji Dockera (bez użycia boot2docker - hint: opcja force_host_vm)! Tak więc - "to działa"! Vagrant występuje tu wiec jako właśnie "manager", z pomocą którego, wykorzystując te same pliki konfiguracyjne, mogę utworzyć moje developerskie środowisko wykorzystując VirtualBox-a bądź Dockera - i to jest moim zdaniem miejsce / rola Vagranta.

Właśnie na taką niezależność samej ideii "środowiska developerskiego" od konkretnej implementacji (czyli kontenera, bądź maszyny wirtualnej), na przykładzie konfiguracji Vagrant + VirtualBox i Vagrant + Docker, chciałem położyć nacisk w tym artykule. W teorii można przygotować jeden zestaw konfiguracyjny i wybierać tylko czy chcemy działać na VirtualBox-ie, czy Dockerze - super. Niestety, choć takie rozwiązanie wydaje się jak najbardziej możliwe, to jednak jeden artykuł okazuje się zbyt ciasny, aby to opisać bez niebezpiecznych skrótów. Opcji i nuansuów jest zbyt wiele. Docker ma swoją filozofię, trochę różną od podejścia "standardowego", i choć "standardowo" też się da, to jednak nie byłoby chyba dobrze, te różne niuanse przemilczeć. Jak robić - to porządnie! Dlatego artykuły będą dwa - w tym skupię się tylko i wyłącznie na środowisku developerskim utworzonym w oparciu o VirtualBox-a. Docker-a jeszcze muszę trochę potestować i mam nadzieję na początku przyszłego roku dodać drugą część, prezentującą vagrantową wersję tego samego środowiska opartą jednak już na Dockerze.

Czy poza jednolitym interfejsem, za którym może kryć się uruchomienie różnych mechanizmów izolacji naszego środowiska deweloperskiego, Vagrant daje nam coś jeszcze? Okazuje się, że tak - tym "czymś" jest Provisioning System.

Provisioning System to rzecz która bardzo fajnie dopełnia całości. Podobnie jak warstwa współpracy z różnymi mechanizmami izolacji (providers), potrafi współgrać z różnymi "standardami branżowymi" - Chef, Puppet, Ansible, również ze skryptami shellowymi (co wykorzystam w przykładzie) - współpracować w zakresie konfiguracji przygotowywanego środowiska. Provisioning System zamyka nam też listę rzeczy które możemy konfigurować w głównym pliku konfiguracyjnym Vagranta (Vagrantfile) - można rzec, jest to ostatni element układanki. Podsumowując, konfiguracja Vagranta (Vagrantfile) to:

  1. informacje o tym jaki mechanizm izolacji (provider) należy wykorzystać (VirtualBox, Docker,...)
  2. Jak skonfigurować wybranego w punkcie 1 providera - obraz jakiego systemu wykorzystać, jak skonfigurować RAM, CPU, sieć, dyski, itd... (elementy konfiguracji są zależne od rodzaju wybranego providera)
  3. (opcjonalnie) Jak przygotować system do pracy (provisioning system) - jak należy zmodyfikować system bazowy, aby odpowiadał naszym wymaganiom

Przykładowy plik konfiguracyjny, aby go przetestować należy pobrać repozytorium https://github.com/lbacik/tools, wejść do katalogu "vagrant" i wykonać:

$ vagrant up

W wyniku powinniśmy otrzymać środowisko developerskie z przygotowanym do pracy frameworkiem symfony 3. Aby móc wyświetlić stronę testową musimy dodać do naszego pliku "hosts" wpis "192.168.33.30 symfony_demo.local" (Linux, OS X, Win - wszędzie jest plik hosts :)), adres strony testowej to oczywiście: http://symfony_demo.local - przetestowałem to na wszystkich trzech systemach i działa ok, oczywiście pierwsze przygotowanie systemu będzie trochę trwało...

Ostatnia rzecz na którą chciałbym zwrócić w tym artykule uwagę to plik 'vagrant/provision.sh' - w repozytorium możemy znaleźć go w dwóch wersjach:

Wynik wykonania będzie ten sam, różnice wynikają z chęci zapewnienia lepszej idempotentności (ang. idempotent, idempotent - słownik poprawnej polszczyzny). Na termin "idempotent" trafiłem w trakcie lektury podręcznika do Ansible - "Ansible, Up & Running" (przyjdzie i czas na kilka słów i o Ansible), termin "idempotentna komenda" oznacza komendę, która nie zmieni stanu systemu jeżeli już raz była (wcześniej) wykonana - czyli możemy ją wykonywać dowolną ilość razy, a efekt będzie taki sam jakbyśmy wykonali ją tylko raz (mam nadzieję, że to dobrze zrozumiałem). Ogólnie wersja v0.1 przykładowego skryptu nie jest specjalnie wrażliwa na ponowne uruchomienia - apt-get nie będzie instalował po raz kolejny tych samych pakietów, zmiany wykonane za pomocą polecenia sed najwyżej zostaną wykonane ponownie (choć to już niesie ze sobą ryzyko nadpisania zmian użytkownika, ale cóż - na to też znajdzie się rozwiązanie). Jedyny rzeczywisty problem to linia 25 - dopisanie kilku linii do jednego z plików, w przypadku ponownego wykonania skryptu provisionującego te linie będą ponownie dopisane - to niedobrze. Skrypt w wersji v0.2 wprowadza poprawki pod kątem idempotentności zawartych w nim kroków - teraz, jeżeli wykonamy zmianę w szablonie pliku konfiguracyjnego vhosta (dla serwera apache) to możemy po prostu usunąć stary plik konfiguracyjny ze środowiska deweloperskiego i uruchomić ponownie plik provisinujący bez obaw o pozostałe "składowe" systemu - tylko konfiguracja vhosta zostanie wykonana ponownie. Standardowo plik provisionujący uruchamiany jest tylko raz (przy budowaniu środowiska), ale są sytuacje w których możemy chcieć go uruchomić ponownie , dlatego idempotentność to całkiem ważna rzecz.

To tylko ogólne informacje o Vagrancie i związanymi z tym narzędziem zagadnieniami - ogólnie Vagranta polecam uwadze wszystkich, którzy jeszcze nie mieli okazji go wypróbować (dokumentacja na stronie projektu jest dość dobra, w kwestii bardziej zaawansowanych zagadnień - jak pisanie własnych modułów - odsyłam do prezentowanej książki: "Vagrant, Up and Running") - to z pewnością narzędzie warte polecenia, choć niekiedy przedstawiane / prezentowane jest w trochę niezrozumiały dla mnie sposób. Mam nadzieję, że udało mi się przedstawić moje spojrzenie na całą tę sprawę. W razie czego dajcie znać na twitterze (@LukaszBacik) bądź fb!