Automatyzacja procesu zarządzania konfiguracją, czyli jeszcze jeden powód dla którego lubię Linuksa
Podejść do tematu zdalnego zarządzania komputerami miałem już kilka. Mając sporo komputerów, w których trzeba czasem coś doinstalować, skonfigurować itp. jakoś nie bardzo chce mi się biegać od komputera do komputera. Stąd poszukiwania jakiegoś wytrychu, którym można by sobie ułatwić życie. Pisałem nawet samodzielnie mały program do zarządzania update'mi i upgrade'ami systemów (w oparciu o Qt4). Pisanie od nowa takiego oprogramowania to jednak dużo pracy i efekt mały w stosunku do włożonego wysiłku. Stąd pomysł, aby nie odkrywać koła od nowa i wykorzystać coś gotowego. Okazuje się, że tego typu darmowych rozwiązań jest cała masa. Znanym i szeroko stosowanym narzędziem jest Puppet. Jednak nie podoba mi się pomysł stosowania ciężkiego klienta na komputerach, które ledwo radzą sobie z zainstalowanym już użytkowym oprogramowaniem. Bliżej za to zainteresowałem się CFEnginem. Wydaje mi się lepszym rozwiązaniem niż Puppet. Napisany w C, zarówno klient jak i serwer nie wymaga dużej ilości zasobów, szczególnie po stronie klienta. Niestety ma on spory minus w postaci dość skomplikowanego języka zapisu oczekiwanego stanu zarządzanych komputerów. (Puppet jest trochę łatwiejszy i chyba właśnie z tego powodu jest bardziej popularny niż CFEngine.) Nie jest to problem dla kogoś kto chce się zajmować tym na co dzień. Jednak jeśli chcemy zarządzać komputerami od czasu do czasu to wysoki próg wejścia jest dość odstraszający. Istnieje ciekawy projekt Rudder napisany w Scali, który umożliwia zarządzanie CFEnginem za pomocą przeglądarki. Jednak dla moich niewielki potrzeb to rozwiązanie jest za ciężkie, wymagające utrzymania dodatkowego serwera tylko do zarządzania. Obydwa wymienione narzędzia mają jeszcze dwie wady. Pierwsza to fakt, że trzeba dbać o klienta zainstalowanego na komputerach i pilnować, aby był w odpowiedniej wersji, a klient Puppeta wymaga okresowego restartu (tak przynajmniej było w starszej wersji Rubiego w którym jest on napisany). Drugą jest czas reakcji. Pisząc pliki konfiguracyjne do zarządzania musimy czekać aż klient na komputerach je pobierze i wykona, a następnie zwróci raporty o wynikach. W razie jakiś problemów dowiemy się o tym dopiero po upływie nawet godziny. Wymieniłem do tej pory tylko dwa tego typu systemy, ale jest ich więcej, w tym Salt napisany w Pythonie. Jest też sporo narzędzi będących w rzeczywistości systemami zarządzania skryptami, tak jak chociażby Rundeck w którym całe zarządzanie odbywa się poprzez stronę internetową.
Na szczęście istnieje świetne narzędzie pozbawione wielu tych wad (ma za to inne, niektórzy zaliczyliby do nich działanie tylko na systemach Uniksowych). Ansible jest dość wyjątkowy jak na narzędzie typu "provisionig" ze względu na to, że nie używa dedykowanego programu klienta i wszystkie operacje wykonywane są na klientach za pomocą połączenia ssh. Wystarczy więc zainstalować na zarządzanych komputerach ssh serwer (na serwerach www zazwyczaj już jest) oraz dodać klucz ssh zarządzającego komputera (w pliku ~/.ssh/authorized_keys). Na komputerze z którego chcemy prowadzić kontrolę instalujemy Ansible (może to być inny serwer lub nasz laptop), edytujemy plik /etc/ansible/hosts dodając adresy komputerów (może być IP lub adres domeny). Plik ma postać:
[nazwa_grupy] host1.domena.pl host2.edu.pl:5353 [grupa_druga] 192.168.1.23 192.168.1.[34:39] [mojewszystkie:children] nazwa_grupy druga_grupa
Jak widać możemy określać niestandardowy port ssh, definiować zakres adresów oraz tworzyć grupy z już istniejących grup (są jeszcze inne możliwości, których tu nie opisuję). Mimo, że w niektórych tutorialach radzą, aby używać do tego konta root oczywiste jest, że nie jest to mądre rozwiązanie. Najlepiej jest wykorzystać do tego użytkownika z uprawnieniami sudo. Na wszystkich komputerach, albo na komputerach z danej grupy ustawiamy taką samą nazwę użytkownika i hasło (można dodać użytkownika tylko w tym celu). Uruchamiając Ansible będziemy musieli za każdym razem podać hasło.
Sama architektura tego narzędzia jest zbudowana modułowo. Można dodawać nowe moduły do zarządzania konfiguracją i pisać je w dowolnym języku programowania pomimo, że sam program jest napisany w Pythonie. Obecna ilość modułów jest tak duża, że wątpię aby ktokolwiek nie znalazł takiego, który spełniałby jego wymagania. Ta możliwość przydaje się raczej firmom potrzebującym wykonania jakiegoś bardzo nietypowego zadania.
Zarządzanie konfiguracją
Najważniejsze jak dla mnie jest to, że zarządzanie nie wymaga wiele nauki. Już po kilkudziesięciu minutach poświęconych na czytanie dokumentacji można napisać coś sensownego i wykorzystać do wykonania pracy. Istnieją dwa tryby zarządzania. Pierwszy to pojedyncze polecenia, przykładowo:
ansible all -m ping
- pingowanie klientów. Pierwszy parametr all oznacza wybór wszystkich grup hostów, których zdefiniowaliśmy wcześniej w pliku /etc/ansible/hosts. Można też osobno odwoływać się do grup lub pojedynczych serwerów.
ansible all -a "jakieś polecenie bash" --user=administrator -K
- uruchomienie polecenia powłoki jako użytkownik administrator, gdzie parametr K każe uruchomić polecenie za pomocą sudo i zapytać ansible o hasło.
ansible all -m apt -a "pkg=eclipse state=present" --user=administrator -K
- użycie modułu apt do instalacji pakietów na systemach debianowych - instalujemy eclipse.
Drugim sposobem jest wykonywanie wielu działań na raz za pomocą tzw. playbook. Są to pliki w YAML, których składnia jest bardzo prosta:
- hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: pkg=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running service: name=httpd state=started handlers: - name: restart apache service: name=httpd state=restarted
Kolejno deklarujemy w nim z jaką grupą hostów pracujemy, dodajemy zmienne, użytkownika na koncie którego będziemy wykonywać polecenia, oraz zadania. Zadanie ma swój opis - komentarz (name) oraz podany moduł (np. yum) i stan. Po kilku minutach nauki składni można zacząć już pracę i tworzyć proste playbooki. Małym problemem Ansible może być fakt, że w pliku hosts wpisujemy IP (lub domeny) i gdy mamy komputery o zmiennym IP z DHCP to nie mamy możliwości nim zarządzać. Łatwo temu zaradzić pisząc proste programiki lub skrypty. Sam akurat korzystam z tego typu konfiguracji i napisałem programik do rozwiązania tego problemu z tym, że ma on być częścią większego rozwiązania w formie zarządzania webowego playbookami. Programy tego typu można również znaleźć w sieci.
Playbooka uruchamiamy poleceniem ansible-playbook, przykładowo:
ansible-playbook playbook.yml -f 10 -K
gdzie -f oznacza ilość procesów ansible równolegle wykonującymi polecenia, a -K wymusza pytanie o hasło sudo. W przypadku niepowodzenia odnalezienia serwera lub nieudanego polecenia Ansible zrzuca plik o nazwie playbooka z rozszerzeniem .retry i możemy go ponownie uruchomić, aby dokończyć pracę. Zachowanie typu "push", czyli łączenie się z klientami przez serwer można odwrócić na "pull" poprzez instalację ansible-pull na klientach, które korzysta dodatkowo z git. Następnie pobiera przez gita konfigurację playbook i wykonuje lokalnie. Rozwiązanie to likwiduje niedogodność polegającą na tym, że to nasz komputer w Ansible przez ssh zajmuje się każdym komputerem z osobna, co dla dużej ich ilości może być powolne. Problem ten można również rozwiązać używając systemu serwerów proxy, do których wysyłamy konfigurację i one zajmują się wykonaniem ich na klientach. Możemy wreszcie doinstalować na kliencie protokół 0mq (jest równocześnie demonem), który pozwala na szybszą komunikację z klientem zamiast użycia ssh.
Samo Ansible bardzo mi się podoba i decydujące tutaj poza lekkością po stronie klienta (serwer ssh) oraz niskim progiem wejścia jest fakt, że od razu wiem jaki skutek odniosły moje działania. Jednak dla osób, które chciałyby zarządzać dużą ilością desktopów (zawodowo) lepszym rozwiązaniem może okazać się CFEngine lub Puppet. Natomiast dla moich potrzeb Ansible nadaje się wyśmienicie i jestem z niego zadowolony. Jest to również następny powód do lubienia Linuksa. Duża ilość różnorodnych i do tego darmowych narzędzi do zarządzania konfiguracją daje mi dużo możliwości. Mogę wybrać takie rozwiązanie, które najbardziej mi pasuje i używać tak długo jak spełnia moje wymagania. A gdy pewnego dnia stwierdzę, że już mi nie wystarcza, rozglądnąć się za czymś innym, ponieważ nie krępuje mnie jego koszt.