Maszyny wirtualne – jak zautomatyzować ich użycie?
Nie ma jednego idealnego rozwiązania w dyskusji „kontenery kontra maszyny wirtualne”. Wirtualizacja za pomocą kontenerów będzie charakteryzować się „lekkością”, czyli mniejszym zużyciem zasobów i szybszym uruchamianiem. Jednak mimo tych zalet, kontenery nie zawsze będą lepszym wyborem niż maszyny wirtualne, szczególnie jeśli „wirtualka” jest odpowiednio zautomatyzowana. Dlatego warto poświęcić chwilę, aby dowiedzieć się więcej na temat tego jak zarządzać maszyną wirtualną i optymalizować jej działanie.
Anna Rzemińska. Młodszy inżynier systemowy w Comarch. Studentka Teleinformatyki na AGH w Krakowie. Swoją przygodę z światem DevOps rozpoczynała dzięki wakacyjnemu stażowi w Comarch w 2020. Obecnie kontynuuje pracę jako młodszy inżynier systemowy. Zafascynowana automatyzacją i kulturą DevOps, aktualnie skupia się na budowaniu doświadczenia oraz poznawaniu tajników kolejnych technologii.
Spis treści
Kontenery vs maszyny wirtualne. Czy na pewno?
Nie da się zaprzeczyć, że kontenery mają liczne zalety, o czym chyba najlepiej świadczy ich popularność. Mniejsze zapotrzebowanie na pamięć i krótki czas restartu w porównaniu do maszyn wirtualnych są niejednokrotnie czynnikami decydującymi o użyciu kontenerów w środowiskach produkcyjnych, gdzie istotna jest niezawodność i koszty utrzymania. Zupełnie inne priorytety mają jednak osoby poznające nową technologię czy po prostu chcące poeksperymentować.
Do tych zastosowań często znacznie bardziej istotna jest izolacja od komputera hosta, czy dostęp do pełnych zasobów emulowanego systemu operacyjnego (np. interfejsów sieciowych). W tych obszarach to właśnie maszyny wirtualne mają więcej do zaoferowania. Stąd też wynika moje spostrzeżenie – warto zaprzyjaźnić się z nimi, a w tym celu należy poznać Vagranta.
Automatyzacja maszyny wirtualnej czyli jak robić mniej i osiągnąć tyle samo
Czym zatem jest Vagrant?
Vagrant, to narzędzie pozwalające na przechowywanie całości konfiguracji maszyny w plikach tekstowych, a także zarządzanie maszynami wirtualnymi z linii komend. Dzięki temu praktycznie w całości. Dzięki temu praktycznie w całości eliminuje konieczność mozolnego „wyklikiwania” konfiguracji, a także ułatwia współdzielenie maszyn, zastępując pliki obrazów o znacznych rozmiarach niewielkim plikami tekstowymi.
Przejdźmy zatem do konkretów i przyjrzyjmy się, jak wygląda instalacja Vagranta. Omówię również jego wybrane funkcjonalności i kilka tricków ułatwiających pracę z programem. Sam Vagrant jest tylko „nakładką” na oprogramowanie wirtualizujące, więc do działania potrzebuje hiperwizora (w terminologii Vagranta nazywanego providerem) takiego jak VirtualBox, Hyper-V, Docker czy VMware, przy czym ten ostatni nie jest domyślnie wspierany i wymaga doinstalowania odpowiedniej wtyczki. Natomiast instalacja samego Vagranta jest możliwa zarówno przez pobranie dostępnych na stronie instalatorów, ze źródeł, jak i przy pomocy managera pakietów – w przypadku Windowsa polecam Chocolately: choco install vagrant
.
Konfiguracja maszyny wirtualnej z wykorzystaniem narzędzia Vagrant
Jak wspomniałam, konfiguracja maszyny wirtualnej przechowywana jest w postaci pliku nazywanego Vagrantfile
. Aby poznać jego strukturę i podstawowe możliwości, sugeruję wygenerowanie przykładowego Vagrantfile poleceniem vagrant init
, wydanym z linii komend z poziomu folderu, w którym chcemy, by został utworzony. Plik zawiera liczne komentarze, które pozwalają na szybkie rozpoczęcia korzystania z narzędzia. Aby móc uruchomić maszynę, wystarczy sprecyzować obraz (podobnie jak przy tradycyjnej konfiguracji maszyn wirtualnych), nazywany box
, na przykład wybierając spośród dostępnych na Vagrant Cloud.
Warto dodać, że obrazy można przygotowywać samodzielnie, co będzie przydatne w sytuacji, gdy wielokrotnie wykorzystujemy specyficzną konfigurację. Można też określić obraz od razu podczas inicjalizacji, podając jego nazwę na końcu polecenia vagrant init
. Kiedy mamy już gotowy Vagrantfile, wystarczy wydać polecenie vagrant up
, aby uruchomić maszynę (z poziomu katalogu, w którym znajduje się Vagrantfile, przy czym należy pamiętać, że w nazwie pliku rozróżniana jest wielkość liter i rozszerzenie). Domyślnie maszyny uruchamiane są bez interfejsu graficznego i dostęp do nich możliwy jest po ssh przez polecenie vagrant ssh <nazwa maszyny>
.
Do zatrzymywania, wyłączenia i usuwania maszyn służą natomiast odpowiednio komendy vagrant suspend
, vagrant halt
i vagrant destroy
. Wymagają one wskazania maszyny, o którą chodzi, co można zrobić na dwa sposoby. Pierwszy to podanie jej nazwy z Vagrantfile (.vm.define
), który w tym przypadku musi być w folderze, z którego wydawane jest polecenie. Drugą metodą jest podanie identyfikatora, który można poznać, wyświetlając listę wszystkich utworzonych przez Vagranta maszyn: vagrant global-status
. Co istotne, przy użyciu tej metody nie ma znaczenia bieżący folder. I jeszcze jedna wskazówka: posługując się identyfikatorem, wystarczy podać tyle początkowych znaków, ile jednoznacznie identyfikuje maszynę wirtualną.
Vagrant – praktyczne funkcjonalności i ich definicje
Skoro znamy podstawy zarządzania maszynami, wróćmy na moment do Vagrantfile. Na zamieszczonym poniżej przykładzie chciałabym pokazać kilka podstawowych i często przeze mnie używanych opcji.
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" config.vm.define "springboot" config.vm.network "forwarded_port", guest: 8080, host: 8088, host_ip: "127.0.0.1", auto_correct: true config.vm.synced_folder ".", "/vagrant", type: "virtualbox" config.vm.provision "file", source: "./target/demo-0.0.1-SNAPSHOT.jar", destination: "/vagrant" config.vm.provision "shell", path: "springboot_setup.sh" config.vm.provider "virtualbox" do |vb| vb.name = "springboot_VM" end end
Analizując funkcjonalności po kolei, w linii (4) mamy przekazywanie portów, które jest przydatne, gdy chcemy na komputerze hosta mieć dostęp do zasobów uruchomionych na maszynie wirtualnej, np. podczas testowania stron internetowych. Dodatkowo ustawiono adres IP maszyny oraz opcje autocorrect
, która w przypadku wykrycia kolizji portów zamiast ustawionego portu 8088 ustawi inny, wolny. Następna opcja to foldery współdzielone (5), które pozwalają na dzielenie plików między maszynę a komputer hosta, przy czym zmiany aktualizowane są na bieżąco. Pozwala to na edycje plików z poziomu komputera i obserwację zmian na maszynie wirtualnej.
W tym przypadku udostępniamy bieżący folder w folderze /vagrant gościa, podając opcjonalnie hiperwizora. Warto dodać, że domyślnie współdzielony jest folder .vagrant
, tworzony automatycznie w folderze z Vagrantfile – co oczywiście można wyłączyć.
Kolejne dwie opcje należą do osobnej kategorii, nazywanej provisioning
, dzięki czemu są rozdzielone od innych zmian w Vagrantfile. File
(6) pozwala na skopiowanie lokalnego pliku do maszyny wirtualnej (w przeciwieństwie do folderów współdzielonych, zmiany nie będą synchronizowane). Natomiast shell
(7) pozwala na wykonanie skryptu powłoki podanego przez przekazanie ścieżki do odpowiedniego pliku bądź bezpośrednio w Vagrantfile (wtedy zamiast path
trzeba użyć inline
).
Jak wspomniałam, zmiany te są traktowanej inaczej niż zmiany w reszcie konfiguracji, których aktualizacja wykonywana jest każdorazowo przy poleceniu vagrant up
oraz w służącym do takiej właśnie aktualizacji,vagrant reload
. Tymczasem, aby zaobserwować zmiany obsługiwane przez provisioning, wystarczy wydać polecenie vagrant provision
lub doprecyzować, że chcemy poza przeładowaniem wykonać provisoning: vagrant reload --provision
. Domyślnie provisioning wykonywany jest tylko podczas tworzenia maszyny.
Ostatni komentarz dotyczy nazw maszyn. Tutaj można się pogubić, ponieważ tak naprawdę mamy do czynienia z więcej niż jedną nazwą: .vm.define
(3) to nazwa używana przez Vagranta (gdzie domyślna wartość to default), natomiast vb.name
(9) to nazwa wyświetlana przez hiperwizora. Dla braku ustawionej wartości, w przypadku VirtualBoxa nazwa zostanie utworzona przez połączenie nazwy folderu, nazwy maszyny używanej przez Vagranta i losowego ciągu znaków.
Więcej opcji wirtualizacji z Vagrantem
Nie można nie wspomnieć, że Vagrantfile jest traktowany jako plik Ruby, a zatem pozwala na użycie wszystkich konstrukcji oferowanych przez składnię tego języka, w tym zmiennych czy pętli. Są one szczególnie przydatne, gdy chcemy za pomocą jednego pliku opisać wiele maszyn, choćby modelując komunikację między serwerem webowym a bazą danych. Składnia języka różni się nieco od innych popularnych języków programowania, takich jak Python czy Java. Z doświadczenia osoby nieznającej Ruby przed rozpoczęciem pracy z Vagratem, polecam zainteresowanym używaniem bardziej zaawansowanych możliwości konfiguracji zapoznanie się z podstawami składni tego języka.
Na deser: razem z Vagrantem dostajemy „w gratisie” wsparcie dla popularnych narzędzi do automatyzacji zarządzania infrastrukturą, takich jak Ansible, Puppet, Chef i Salt. Dzięki temu możemy w prosty sposób poznać ich działanie bez myślenia o konfiguracji połączenia ssh czy lokalnych ustawieniach komputera. Oprócz nauki Vagrant jest też dobrym narzędziem do testowania działania przygotowanych plików konfiguracyjnych, przykładowo w postaci playbooków Ansible. Dzięki użyciu maszyn wirtualnych zyskujemy pewność, że żadne zaszłości konfiguracyjne nie wpłyną na ich działanie, a także możemy łatwo zmieniać choćby system operacyjny, na którym pracujemy.
Kończąc ten krótki przewodnik po funkcjonalnościach, należy dodać, że nie wyczerpałam tematu, a chcącym go zgłębić i usystematyzować, polecam zacząć od oficjalnej dokumentacji, która jest przejrzysta i przyjazna dla rozpoczynających swoją przygodę z Vagrantem. A jak wiadomo, w IT bez dokumentacji ani rusz.
Vagrant, a kultura DevOps
Zdaję sobie sprawę, że Vagrant jest narzędziem do dość mocno określonych zastosowań, a przy tym nie należy do czołówki technologii wymienianych w ogłoszeniach o pracę. Uważam jednak, że warto go poznać nie tylko po to, by usprawnić korzystanie z maszyn wirtualnych. Za jego działaniem kryją się zasady i koncepcje bliskie kulturze DevOps, przez co może być on świetnym sposobem na pierwsze kroki w tym świecie.
I tak idea przechowywania konfiguracji w pliku tekstowym, znana pod nazwą Infrastructure as Code
, jest uznawana za jedną ze składowych metodyki DevOps. Dzięki rezygnacji z ręcznego wprowadzania ustawień w interfejsie graficznym na rzecz plików tekstowych, zdecydowanie łatwiej uniknąć błędów ludzkich. Możliwe staje się także przechowywanie konfiguracji w systemie kontroli wersji i korzystanie z wszystkich ich dobrodziejstw. W szczególności wyróżnić warto możliwość szybkiego powrotu do poprzedniej, działającej wersji w przypadku, gdy zmiany „coś zepsują”.
Co więcej, schemat tworzenia maszyn wirtualnych przez Vagranta nie jest pozbawiony podobieństw do innych technologii. Przyglądając się działaniu Dockera, łatwo dostrzec analogię między Vagrantfile i Dockerfile jako plikami przechowującymi konfigurację odpowiednio maszyny wirtualnej i kontenera, czy przechowywaniem obrazów w zewnętrznym repozytorium. W obu przypadkach przydatna jest umiejętność tworzenia skryptów powłoki do automatyzacji przygotowania środowiska.
Moja przygoda z Vagrantem – podsumowanie
Poznałam Vagranta, o którym w głównej mierze jest ten artykuł, podczas stażu w Comarch – i żałuję jedynie, że nastąpiło to tak późno, ponieważ jego znajomość znacząco usprawniła moją pracę nad projektami w trakcie studiów. A to tylko jedna z wielu technologii, których można nauczyć się w ramach stażu. W tym roku rekrutacja na staż trwa do 15 kwietnia, warto spróbować i nadać tempa swojej karierze.
Podsumowując, mam nadzieję, że Vagrant pozwoli na przyjemniejszą, bardziej efektywną pracę z maszynami wirtualnymi, a także przybliży zasady pracy w kulturze DevOps. Przywołując radę zasłyszaną na początku moich studiów: chodzi o to, żeby nie uczyć się tylko konkretnej technologii, ponieważ one nieustannie się zmieniają, lecz podejścia i logiki, która się za nimi kryje. A wierzę, że niezależnie od specjalizacji, każdy może czerpać z kultury DevOps.
Na staż w Comarch możecie aplikować do 15 kwietnia. Więcej informacji dotyczących profili stażowych znajdziecie tutaj.
Zdjęcie główne artykułu pochodzi z unsplash.com.