Instalacja marionetki. Scentralizowana konfiguracja systemów UNIX przy użyciu Puppet

Dom / Urządzenia mobilne

Nie tak dawno temu na łamach magazynu przyglądaliśmy się systemowi zdalne sterowanie konfiguracja maszyn UNIX Cfengine, co znacznie upraszcza życie administratora systemu poprzez automatyzację kroków konfiguracyjnych wielu węzłów sieci. Ale niezależnie od tego, jak wygodny jest Cfengine, ma on wiele wad, których nie ma system o nazwie Puppet.

Wyobraź sobie siebie w roli administratora systemu, odpowiedzialnego za utrzymanie funkcjonalności setek maszyn z systemami operacyjnymi typu UNIX. Każdy z nich wymaga konfiguracji, okresowej aktualizacji i monitorowania, przy czym zakłada się, że wiele z nich spełnia podobne funkcje.

Dwie trzecie to stacje robocze, kilka kolejnych to routery, reszta to kilka serwerów internetowych i magazynów danych. Pytanie: jak zarządzać całym tym biznesem? Najprostszą odpowiedzią jest po prostu połączenie się z każdym z nich za pomocą SSH i dokonanie niezbędnych zmian. Jednak metoda ta ma dwa problemy. Po pierwsze, jest to bardzo pracochłonne. Po drugie, administrator będzie musiał stale wykonywać wiele monotonnych czynności (np. aby zaktualizować OpenOffice.org na wszystkich stacjach roboczych, trzeba będzie kilkadziesiąt razy wykonać te same polecenia). Możesz spróbować uniknąć tego problemu, pisząc kilka skryptów, które same połączą się z każdą maszyną i wykonają wcześniej napisane polecenia. Ale i tutaj czekają Cię problemy.

Skrypty będą musiały być stale modyfikowane, aby dostosować je do każdego zadania; Skrypty będą musiały uwzględniać różnice w systemach operacyjnych i wersjach, a także będą musiały być długo debugowane, zanim zostaną zastosowane na uruchomionych maszynach. Ogólnie rzecz biorąc, nie comme il faut. Prawidłową odpowiedzią jest wykorzystanie tzw. systemów zdalnego zarządzania konfiguracją, których najsłynniejszymi przedstawicielami są systemy otwarte Cfengine i Marionetka. Takie systemy przejmują całą odpowiedzialność za dostosowanie konfiguracji maszyny właściwy typ, wymagając od administratora jedynie opisania końcowego stanu systemu w specjalnym języku (na przykład opis, jakie pakiety należy zainstalować w systemie operacyjnym, jakie linie dodać do plików konfiguracyjnych, jakie polecenia należy wykonać itp.). ). Następnie wszystkie węzły same otrzymają informację o wymaganym stanie z serwera i dokonają autokonfiguracji systemu. Dzięki temu mechanizmowi nowe maszyny można w pełni skonfigurować bez ingerencji człowieka, a istniejące można rekonfigurować dodając zaledwie kilka linijek do opisu stanu.

Marionetka?

Systemowi Cfengine poświęciliśmy już cały artykuł, dlatego dziś skupimy się na systemie Marionetek, który śmiało można nazwać jego ideologicznym następcą. Twórcą Puppeta był Luke Kanies, któremu znudziły się ograniczenia Cfengine i postanowił stworzyć od podstaw lepszą wersję. Jeśli korzystałeś już z Cfenfine, prawdopodobnie uznasz Puppet za wygodniejszy i wydajniejszy system. Język stanu Puppet jest bardziej zaawansowany i elastyczny, więc administratorzy nie muszą się martwić o takie rzeczy, jak pisanie oddzielnych reguł dla każdego typu systemu operacyjnego lub szczegółowy opis wykonując banalne czynności. Marionetka pozwala swojemu mistrzowi skupić się na tym, co chce zrobić, zamiast na tym, jak to zrobić (na przykład, aby zainstalować konkretny pakiet na dowolnym obsługiwanym systemie operacyjnym, wystarczy napisać dosłownie kilka linijek z napisem „Zainstaluj ten program " zamiast opisywać polecenia niezbędne do jego instalacji). Puppet napisany jest w prostym języku Ruby, co pozwala łatwo dostosować go do konkretnego zadania i rozszerzyć jego funkcjonalność (zapewniony jest elastyczny system wtyczek).

Dodatkowo, w przeciwieństwie do modelu rozwoju Cfengine, który zasadniczo kręci się wokół jednej osoby, Puppet ma dużą społeczność entuzjastów, którzy ulepszają kod, dzielą się przykładami konfiguracji i piszą dokumentację.

Ogólnie Puppet wydaje się być systemem bardziej nowoczesnym i przemyślanym dobry projekt. Podobnie jak Cfengine, obsługuje prawie wszystkie nowoczesne systemy operacyjne typu UNIX (w tym MacOS X), a także może działać w środowisku Cygwin na systemie Windows. Jego lista zależności zawiera tylko interpreter Ruby i narzędzie Factor, więc z instalacją nie powinno być problemów (szczerze mówiąc, lista zależności Cfengine jest jeszcze krótsza).

Instalacja

Podobnie jak Cfengne, Puppet jest systemem klient-serwer składającym się z serwera sterującego i węzłów podrzędnych. Serwer przechowuje opis końcowych stanów węzłów (co w terminologii Puppeta nazywa się manifestem) i czeka na ich połączenie. Co pół godziny (domyślnie) klient łączy się z serwerem, otrzymuje od niego opis stanu końcowego, porównuje go z aktualnym i jeżeli on i/lub opisywany stan uległ zmianie, dokonuje rekonfiguracji systemu oraz potem idzie spać. Komunikacja odbywa się za pośrednictwem szyfrowanego kanału, więc wykluczone są ataki polegające na podstawieniu opisu stanu (jednak jeśli atakujący przejmie serwer, wówczas wszystkie węzły znajdą się pod jego kontrolą).

Puppet znajduje się w repozytoriach wszystkich popularnych dystrybucji, więc jego instalacja nie powinna być trudna. Na przykład w Debianie/Ubuntu klienta Puppet można zainstalować w następujący sposób:

$ Sudo apt-get install marionetka

A serwer wygląda tak:

$ sudo apt-get zainstaluj marionetkowy mistrz marionetek

Pliki konfiguracyjne klienta i serwera są przechowywane w katalogu /etc/puppet. Najważniejszym z nich jest plik /etc/puppet/manifests/site.pp, który zawiera manifest.

Przechowuje opis stanów i powinien istnieć tylko na serwerze. Aby ułatwić debugowanie, dodajmy do niego prostą konfigurację:


hasło klasy(
plik("/etc/passwd":
właściciel => root,
grupa => korzeń,
tryb => 644,
}
}
domyślny węzeł (
zawiera hasło
}

Linie te opisują stan, w którym właścicielem pliku /etc/passwd musi być root, a jego uprawnienia są ustawione na 644. W następnej sekcji przyjrzymy się bliżej formatowi pliku manifestu. Drugim najważniejszym plikiem jest /etc/puppet/puppet.conf. Ustawia konfigurację serwera i klientów, dlatego musi być obecny na wszystkich komputerach zorganizowanych w sieci Puppet. W Ubuntu plik ten zawiera minimalne niezbędne i w większości przypadków wystarczające ustawienia. Poniżej podano je z komentarzem:

# vi /etc/puppet/puppet.conf
# Standardowe ścieżki katalogów
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
# Współczynnik lokalizacji narzędzia,
# używany do uzyskiwania informacji o systemie operacyjnym
factpath=$vardir/lib/faktor
# Synchronizuj wtyczki
# (wtyczki zainstalowane na serwerze - są kopiowane do klientów)
pluginsync=true
# Katalog z szablonami (przeczytaj o nich poniżej)
templatedir=$confdir/szablony
# Synchronizacja z etckeeperem
# (kto wie, zrozumie, innym nie jest to potrzebne)
prerun_command=/etc/puppet/etckeeper-commitpre
postrun_command=/etc/puppet/etckeeper-commitpost

Plik konfiguracyjny może zawierać duża liczba różne opcje, o których informacje można uzyskać generując domyślną konfigurację:

$ sudo puppetmasterd -genconfig > /etc/puppet/
puppetd.conf.default

Domyślna konfiguracja klienta jest generowana przy użyciu innego polecenia:

$ sudo puppet -genconfig > /etc/puppet/puppetd.conf.default

Do konfiguracji wykorzystywane są pliki Fileserver.conf i auth.conf serwer plików(przeczytaj o tym w sekcji „Serwer plików”) i uwierzytelnianie. Nie ma jeszcze sensu ich dotykać. Po zakończeniu konfiguracji serwer Puppet musi zostać zrestartowany:

$ sudo /etc/init.d/puppetmaster uruchom ponownie

Po czym będzie gotowy do przyjmowania żądań klientów. Jednak bez podpisanego certyfikatu żaden klient nie będzie mógł odebrać manifestu z serwera i skonfigurować maszyny.

Dlatego musimy uruchomić klientów Puppet w trybie testowym, aby mogli przesłać swoje certyfikaty na serwer do podpisu (swoją drogą można to zrobić na wszystkich komputerach jednocześnie za pomocą narzędzia shmux):

$ sudo puppetd -server puppet-server.com -verbose -test

Wracamy na serwer i otrzymujemy listę certyfikatów gotowych do podpisania:

$ sudo puppetca --list

Wybierz hosta z listy i podpisz jego certyfikat:

$ sudo puppetca --sign nomad.grinder.com

Lub podpisujemy wszystko na raz:

$ sudo puppetca --sign --all

Teraz możesz uruchamiać klientów w trybie walki. Ale najpierw musisz wpisać nazwę serwera Puppet w pliku konfiguracyjnym (domyślnie jego nazwa to po prostu marionetka):

$sudo su
# echo "" >> /etc/puppet/puppet.conf
# echo "server=puppet-server.com" >> /etc/puppet/puppet.conf
# Wyjście

Uruchamianie klientów:

$ sudo /etc/init.d/puppet start

Język opisu stanu

Jak wspomniano powyżej, Puppet używa własnego języka do opisu stanu końcowego system operacyjny, za pomocą którego administrator systemu wskazuje, do jakiej formy należy doprowadzić komponenty systemu operacyjnego, aby osiągnął on pożądany stan. Jest to dość złożony język, który jednak jest znacznie prostszy niż jakikolwiek język programowania. Jeśli przynajmniej powierzchownie znasz język skryptowy bash, z łatwością zrozumiesz język Puppet. Kluczowym elementem języka są zasoby, które służą do opisania, do jakiej postaci należy przekonwertować jeden z komponentów systemu operacyjnego. Na przykład następujący prosty zasób opisuje pożądany stan pliku /etc/passwd:

# vi /etc/puppet/manifests/site.pp
plik("/etc/passwd":
właściciel => „root”
}

Tutaj plik jest typem zasobu. W sumie jest ich kilkadziesiąt, począwszy od zasobów zarządzających plikami, jak w tym przykładzie, po pakiety i usługi. Linia /etc/passwd to nazwa zasobu.

W przypadku typu pliku nazwa jest taka sama jak ścieżka do pliku, lecz w przypadku niektórych innych typów nazwa może być dowolna. Linia właściciel => „root” opisuje ustawienie atrybutu właściciela na root, to znaczy mówi, że właściciel określony plik musi być administrator.

Każdy typ zasobu ma swój własny zestaw atrybutów dostępnych do modyfikacji, a ponadto istnieją specjalne atrybuty meta, których można użyć w dowolnym zasobie. Jedną z ważnych cech zasobów jest możliwość powiązania z nimi. Można to wykorzystać do tworzenia łańcuchów zależności. Poniższy wpis tworzy zasób /etc/group, który jest zależny od zasobu /etc/passwd (zależności są określane za pomocą atrybutu meta require):

# vi /etc/puppet/manifests/site.pp
plik("/etc/grupa":
wymagaj => Plik["/etc/passwd"],
właściciel => "root",
}

Oznacza to, że zasób /etc/group można skonfigurować (doprowadzić do opisanej postaci) tylko wtedy, gdy skonfigurowany jest zasób /etc/passwd. Zasoby można pogrupować w kolekcje zasobów zwane klasami. Jest to konieczne, aby w jeden abstrakcyjny zasób połączyć zasoby o podobnym znaczeniu i rodzaju wykonywanego zadania. Na przykład dla wygody moglibyśmy połączyć instalację i uruchomienie serwera WWW Nginx w jeden abstrakcyjny zasób o tej samej nazwie:

# vi /etc/puppet/manifests/site.pp
klasa nginx(
pakiet("nginx":
upewnij się => zainstalowany
}
usługa("nginx":
upewnij się => działa,
wymagaj => Pakiet["nginx"],
}
}

Tutaj typ zasobu pakietu służy do zainstalowania pakietu nginx w systemie, a usługa służy do uruchomienia usługi o tej samej nazwie. Za pomocą require wymuszamy na systemie uruchomienie usługi tylko wtedy, gdy pakiet został pomyślnie zainstalowany. Wygoda zajęć polega na tym, że można je uwzględniać także w zależności od:

# vi /etc/puppet/manifests/site.pp
usługa("kałamarnica":
upewnij się => działa,
wymagaj => Klasa["nginx"],
}

Podobnie jak w prawdziwych językach OOP, klasy mogą dziedziczyć od siebie i zastępować atrybuty:

# vi /etc/puppet/manifests/site.pp
hasło klasy(
plik("/etc/passwd":
właściciel => "root",
grupa => "root",
}
}
klasa passwd-bsd dziedziczy passwd (
Plik["/etc/passwd"] ( grupa => "koło")
}

Tutaj klasa passwd-bsd dziedziczy po passwd, aby zastąpić atrybut group zasobu /etc/passwd (w systemach BSD /etc/passwd należy do grupy koła, dlatego stworzyliśmy osobną klasę dla takich systemów). Później przyjrzymy się bardziej poprawnemu i oczywistemu sposobowi wyboru alternatywnych wartości atrybutów za pomocą warunków.

Zmienne są jednym z podstawowych elementów każdego języka programowania i Puppet również je posiada. Zmienne zaczynają się od znaku $ i mogą zawierać dowolną liczbę, ciąg znaków lub wartość logiczna(prawda, fałsz):

$want_apache = prawda
$apache_version = "2.2.14"

Jedną z najpotężniejszych funkcji Puppet związanych ze zmiennymi jest jego integracja z narzędziem informacyjnym o maszynie fakterskiej. Narzędzie to zwraca wszystkie informacje specyficzne dla komputera w postaci par klucz-wartość, które w programie Puppet są przekształcane w zmienne o tej samej nazwie. Razem z instrukcjami warunkowymi w języku Puppet można ich używać do zmiany atrybutów zasobów w zależności od właściwości maszyny.

Na przykład opisaną powyżej klasę passwd można łatwo przepisać, aby automatycznie wybierała atrybut w zależności od typu systemu operacyjnego (bez potrzeby stosowania samej klasy):

# vi /etc/puppet/manifests/site.pp
plik("/etc/passwd":
właściciel => "root",
grupa => $jądro? (
Linux => „root”,
FreeBSD => "koło",
},
}

W zależności od tego, w jakim systemie operacyjnym będzie analizowany ten fragment manifestu, wartością atrybutu group będzie root lub koło. Z wyjątkiem operatora warunkowego, język Puppet obsługuje również operator wyboru przypadków, którego można użyć do utworzenia określonego zasobu w zależności od wartości zmiennej:

# vi /etc/puppet/manifests/site.pp
sprawa $system operacyjny (
redhat: (usługa("httpd": upewnij się, że => działa))
debian: (service("Apache": upewnij się, że => działa))
domyślnie: ( service („Apache2”: upewnij się, że =>
działanie))
}

Ten kod definiuje różne opcje zasób typu service w zależności od systemu operacyjnego (nazwy usług w różnych dystrybucjach Linuksa mogą się różnić, dlatego też to, jaką usługę Puppet ma uruchomić, należy określić indywidualnie dla każdej z nich).

Opcja domyślna stosowana jest w przypadku, gdy wartość zmiennej nie odpowiada żadnej z poprzednich opcji. Oprócz wcześniej omówionych typów zasobów plików, pakietów i usług, Puppet obsługuje dużą liczbę innych typów zasobów, w tym te utworzone przez zewnętrznych programistów. Ich szczegółowy opis, zawierający przykłady, obsługiwane atrybuty i funkcje, można znaleźć w oficjalnej dokumentacji - http://docs.puppetlabs.com/references/stable/type.html. Poniżej znajduje się lista i krótki opis najczęściej używane to:

Popularne typy zasobów Marionetka

  • cron - zarządzaj zadaniami cron
  • exec - uruchamiaj skrypty i polecenia
  • plik - zarządzanie plikami
  • zasobnik plików - kopia zapasowa akta
  • grupa - zarządzanie grupą
  • host – zarządzaj wpisami w pliku /etc/hosts
  • interfejs - konfiguracja interfejsów sieciowych
  • mount - montowanie systemów plików
  • notify - wyślij wiadomość do pliku dziennika Puppet
  • pakiet - zarządzanie pakietami
  • usługa - zarządzanie usługami
  • sshkey - zarządzaj kluczami SSH
  • tidy - usuwanie plików w zależności od warunków
  • użytkownik - zarządzanie użytkownikami
  • strefy - Zarządzanie strefami Solaris

Drugim najważniejszym elementem języka Puppet po zasobach są węzły. Za ich pomocą administrator może opisać, do jakich maszyn mają zostać zastosowane określone zasoby i klasy. Inaczej mówiąc, jest to sposób na określenie indywidualnej konfiguracji dla każdej z maszyn uczestniczących w sieci Puppet. Najprostszy przykład węzła podano na początku artykułu w sekcji „Instalacja”:

# vi /etc/puppet/manifests/site.pp
domyślny węzeł (
zawiera hasło
}

To jest definicja domyślnego węzła, która zawiera zasób/klasę passwd. Domyślna nazwa oznacza „wszystkie inne węzły”, więc zasób/klasa passwd zdefiniowana gdzieś powyżej zostanie skonfigurowana na każdym z nich. Słowo kluczowe include zostało tutaj użyte dla wygody; w rzeczywistości wszystkie klasy i zasoby można opisać bezpośrednio w opisie węzła, ale nie jest to zalecane. Oprócz domyślnej, w nazwie węzła można podać nazwę sieciową maszyny (wtedy wszystkie zasoby opisane w węźle zostaną skonfigurowane tylko na tej maszynie) lub dowolną nazwę (wtedy węzeł ten może zostać odziedziczony przez inny węzeł) . Aby zrozumieć jak to wszystko współpracuje z klasami i zasobami, spójrzmy na przykład gotowego manifestu Puppet służącego do konfiguracji dwóch maszyn sieciowych (serwera WWW i serwera NTP):

# vi /etc/puppet/manifests/site.pp
# Instalowanie i uruchamianie serwera SSH
klasa sshd (
pakiet ( openssh-server: upewnij się => zainstalowany)
usługa (sshd:
nazwa => $system operacyjny ? (
fedora => "sshd",
debian => "ssh",
domyślnie => "sshd",
},
włącz => prawda,
upewnij się => działa,
}
}
# Zainstaluj i uruchom Apache
klasa httpd(
pakiet (httpd: upewnij się => zainstalowany)
usługa(httpd:
włącz => prawda,
upewnij się => działa,
}
}
# Instalowanie i uruchamianie serwera NTP
klasa ntpd(
pakiet (serwer NTP: upewnij się => zainstalowany)
praca (
serwer NTP:
włącz => prawda,
upewnij się => działa,
}
}
# Węzeł podstawowy, używany tylko jako rodzic wszystkich pozostałych
podstawa węzła (
Dołącz sshd
}
# Węzeł, w którym będzie zlokalizowany serwer WWW
węzeł web.server.com dziedziczy bazę (
Dołącz httpd
}
# Węzeł serwera NTP
węzeł ntp.server.com dziedziczy bazę (
uwzględnij ntpd
}

Ta pozornie prosta konfiguracja robi całkiem sporo: instaluje i uruchamia Apache na komputerze pod adresem web.server.com oraz instaluje i uruchamia serwer NTP na komputerze. ntp.server.com. Dodatkowo na obu komputerach instalowany jest serwer SSH. Jest mało prawdopodobne, aby ta konfiguracja odpowiadała choćby jednemu administratorowi; trzeba będzie go poważnie ulepszyć, aby uczył, jak poprawnie konfigurować serwery, otrzymywać świeże konfiguracje i inne pliki z głównego serwera Puppet.

Jednak wyraźnie pokazuje siłę Puppet. Stosując prostą konfigurację, sprawiliśmy, że maszyny same instalowały i uruchamiały niezbędne oprogramowanie oraz utrzymywały je w dobrym stanie (jeśli serwer ulegnie awarii, Puppet sam przeprowadzi ponowną konfigurację, aby doprowadzić systemy do wymaganego stanu).

Serwer plików

Wiele zadań związanych ze zdalną administracją nie może zostać rozwiązanych bez kopiowania na komputery dodatkowe pliki. Mogą to być wstępnie przygotowane konfiguracje, strony internetowe dla Apache, pakiety, których nie ma w oficjalnym repozytorium i wiele więcej. Aby ułatwić proces przesyłania tych plików do zdalnych hostów, Puppet zawiera serwer plików.

Ustawienia serwera plików są przechowywane w pliku /etc/puppet/fileserver.conf. Aby zmusić Puppet do udostępniania klientom zawartości określonego katalogu, musisz umieścić w nim kilka linii:

# vi /etc/puppet/fileserver.conf
ścieżka = /var/puppet/files
zezwól na *.server.com

Te dwie linie wskazują, że katalog /var/puppet/files powinien być dostępny dla wszystkich hostów w domenie server.com. Dodatkowo możemy określić pełną nazwę domeny dozwolonej maszyny lub jej adres IP, a także odciąć niechciane za pomocą dyrektywy deny. Następnie dowolny plik w tym katalogu można przenieść do klienta przy użyciu zasobu plikowego. Na przykład:

# vi /etc/puppet/manifests/site.pp
plik("/etc/httpd/conf/httpd.conf":
źródło => "marionetka://httpd/httpd.conf",
tryb => 644,
}

Plik httpd.conf, znajdujący się na serwerze w katalogu /var/puppet/files/httpd, zostanie skopiowany na komputer docelowy ścieżką określoną w nazwie zasobu.

Wnioski

W tym artykule omówiliśmy bardzo małą część możliwości Puppet. Właściwie to złożony system, które w pełni można opisać jedynie na kartach książki. Jednocześnie Puppet jest bardzo łatwy w konfiguracji i utrzymaniu, zwłaszcza, że ​​w Internecie można znaleźć mnóstwo przykładów jego konfiguracji.

Informacje

  • Puppet korzysta z protokołu HTTP, więc można go uruchomić na serwerze WWW, aby poprawić wydajność.
  • Puppet może służyć do automatycznej konfiguracji i konserwacji pojedynczej maszyny lokalnej.
  • Łącząc Puppet, instalację sieciowego systemu operacyjnego (pxe-install) i samobudujące się obrazy instalacyjne, możesz stworzyć całkowicie samokonfigurującą się sieć maszyn, którą można wdrożyć za pomocą tylko jednego polecenia.
  • Wiele dużych firm wykorzystuje w swojej pracy Puppet, jak np. Google, Fedora Project, Stanford University, Red Hat, Siemens IT Solution czy SugarCRM.

Spinki do mankietów

  • http://docs.puppetlabs.com — Dokumentacja lalek
  • http://docs.puppetlabs.com/guides/language_tutorial.html — Pełny opis Język lalek
  • http://docs.puppetlabs.com/references/stable/type.html — Typy zasobów

Kiedy liczba serwerów, którymi zarządzasz, jest mniejsza niż dziesięć, rzadko kiedy ktoś myśli o ich scentralizowanym zarządzaniu, może to nie być wymagane. W przypadku kilkudziesięciu serwerów niezwykle przydatne jest scentralizowane zarządzanie oprogramowaniem i konfiguracją. Jest to niezbędne w przypadku setek i tysięcy serwerów. Programów tego typu jest wiele, np.: Chef, CFEngine, Puppet... Właśnie o tym ostatnim porozmawiamy w tym poście.

Marionetka jest zasłużenie uważana za jedną z najlepsze rozwiązania tak. Używają go takie firmy jak Google, Citrix i Red Hat. Jest to aplikacja klient-serwer napisana w języku programowania Ruby, która dystrybuowana jest w dwóch wersjach:

  • Puppet Open Source - całkowicie darmowa wersja
  • Puppet Enterprise - bezpłatnie do 10 serwerów, następnie wymagane licencje

Rozważmy instalację serwera i agenta Puppet Open Source, które znajdują się w pakietach większości nowoczesnych dystrybucji. Następnie porozmawiamy o Ubuntu 12.04 Precise Pangolin.

Tylna część Puppet nazywa się mistrz lalek, zacznijmy instalację od tego miejsca:

:~# apt-get install marionetka

A teraz klient:

:~# apt-get install marionetka

W pliku konfiguracyjnym klienta /etc/puppet/puppet.conf musisz porozmawiać o serwerze, dodając następującą sekcję:

Serwer=puppet.local report=true pluginsync=false

Na początkowym etapie lepiej wyłączyć synchronizację wtyczki.

Uruchommy klienta marionetkowego, aby utworzył żądanie certyfikatu:

:~# puppetd --verbose --test info: Tworzenie nowego klucza SSL dla informacji o linux.local: Buforowanie certyfikatu dla informacji o CA: Tworzenie nowego żądania certyfikatu SSL dla informacji o linux.local: Odcisk palca żądania certyfikatu (md5): E5: EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51 Wyjście; nie znaleziono certyfikatu, a Waitforcecert jest wyłączony

Na serwerze należy sprawdzić, czy otrzymano żądanie certyfikatu i jeśli tak, wystawić certyfikat:

:~# puppetca --list "linux.local" (E5:EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51) :~# lalek - -sign linux.local zawiadomienie: Podpisane żądanie certyfikatu dla linux.local powiadomienie: Usuwanie pliku Puppet::SSL::CertificateRequest linux.local w "/var/lib/puppet/ssl/ca/requests/linux.local.pem"

Powtórz poprzedni krok na kliencie:

:~# puppetd --verbose --test info: Informacje o buforowaniu certyfikatu dla linux.local: Pobieranie informacji o wtyczce: Buforowanie listy odwołań_certyfikatów dla informacji o CA: Informacje o katalogu buforowania dla linux.local: Stosowanie wersji konfiguracyjnej „1356278451” Informacje: Tworzenie pliku stanu / var/lib/puppet/state/state.yaml zawiadomienie: Ukończenie katalogu w 0,02 sekundy

Świetnie, wszystko działa. Przejdźmy do tworzenia pierwszego manifestu. Manifesty, czyli konfiguracje, są opisane w specjalnym języku deklaratywnym. Od razu przywykniemy do dobrych rzeczy, będziemy korzystać z modułowej struktury i klas. Na przykład napiszmy moduł, który będzie dbał o aktualność pliku /etc/hosts na wszystkich naszych serwerach.

Sprawdźmy gdzie marionetka szuka modułów:

:~# marionetka Apply --configprint ścieżka modułu /etc/puppet/modules:/usr/share/puppet/modules

Utwórz katalogi dla swojego modułu

:~# cd /etc/puppet/modules :~# mkdir hosts; hosty płyt CD; manifest mkdir; manifesty CD

Należy wywołać pierwszy manifest, zwany także głównym plikiem modułu init.pp

Hosty klasy ( # puppet.local host ( "puppet.local": zapewnienia => "obecny", target => "/etc/hosts", ip => "192.168.0.1", host_aliases => "marionetka", ) # host linux.local („linux.local”: zapewnienia => „obecny”, cel => „/etc/hosts”, ip => „192.168.0.2”, host_aliases => „linux”, ) )

Domyślnie marionetka szuka pliku /etc/puppet/manifests/site.pp aby załadować konfigurację, sprowadźmy ją do następującej postaci:

Domyślny węzeł (uwzględnij hosty)

Sprawdzamy manifest na serwerze:

:~# marionetka Apply --verbose /etc/puppet/manifests/site.pp info: Stosowanie wersji konfiguracji „1356281036” uwaga: /Stage//Host/ensure: utworzone informacje: FileBucket dodawanie (md5)powiadomienie: /Stage// Host/zapewnij: utworzono powiadomienie: Zakończono uruchomienie katalogu w 0,03 sekundy

Na kliencie:

:~# ll /etc/hosts rw-r--r-- 1 root root 290 16 grudnia 19:10 /etc/hosts :~# puppetd --verbose --informacje o teście: Katalog pamięci podręcznej dla informacji o linux.local: Stosowanie wersja konfiguracji „1356283380” Informacje: FileBucket dodawanie (md5)powiadomienie: /Stage/Hosts/Host/ensure: utworzone powiadomienie: /Stage/Hosts/Host/ensure: utworzone powiadomienie: Zakończono uruchomienie katalogu w 0,04 sekundy: ~# ll /etc /hosts -rw-r--r-- 1 korzeń główny 551 23 grudnia 20:43 /etc/hosts

Gdy mamy pewność, że wszystko działa, pozwalamy na uruchomienie usługi /etc/default/puppet zmiana:

# Uruchomić marionetkę przy starcie? START=tak

Uruchomienie usługi

:~# uruchomienie marionetki serwisowej

Puppet będzie co 30 minut odpytywał serwer puppetmaster o zmiany w konfiguracji i, jeśli to konieczne, odpowiednio dostosuje system.

Jakiś czas temu lista serwerów w moich zakładkach przekroczyła 200. Wraz ze wzrostem liczby serwerów wdrażanie jakiejkolwiek nowej konfiguracji lub instalowanie nowych pakietów to ogromna ilość czasu. Dlatego zdecydowałem się użyć marionetki.
Marionetka(English marionetka) to wieloplatformowa aplikacja klient-serwer, która pozwala centralnie zarządzać konfiguracją systemów operacyjnych i programów zainstalowanych na kilku komputerach. Puppet jest napisany w języku programowania Ruby.

Mówią też, że marionetka to system zdalnego zarządzania konfiguracją, którego najbardziej znanymi przedstawicielami są systemy otwarte Cfengine i Puppet.

Po przeczytaniu recenzji zdecydowałem się na użycie marionetki.

Instalacja i konfiguracja serwera Puppet:
Instalowanie serwera marionetkowego:
Zainstaluj serwer lalek na OpenSuSE 11.4:

zamek błyskawiczny w marionetkowym serwerze

Zmieńmy nazwę serwera na marionetkowy:
/etc/NAZWA HOSTA:

Rekord DNS musi mieć adres 127.0.0.2
kot /etc/hosts:

127.0.0.2 marionetka.strona marionetkowa

Dajmy użytkownikowi uprawnienia marionetka:

Uruchommy usługę Władca Marionetek:

początek rcpuppetmasterd

Dodajmy do startu uruchomienie demona lalek:

chkconfig – mistrz marionetek

Konfigurowanie serwera marionetkowego:
Zdefiniujmy katalog, w którym będą przechowywane pliki, które serwer marionetek będzie przesyłał do maszyn klienckich w manifestach danego typu pliku.

vim /etc/puppet/fileserver


ścieżka /etc/puppet/files
umożliwić *

mkdir /etc/puppet/files

chown -R marionetka:marionetka /etc/puppet/files

Stworzymy plik z dowolną treścią do wdrożenia i przetestowania na klientach

dotknij /etc/puppet/files/puppettesting

Zrestartujmy serwer marionetkowy:

Uruchom ponownie rcpuppetmasterd

Marionetka posługuje się własnym językiem opisu końcowego stanu systemu operacyjnego, za pomocą którego administrator systemu wskazuje, do jakiej postaci należy doprowadzić komponenty systemu operacyjnego, aby osiągnął on pożądany stan. Stan może oznaczać obecność określonego pliku, folderu, uruchomionych usług, zainstalowanych pakietów, aktualizacji i nie tylko. Wszystkie ustawienia stanu opisane są w plikach lub manifestach, które znajdują się w katalogu: /etc/puppet/manifests. Pliki te mają nazwy takie jak *.pp.

Stwórzmy najprostsze manifest:
/etc/puppet/manifests/1.file.pp:

plik("/tmp/puppettetesting":
źródło => "puppet:///files/puppettesting",
}

Aby użyć tego manifestu:
marionetka Apply 1.file.pp

Instalacja i konfiguracja klienta marionetkowego:

Zamek błyskawiczny w marionetce

Nadajmy użytkownikowi uprawnienia marionetkowe:

chown -R marionetka.puppet /var/lib/puppet/

Aby nawiązać połączenie z serwerem marionetkowym, klient marionetkowy wysyła żądanie potwierdzenia certyfikatu; po potwierdzeniu tego żądania na serwerze klient marionetkowy zacznie korzystać z przeznaczonych dla niego manifestów. Wyślemy prośbę o potwierdzenie certyfikatu:

Na serwerze możemy zobaczyć, jakie żądania potwierdzenia oczekują:

„klient marionetkowy.domena lokalna” (B5:12:69:63:DE:19:E9:75:32:2B:AA:74:06:F6:8E:8A)

Potwierdzamy:

puppetca --sign "klient-marionetkowy.domenalokalna"

Czas przyjrzeć się najprostszym przykładom tworzenia manifestów:
utwórz plik /etc/puppet/manifests/site.pp:

domyślny węzeł (
plik("/tmp/puppettetesting":
źródło => „puppet:///files/testowanie lalek”,
}
usługa("ntp":
upewnij się => działa,
włącz => prawda,
}
pakiet("htop":
upewnij się => zainstalowany,
}
}

domyślnie - dotyczy wszystkich klientów
plik — ta sekcja mówi o utworzeniu lub nadpisaniu pliku /tmp/puppettetesting, który znajduje się na serwerze w katalogu /etc/puppet/files
usługa: sprawdź, czy usługa jest uruchomiona, jeśli nie, uruchom ją, a także dodaj do uruchamiania
pakiet: sprawdź, czy na kliencie jest zainstalowany pakiet htop, a jeśli nie, zainstaluj go.

Aby to sprawdzić, uruchom na kliencie:

Jak widać na kliencie do startu dodano ntp, uruchomiono demona ntp, zainstalowano pakiet htop i skopiowano plik puppettetesting do katalogu /tmp/

info: Katalog buforowania dla puppet-client.localdomain
info: Stosowanie wersji konfiguracji „1370163660”
zauważ: / Etap [główny] // Węzeł [domyślny] / Usługa [ntp] / upewnij się: upewnij się, że zmieniono „zatrzymany” na „działa”
zauważ: / Etap [główny] // Węzeł [domyślny] / Pakiet [ htop ] / upewnij się: utworzono
uwaga: / Stage [główny] // Węzeł [domyślny] / Plik [ / tmp/ puppettesting] / upewnij się: zdefiniowano treść jako "(md5)f2171ac69ba86781bea2b7c95d1c8e67"
Uwaga: Gotowy katalog można uruchomić w 3,95 sekundy

W kolejnym artykule opiszę bardziej złożone przykłady tworzenia manifestów i interfejsu WWW marionetek-dashboardu.

Popularne typy zasobów Marionetka
cron- zarządzanie zadaniami cron
wykonawczy- uruchamianie skryptów i poleceń
plik- zarządzanie plikami
zasobnik plików- kopia zapasowa plików
grupa- zarządzanie grupą
gospodarz- zarządzanie wpisami w pliku /etc/hosts
interfejs- konfiguracja interfejsów sieciowych
uchwyt- montowanie systemów plików
notyfikować- wysłanie wiadomości do pliku dziennika Puppet
pakiet- zarządzanie pakietami
praca- zarządzanie usługami
sshkey- Zarządzanie kluczami SSH
czysty- usuwanie plików w zależności od warunków
użytkownik- zarządzanie użytkownikami
strefy- Zarządzanie strefą Solaris


Trochę poezji. Wydawać by się mogło, że ten artykuł powinien być punktem wyjścia dla całej serii, jednak grupą docelową są w dalszym ciągu bardziej doświadczeni użytkownicy produktów Open Source Puppet Labs, którym nie wystarczają poszczególne, słabo zintegrowane moduły z Puppet Forge. Jak w każdym przypadku „biblioteka kontra framework”, ceną do zapłacenia jest podążanie za światopoglądem autora zintegrowanego rozwiązania.

Trochę o tym, jak działa Puppet

Puppet to przede wszystkim specyficzny język służący do deklaratywnego określania końcowego stanu systemu. Dla porównania niezwykle odpowiedni jest plik GNU Makefile, w którym oprócz bezpośredniego opisu zależności można pobawić się maksymalnie.

Abstrakcja lalek jest mniej więcej taka ( łamanie schematów - zapomnij o wszystkim, co wiedziałeś o terminach programowania!).

  • Węzeł to zestaw konfiguracji dla konkretnego systemu docelowego. W rzeczywistości jest to szczególny przypadek klasy.
  • Klasa to zbiór logiki deklaratywnej zawarty w konfiguracji węzła lub innych klasach. Klasa nie ma instancji ani metod, ale ma parametry i zmienne zdefiniowane w ramach logiki. Tak naprawdę jest to raczej procedura, która może odziedziczyć inną procedurę poprzez proste dodanie kodu i posiadanie niezbyt banalnego zakresu zmiennych.
  • Typ- ale to bardziej przypomina klasę klasyczną - zakłada instancje z nazwą i ściśle określonymi parametrami, ale nic więcej. Konkretną implementację typu można zapisać jako skrypt Puppet za pomocą narzędzia Definiowanie, które tworzy instancje innych typów, lub jako rozszerzenie Ruby w odrobinie wyobraźni.
  • Ratunek- są to właściwie nazwane instancje typów. Każda nazwa zasobu jest unikatowa w ramach określonego typu w konfiguracji węzła (katalogu).
  • Zmienne- cóż, krótko mówiąc, są to stałe... Przed Puppet 4 było jeszcze gorzej z ich zakresem. Teraz jest to wystarczające: do użycia spoza lokalizacji definicji należy podać w pełni kwalifikowany identyfikator, z wyjątkiem przypadku dziedziczenia klas.
Puppet może być używany do wdrażania lokalnego bez sieci i powiązanej infrastruktury. Można tego używać do tworzenia obrazów kontenerów. Istnieje nawet cały ruch opowiadający się za porzuceniem scentralizowanego serwera.

W ideologicznie poprawny sposób infrastruktura Puppet składa się z agenta – uprzywilejowanej usługi w systemie docelowym – oraz serwera, który na żądanie agentów dystrybuuje cenne instrukcje w postaci deklaratywnych katalogów zasobów. Bezpieczeństwo realizowane jest na poziomie infrastruktury klucza publicznego prywatnego (X.509). Mówiąc najprościej, te same mechanizmy co w HTTPS, ale z własnym CA i obowiązkową weryfikacją certyfikatu klienta.

W uproszczonej formie procedura wdrażania wygląda mniej więcej tak:

  1. Przetwarzanie poprzez TLS i X.509 (nawiązanie połączenia, aktualizacja list CRL, sprawdzenie ograniczeń certyfikatów itp.)
  2. Agent otrzymuje z serwera generatory faktów wraz z buforowaniem i całą resztą (dokładniej wszystko jest pobierane z folderów lib/ w modułach). Dodanie własnego skryptu Ruby w celu zebrania interesujących informacji nie jest trudne.
  3. Agent zbiera fakty na temat systemu docelowego i przesyła je do serwera. Wszystkie fakty można łatwo przeglądać ręcznie za pomocą wywołania faktów marionetkowych. Fakty te są dostępne jako zmienne globalne.
  4. Serwer kompiluje katalog zasobów i wysyła go do agenta. Pod tym kryje się cała warstwa różnych koncepcji.
  5. Agent pobiera wszystko, co niezbędne z serwera i doprowadza system do określonej postaci. Agent sam nie wie, co zrobić z zasobami; opiera się na implementacji dostawców (w tłumaczeniu semantycznym będzie to „realizator”, a nie dostawca) określonych typów zasobów. Niektórzy dostawcy są standardowi i znajdują się w pakietach Puppet, natomiast reszta jest pobierana z modułów.
Aby cieszyć się wszystkimi pysznościami, dostępne są dodatkowe bułeczki w postaci:
  • Moduł- zbiór deklaratywnych skryptów Puppet, rozszerzeń Ruby dla Puppet, plików, szablonów plików, danych Hiera i wielu innych. Bardziej poprawnym terminem byłoby „pakiet”.
  • Środowisko- zestaw skryptów, modułów i danych Hiera. W miarę jak infrastruktura stawała się coraz bardziej złożona, nieuchronnie konieczne stało się dalsze podzielenie konfiguracji niż standardowy podział według węzłów. Zasadniczo jest to wymagane w przypadku pilotażowych innowacji i banalnej kontroli dostępu (kiedy nie wszyscy administratorzy mają dostęp do wszystkich węzłów infrastruktury IT).
  • Hiera- hierarchiczna baza danych. To sformułowanie może być bardzo zastraszające. Prawdopodobnie dlatego zostało to zmienione w dokumentacji późniejszych wersji. Tak naprawdę jest to niezwykle prosty i wygodny mechanizm ściągania konfiguracji z plików YAML lub JSON. Hierarchia to możliwość określenia kolejności odczytu wielu plików konfiguracyjnych - tj. hierarchia/priorytet tych plików.
    • Oprócz pobierania danych z wywołań funkcji, Puppet pobiera domyślne parametry klasy, co jest główną atrakcją.
    • Oczywiście Hiera obsługuje interpolację faktów, a nawet wywoływanie funkcji specjalnych.
    • W Puppet 4.3 ponownie zaimplementowaliśmy tę samą funkcjonalność, aby obsługiwać nie tylko globalną bazę danych, ale także lokalną dla Środowiska i Modułu, chociaż autor znalazł już kilka problemów w ich implementacji (PUP-5983, PUP-5952 i PUP -5899), które zostały natychmiast naprawione przez Puppet Labs.
    • Obsługiwanych jest kilka strategii wyodrębniania wartości ze wszystkich plików w hierarchii:
      • First - zwracana jest pierwsza wartość znaleziona według priorytetu
      • unikalny - zbiera wszystkie wartości w jednowymiarową tablicę i usuwa duplikaty
      • hash - łączy wszystkie znalezione skróty YAML. Duplikaty kluczy są wybierane według priorytetu.
      • deep jest zasadniczo rekursywną wersją skrótu
    • Piękno polega na tym, że strategię próbkowania można ustawić wywołując funkcję lookup(), ponieważ oraz w dowolnym pliku hierarchii poprzez specjalny klucz lookup_options, który jest aktywnie używany w module cfnetwork.
  • PuppetDB- zasadniczo warstwa logiki biznesowej wokół relacyjnej bazy danych (PostgreSQL), która pozwala na zapisywanie raportów dotyczących faktów i przeprowadzonych wdrożeń oraz eksportowanie zasobów w celu późniejszego importu do katalogów na innych węzłach lub selekcji za pomocą specjalnych funkcji. Dostępny jest także interfejs sieciowy w postaci Puppet Dashboard.
  • Infrastruktura X.509- wspomniana już infrastruktura certyfikatów, która jest niezwykle wygodna w użyciu dla innych usług, bez konieczności zarządzania oddzielną infrastrukturą.
  • MZbiorowy- zdaje się przydatna rzecz do uruchamiania zadań na farmie serwerów na podstawie zdarzeń, jednak autor ma pewną nieufność co do bezpieczeństwa konkretnego rozwiązania.
  • Kuźnia Lalek- otwarta platforma do publikowania i pobierania Modułów.
  • kilka innych funkcji w postaci kontroli urządzenia zewnętrzne takich jak sprzęt Cisco i wdrażanie na platformie „bare metal”, ale to inna historia

Uwagi dotyczące bezpieczeństwa i dostępności

Musisz zrozumieć, że Puppet Server staje się wrażliwym punktem całej infrastruktury IT, ponieważ... określa ostateczną konfigurację wszystkich systemów. W szczególnych przypadkach sensowne jest wykonanie separacji – osobnego serwera dla krytycznych elementów infrastruktury z niezwykle ograniczony dostęp I aktualizacja ręczna a drugi do wszystkiego innego.

Dostępność Puppet Server determinuje możliwość zarządzania całą infrastrukturą. Rozsądne jest hostowanie Puppet Server na maszynie wirtualnej w bardziej niezawodnej i szybko odtwarzalnej chmurze innej firmy niż własne możliwości. Lub powinieneś zainstalować kilka serwerów.

W żadnym wypadku nie powinieneś instalować innych usług w systemie, w którym zostanie wdrożony Puppet Server z dzwonkami i gwizdkami. Wirtualizacja i konteneryzacja mogą Ci pomóc.

Multi-master (kilka oddzielnych serwerów marionetkowych)

  • W w tym przypadku tylko jeden serwer pełni funkcję CA (Certificate Authority) - jego niedostępność powoduje, że nie ma możliwości dodawania nowych węzłów.
    • Puppet umożliwia korzystanie z infrastruktury X.509 innej firmy, jeśli wbudowana nie jest zadowalająca.
  • Cała konfiguracja (Środowisko) musi być przechowywana w systemie kontroli wersji i wdrożona na każdym serwerze jednocześnie.
  • Jedyne, co łączy, to baza danych PostgreSQL, której organizacja wysokiej dostępności wykracza poza zakres tego artykułu.
  • Moduł cfpuppetserver obsługuje zarówno instalacje serwerów podstawowych (z CA), jak i serwerów pomocniczych.

Co istotne zmieniło się od starszych wersji

Producent posiada pełny opis.
  • Wszystkie usługi zostały przeniesione do JVM, JRuby i Jetty. Pomimo oczywistych zalet integracji istnieją również wady związane ze zużyciem pamięci.
  • Dodano funkcje Lambda do przetwarzania kolekcji - teraz nie ma potrzeby wycinania kul w Ruby ani perwersji poprzez create_resources()
  • Pojawiło się narzędzie do obróbki szablonów EPP - w zasadzie ten sam ERB, ale z Puppet DSL zamiast Ruby,
  • Domyślna struktura katalogów plików konfiguracyjnych uległa znaczącym zmianom
  • Dodano obsługę dostawców danych dla środowisk i modułów (hacki nie są już wymagane).
  • Bagatelizowanie roli globalnej Hiery. Nowym i powiązanym poleceniem jest wyszukiwanie marionetkowe.

Instalacja

Proces ten jest dość prymitywny, ale wymaga wykonania określonej sekwencji kroków. Ponieważ robienie tego ręcznie jest niewdzięcznym zadaniem, autor nauczy Cię czegoś złego, a mianowicie pobrania niezrozumiałych skryptów z Internetu i uruchomienia ich w systemie jako root.

Trzy główne komponenty serwera to sam serwer Puppet, PuppetDB i PostgreSQL. Można je wszystkie zmieścić w jednym węźle lub podzielić na dwa lub trzy systemy. Puppet Server i Puppet DB można uruchamiać wiele razy, ale PostgeSQL jest pojedynczym punktem awarii. Istnieją różne podejścia do replikacji i klastrowania PostgeSQL. Wygodnym podejściem w przypadku serwerów głównych i pomocniczych byłoby Master + Read-Only Slave, które jest obsługiwane w samej PuppetDB jako główny węzeł bazy danych tylko do odczytu, ale automatyzujący takie. konfiguracja wymaga czasu i dlatego nie jest jeszcze dostępna w module cfpuppetserver.

Sama konfiguracja może być po prostu przechowywana przynajmniej na system plików razem z Puppet Server, ale to jak pisanie skryptów na produkcyjnym serwerze WWW. Najbardziej odpowiednim rozwiązaniem jest repozytorium git. Narzędzie r10k może pobrać wszystkie gałęzie repozytorium i wdrożyć je na serwerze Puppet Server jako oddzielne środowiska. r10k dość słabo radzi sobie z wyciąganiem zależności, więc na wierzchu używana jest bibliotekarka-puppet. Warto od razu zaznaczyć, że głównym kanonicznym środowiskiem lalek jest „produkcja”. Dlatego repozytorium konfiguracji powinno używać gałęzi o nazwie „production”, a nie „master”.

Wymagania systemowe

Sprzęt opisuje sam producent. Moduł cfpuppetserver obsługuje obecnie tylko Debian Jessie+ i Ubuntu Trusty+.

Konfiguracja w Gicie

Dla samego r10k lokalizacja repozytorium nie ma większego znaczenia - najważniejsza jest jego dostępność. Na przykład do celów testowych repozytorium może znajdować się w tym samym systemie i można do niego uzyskać dostęp za pośrednictwem file:// . Dobrym miejscem na rozpoczęcie jest przykład konfiguracji codingfuture/puppet-exampleenv.
  1. Klonowanie repozytorium: git clone https://github.com/codingfuture/puppet-exampleenv my-puppet-conf && cd my-puppet-conf
  2. Ogólne ustawienia dostępu administratora ustalamy korzystając ze wskazówek w komentarzach:
    • $EDITOR dane/common.yaml
  3. Stwórzmy konfigurację węzła:
    • $MY_DOMAIN — root nazwa domeny(np. przykład.org)
    • $HOST_NAME — nazwa hosta klienta bez domeny
    • mkdir dane/$MY_DOMAIN
    • cp data/example.com/puppet.yaml data/$(MOJA_DOMENA)/puppet.yaml
    • $EDITOR nano -w data/$(MY_DOMAIN)/puppet.yaml - konfiguracja węzła z serwerem Puppet zgodnie z sugestiami w komentarzach
    • cp data/example.com/host.yaml data/$(MOJA_DOMENA)/$(NAZWA_HOSTU).yaml
    • $EDITOR nano -w data/$(MY_DOMAIN)/$(HOST_NAME).yaml - ustawienie dowolnego węzła na podstawie sugestii w komentarzach
  4. Wysyłamy na nasz własny serwer Git lub udostępniamy go lokalnie na węźle z serwerem Puppet poprzez rsync lub scp. Lokalne repozytorium jest wygodnym krokiem pośrednim, dopóki serwer Git nie zostanie wdrożony z poziomu samego Puppet. W pewnym sensie przypomina to składanie kompilatora w kilku etapach.

Instalacja od zera na czystym systemie

Moduł cfpuppetserver pozwala zainstalować wszystko przy użyciu samego Puppet, ale w ramach pierwszej instalacji podstawowe operacje powielane przez skrypt Bash.

W systemie docelowym:

  1. Pobierz skrypt instalacyjny: wget https://raw.githubusercontent.com/codingfuture/puppet-cfpuppetserver/master/setup_puppetserver.sh
  2. Przeglądamy skrypt i marszczymy brwi: less setup_puppetserver.sh
  3. Uruchom: bash setup_puppetserver.sh marionetka.$(MY_DOMAIN) .
    • Przykład ze zdalnym repozytorium: bash setup_puppetserver.sh ssh:// [e-mail chroniony]/puppet-conf
    • Przykład z lokalnym: bash setup_puppetserver.sh file:///root/puppetconf/
  4. Widzimy, jak system się psuje i nie instaluje wszystkiego bardzo szybko.
  5. Jeśli repozytorium jest zdalne:
    • Utwórz klucz SSH dla roota: ssh-keygen -t rsa -b 2048
    • Rejestrujemy klucz publiczny /root/.ssh/id_rsa.pub na zdalnym serwerze Git...
    • ... i skonfiguruj tam hak Git, wywołując następującą komendę: /usr/bin/ssh -T wdrażapuppet@puppet.$(MOJA_DOMENA) ./puppetdeploy.sh
  6. Rozpoczynamy wdrażanie konfiguracji ręcznie: /etc/puppetlabs/deploy.sh
  7. Spróbujmy jak to działa na samym serwerze: /opt/puppetlabs/bin/puppet agent --test
  8. Sprawdź swoją sieć, filtr sieciowy i ustawienia dostępu SSH

Dodawanie zarządzanych węzłów

  1. Pełna nazwa serwera Puppet musi być dostępna poprzez DNS na zarządzanym hoście lub zakodowana na stałe w pliku /etc/hosts.
    • Przykład: echo "128.1.1.1 marionetka.example.com" >> /etc/hosts
  2. W węźle z serwerem Puppet uruchom następujący skrypt /root/genclientinit.sh $(NAZWA_HOSTU).$(MY_DOMAIN) .
  3. Skopiuj cały wynik i wklej go do wiersza poleceń w systemie docelowym.
  4. Czekamy na koniec wykonywania i uruchamiamy /opt/puppetlabs/bin/puppet agent --test . Przy pierwszym uruchomieniu zostanie wygenerowane żądanie podpisania certyfikatu.
  5. Udajemy się do węzła Puppet Server w celu podpisania certyfikatu.
    • lista certyfikatów marionetkowych - sprawdzamy podpis certyfikatu pod kątem dodatkowej paranoi.
    • marionetkowy znak certyfikatu $(HOST_NAME).$(MY_DOMAIN) - właściwie to my podpisujemy certyfikat.
  6. Wracamy do zarządzanego węzła i ponownie uruchamiamy: /opt/puppetlabs/bin/puppet agent --test`. Wymusi to rozpoczęcie procedury wdrażania.
  7. Czekamy na zakończenie wdrożenia za pośrednictwem Puppet Agent.
  8. To wszystko, masz gotową minimalną infrastrukturę Puppet!

Przykładowe dane wyjściowe z pliku /root/genclientinit.sh

grzmotnąć</etc/cflocation fi jeśli test ! -z ""; następnie echo -n >/etc/cflocationpool fi, jeśli test! -z "\$http_proxy"; następnie eksportuj http_proxy eksport https_proxy="\$http_proxy" eksport HTTP_PROXY="\$http_proxy" eksport HTTPS_PROXY="\$http_proxy" fi echo host.example.com > /etc/hostname nazwa hosta host.example.com if ! które wydanie lsb | Czytać; następnie apt-get install lsb-release fi nazwa kodowa=\$(lsb_release -cs) if test -z "\$nazwa kodowa"; następnie echo „Nie udało się wykryć poprawnej nazwy kodowej” zakończ 1 fi wget https://apt.puppetlabs.com/puppetlabs-release-pc1-\$(nazwa kodowa).deb dpkg -i puppetlabs-release-pc1-\$(nazwa kodowa) .deb mkdir -p /etc/puppetlabs/puppet cat > /etc/puppetlabs/puppet/puppet.conf<marionetkowy znak certyfikatu host.example.com” echo „Użyj CTRL+C, aby zatrzymać cykl, jeśli zakończy się niepowodzeniem z różnych powodów” sen 5 wykonany EOT

Opis modułu

Pełna lista początkowych parametrów skryptu instalacyjnego Bash

~# ./setup_puppetserver.sh Użycie: ./setup_puppetserver.sh [ [ [ [] ] ] ]
  • r10k_repo_url - URI repozytorium Git
  • certname - w pełni kwalifikowana nazwa domeny hosta
  • cflocation - inicjalizacja faktu cf_location
  • cflocationpool - inicjalizacja faktu cf_location_pool
  • http_proxy - serwer proxy dla żądań HTTP i HTTPS

Pełna lista parametrów Bash dla skryptu inicjującego klienta Puppet

~# /root/genclientinit.sh Użycie: ./genclientinit.sh [ [ []]]
Znaczenie parametrów jest takie samo jak w poprzednim skrypcie.

klasa cfpuppetserver

  • wdrożyćuser = "deploypuppet" - nazwa użytkownika do automatycznego wdrażania aktualizacji konfiguracji
  • wdrożyćuser_auth_keys = undef - lista kluczy dla $deployuser
  • repo_url = undef - URI repozytorium (przykład: ssh://user@host/repo lub file:///jakaś/ścieżka)
  • puppetserver = true — czy zainstalować komponent Puppet Server w tym węźle
  • puppetdb = true — czy zainstalować komponent PuppetDB w tym węźle
  • puppetdb_port = 8081 - port dla PuppetDB
  • setup_postgresql = true - czy zainstalować komponent PostgreSQL na tym węźle (tylko jeśli włączona jest instalacja PuppetDB)
  • service_face = "any" - nazwa zasobu cfnetwork::iface służącego do akceptowania połączeń przychodzących
  • puppetserver_mem = auto - RAM dla serwera Puppet w megabajtach (minimum 192 MB)
  • puppetdb_mem = auto - RAM dla PuppetDB w megabajtach (minimum 192MB)
  • postgresql_mem = auto - RAM dla PostgreSQL w megabajtach (minimum 128MB)

klasa cfpuppetserver::puppetdb

  • postgresql_host = "localhost" - adres bazy danych
  • postgresql_listen = $postgresql_host - wartość przechodzi bezpośrednio do dyrektywy Listen_addresses PostgreSQL
  • postgresql_port = 5432 - port bazy danych
  • postgresql_user = "puppetdb" - użytkownik PuppetDB w bazie danych
  • postgresql_pass = "puppetdb" - hasło użytkownika PuppetDB w bazie danych
  • postgresql_ssl = false - włącz szyfrowanie połączeń w oparciu o certyfikaty Puppet PKI

klasa cfpuppetserver::puppetserver

  • autosign = false - NIE NALEŻY używać w środowisku bojowym, z wyjątkiem być może strefy DMZ. Istnieje wyłącznie do automatyzacji testów.
  • global_hiera_config = "cfpuppetserver/hiera.yaml" - ścieżka do domyślnego pliku konfiguracyjnego Hiera zgodnie z kanonami Puppet (pierwszy składnik to nazwa modułu, reszta to ścieżka pod plikami/folderem w module)

Możesz pomóc i przekazać część środków na rozwój strony



Siergiej Jaremczuk

Scentralizowana konfiguracja systemów UNIX przy użyciu Puppet

Zarządzanie dużą liczbą systemów UNIX nie może być nazwane wygodnym. Aby zmienić jeden parametr, administrator musi skontaktować się z każdą maszyną; skrypty mogą pomóc tylko częściowo i nie we wszystkich sytuacjach.

Trzeba przyznać, że administratorzy sieci Windows są nadal w korzystniejszej sytuacji. Wystarczy zmienić ustawienia profilu grupowego, a po chwili wszystkie komputery w sieci, także te z niedawno zainstalowanym systemem operacyjnym, „dowiedzą się” o innowacji, jeśli oczywiście ich ona dotyczy. Patrząc wstecz na długi okres rozwoju UNIX-a, widać, że nic takiego nigdy się nie przyjęło. Istnieją rozwiązania takie jak kickstart, które pomagają w początkowej instalacji systemu operacyjnego, ale dalszy rozwój będzie wymagał znacznego wysiłku. Rozwiązania komercyjne, takie jak BladeLogic i OpsWare, tylko częściowo rozwiązują problem automatyzacji ustawień; ich główną zaletą jest obecność interfejsu graficznego, na który mogą sobie pozwolić tylko duże organizacje. Istnieją oczywiście projekty, które oferują darmowe rozwiązania, ale przez cały okres swojego istnienia nie udało im się stworzyć dużej społeczności. Przykładowo Cfengine nie jest zbyt popularny wśród administratorów, chociaż oprócz Linuksa można go używać w *BSD, Windows i Mac OS X. Może to wynikać ze względnej złożoności tworzenia konfiguracji. Opisując zadania, należy wziąć pod uwagę charakterystykę każdego konkretnego systemu i ręcznie kontrolować kolejność działań podczas wykonywania poleceń. Oznacza to, że administrator musi pamiętać, że dla niektórych systemów należy napisać adduser, dla innych - useradd, wziąć pod uwagę lokalizację plików w różnych systemach i tak dalej. Komplikuje to proces pisania poleceń o rząd wielkości; bardzo trudno jest stworzyć poprawną konfigurację w locie, a odczytanie utworzonych konfiguracji po pewnym czasie jest prawie niemożliwe. Pomimo licencji GPL, Cfengine jest w zasadzie projektem jednoosobowym, który kontroluje wszystkie zmiany i nie jest zbytnio zainteresowany budowaniem otwartego społeczeństwa. W rezultacie możliwości Cfengine są dla programisty całkiem zadowalające, ale dla innych administratorów jest to raczej dodatkowy ból głowy. Aby ulepszyć Cfengine, zewnętrzni programiści stworzyli różne dodatki, co często tylko pogarszało sytuację. Autor kilku takich modułów dla Cfengine, Luke Kanies, ostatecznie zdecydował się opracować podobne narzędzie, ale pozbawione wielu wad Cfengine.

Funkcje lalek

Puppet, podobnie jak Cfengine, jest systemem klient-serwer, który używa języka deklaratywnego do opisu zadań i bibliotek do ich realizacji. Klienci okresowo (domyślnie co 30 minut) łączą się z serwerem centralnym i otrzymują najnowszą konfigurację. Jeżeli otrzymane ustawienia nie będą zgodne ze stanem systemu, zostaną one wykonane, a w razie potrzeby wysłany zostanie raport z wykonanych operacji na serwer. Serwer wiadomości może zapisać je w syslog lub pliku, utworzyć wykres RRD i wysłać go na podany adres e-mail. Dodatkowe warstwy abstrakcji transakcyjnej i zasobów zapewniają maksymalną kompatybilność z istniejącymi ustawieniami i aplikacjami, pozwalając skupić się na obiektach systemowych bez martwienia się o różnice w implementacji i opisie szczegółowych poleceń i formatów plików. Administrator operuje tylko typem obiektu, Puppet zajmuje się resztą. Zatem typ pakietu zna 17 systemów pakietów; wymagany zostanie automatycznie rozpoznany na podstawie informacji o wersji dystrybucji lub systemu, chociaż w razie potrzeby można ustawić menedżera pakietów na siłę.

W przeciwieństwie do skryptów, których często nie da się użyć w innych systemach, konfiguracje Puppet napisane przez zewnętrznych administratorów będą działać w każdej innej sieci przeważnie bez problemów. W Puppet CookBook znajdziesz już trzy tuziny gotowych przepisów. Obecnie Puppet oficjalnie obsługuje następujące systemy operacyjne i usługi: Debian, RedHat/Fedora, Solaris, SUSE, CentOS, Mac OS X, OpenBSD, Gentoo i MySQL, LDAP.

Język lalek

Aby pójść dalej, musisz najpierw zrozumieć podstawowe elementy i możliwości języka. Język jest jedną z mocnych stron Puppet. Opisuje zasoby, którymi administrator planuje zarządzać oraz działania. W przeciwieństwie do większości podobnych rozwiązań, Puppet pozwala językowi uprościć dostęp do wszystkich podobnych zasobów w dowolnym systemie w heterogenicznym środowisku. Opis zasobu zazwyczaj składa się z nazwy, typu i atrybutów. Na przykład wskażmy plik /etc/passwd i ustawmy jego atrybuty:

plik("/etc/passwd":

Właściciel => root,

Grupa => korzeń,

Tryb => 644,

Teraz klienci łączący się z serwerem skopiują plik /etc/passwd i ustawią określone atrybuty. W jednej regule możesz zdefiniować wiele zasobów, oddzielając je średnikiem. Co jednak w sytuacji, gdy plik konfiguracyjny używany na serwerze różni się od pliku konfiguracyjnego klienta lub w ogóle nie jest używany? Na przykład taka sytuacja może wystąpić podczas konfigurowania połączeń VPN. W takim przypadku należy wskazać plik za pomocą dyrektywy źródłowej. Opcje są tutaj dwie; możesz jak zwykle określić ścieżkę do innego pliku, a także skorzystać z dwóch obsługiwanych protokołów URI: pliku i marionetki. W pierwszym przypadku wykorzystywane jest łącze do zewnętrznego serwera NFS, w drugim przypadku na serwerze Puppet uruchamiana jest usługa przypominająca NFS, która eksportuje zasoby. W tym drugim przypadku domyślna ścieżka jest względna względem katalogu głównego marionetki – /etc/puppet. Oznacza to, że link puppet://server.domain.com/config/sshd_config będzie odpowiadał plikowi /etc/puppet/config/sshd_config. Możesz zastąpić ten katalog za pomocą dyrektywy filebucket, chociaż bardziej poprawne jest użycie sekcji o tej samej nazwie w pliku /etc/puppet/fileserver.conf. W takim przypadku możesz ograniczyć dostęp do usługi tylko do wybranych adresów. Opiszmy na przykład sekcję konfiguracji:

Ścieżka /var/puppet/config

Zezwalaj na *.domena.com

Zezwól na 127.0.0.1

Zezwól na 192.168.0.*

Zezwól na 192.168.1.0/24

Zabroń *.wireless.domain.com

Następnie odwołujemy się do tej sekcji, opisując zasób:

źródło => "puppet://server.domain.com/config/sshd_config"

Przed dwukropkiem znajduje się nazwa zasobu. W większości proste przypadki Możesz po prostu podać pełną ścieżkę do pliku jako nazwę. W bardziej złożonych konfiguracjach lepiej jest użyć aliasu lub zmiennych. Alias ​​ustawia się za pomocą dyrektywy alias:

plik("/etc/passwd":

Alias ​​=> hasło

Inna opcja tworzenia aliasu jest dobra, gdy masz do czynienia z różnymi systemami operacyjnymi. Na przykład utwórzmy zasób opisujący plik sshd_config:

plik (sshdconfig:

Nazwa => $system operacyjny ? (

Solaris => "/usr/local/etc/ssh/sshd_config",

Domyślnie => „/etc/ssh/sshd_config”

W tym przykładzie stajemy przed wyborem. Plik dla Solarisa jest określony osobno, dla wszystkich pozostałych zostanie wybrany plik /etc/ssh/sshd_config. Teraz dostęp do tego zasobu można uzyskać jako sshdconfig, w zależności od systemu operacyjnego zostanie wybrana żądana ścieżka. Na przykład zwróćmy uwagę, że jeśli demon sshd jest uruchomiony i odbiera nowy plik, powinieneś zrestartować usługę:

usługa (sshd:

Upewnij się => prawda,

Subskrybuj => Plik

Zmienne są często używane podczas pracy z danymi użytkownika. Na przykład opisujemy lokalizację katalogów domowych użytkowników:

$homeroot = "/dom"

Teraz dostęp do plików konkretnego użytkownika można uzyskać w następujący sposób:

$(katalog główny)/$nazwa

Parametr $name zostanie wypełniony nazwą konta użytkownika. W niektórych przypadkach wygodnie jest zdefiniować wartość domyślną dla jakiegoś typu. Na przykład dla typu exec bardzo często określa się katalogi, w których powinien on szukać pliku wykonywalnego:

Exec ( ścieżka => "/usr/bin:/bin:/usr/sbin:/sbin" )

Jeśli chcesz wskazać kilka zagnieżdżonych plików i katalogów, możesz użyć parametru recurse:

plik("/etc/apache2/conf.d":

Źródło => "puppet:// puppet://server.domain.com/config/apache/conf.d",

Powtórzenie => „prawda”

Wiele zasobów można łączyć w klasy lub definicje. Klasy stanowią pełny opis systemu lub usługi i są używane oddzielnie:

klasa Linuksa (

Plik (

"/etc/passwd": właściciel => root, grupa => root, tryb => 644;

„/etc/shadow”: właściciel => root, grupa => root, tryb => 440

Podobnie jak w językach obiektowych, klasy można nadpisywać. Na przykład we FreeBSD właścicielem grupy tych plików jest koło. Dlatego, aby nie przepisywać całkowicie zasobu, utwórzmy nowa klasa freebsd, który odziedziczy klasę Linuksa:

klasa freebsd dziedziczy Linuksa (

Plik["/etc/passwd"] ( grupa => koło );

Plik["/etc/shadow"] ( grupa => koło )

Dla wygody można umieścić wszystkie klasy osobny plik, które muszą być dołączone do dyrektywy include. Definicje mogą przyjmować wiele parametrów jako argumenty, ale nie obsługują dziedziczenia i są używane, gdy trzeba opisać obiekty wielokrotnego użytku. Przykładowo zdefiniujmy katalog domowy użytkowników i polecenia potrzebne do założenia nowego konta:

zdefiniuj katalog_home_użytkownika ($group, $fullname, $ingroups) (

Użytkownik("$nazwa":

Zapewnij => obecny,

Komentarz => "$pełne imię",

Gid => "$grupa",

Grupy => $wgrupach,

Członkostwo => minimalne,

Powłoka => "/bin/bash",

Strona główna => "/home/$nazwa",

Wymagaj => Grupa[$grupa],

Exec("$nazwakatalog domowy":

Command => "/bin/cp -R /etc/skel /home/$nazwa; /bin/chown -R $nazwa:$grupa /home/$nazwa",

Tworzy => "/home/$nazwa",

Wymagaj => Użytkownik[$nazwa],

Teraz utwórz nowy konto, po prostu skontaktuj się z user_homedir:

user_homedir("sergej":

Grupa => "sergej",

Imię i nazwisko => "Siergiej Jaremczuk",

Grupy dyskusyjne => ["media", "admin]

Istnieją osobne opisy węzłów obsługujących dziedziczenie, a także klas. Gdy klient połączy się z serwerem Puppet, przeszukana zostanie odpowiednia sekcja węzła i zostaną podane ustawienia specyficzne tylko dla tego komputera. Aby opisać wszystkie inne systemy, możesz użyć wartości domyślnych węzła. Opis wszystkich typów znajduje się w dokumencie „Odniesienie do typu”, z którym w każdym przypadku należy się zapoznać, przynajmniej w celu zrozumienia wszystkich możliwości języka Puppet. Różne typy pozwolić ci wystąpić określone polecenia, w tym po spełnieniu określonych warunków (na przykład zmiana pliku konfiguracyjnego), pracy z cronem, poświadczeniami i grupami użytkowników, komputerami, montowaniem zasobów, uruchamianiem i zatrzymywaniem usług, instalowaniem, aktualizowaniem i usuwaniem pakietów, pracą z kluczami SSH, strefami Solaris i tak dalej. W ten sposób możesz łatwo wymusić aktualizację listy pakietów w dystrybucjach za pomocą apt codziennie od 2 do 4 godzin:

harmonogram (codziennie:

Okres => codziennie,

Zasięg =>

exec("/usr/bin/apt-get update":

Harmonogram => codziennie

Aktualizacja za ten okres zostanie przeprowadzona przez każdy system tylko raz, po czym zadanie zostanie uznane za zakończone i usunięte z komputera klienckiego. Język Puppet obsługuje inne znane struktury: warunki, funkcje, tablice, komentarze i tym podobne.

Instalacja Marionetki

Puppet wymaga Ruby (wersja 1.8.1 i wyższa) z obsługą OpenSSL i bibliotekami XMLRPC, a także biblioteką Faster. Repozytorium Ubuntu 7.04 użyte do instalacji testowej zawiera już pakiet szczeniaka:

$ sudo marionetka wyszukiwania apt-cache

~$ Ruby -rxmlrpc/client -e "stawia:tak"

Tak

Jeśli nie zostaną wyświetlone żadne błędy, oznacza to, że wszystko, czego potrzebujesz, jest już uwzględnione. Pliki opisujące pożądaną konfigurację systemów nazywane są manifestami w terminologii Puppet. Po uruchomieniu demon próbuje odczytać plik /etc/puppet/manifests/site.pp; jeśli go brakuje, wyświetla komunikat ostrzegawczy. Podczas testowania możesz powiedzieć demonowi, aby działał w trybie autonomicznym, który nie wymaga manifestu:

$ sudo /usr/bin/puppetmasterd --nonodes

Jeśli zajdzie taka potrzeba, do site.pp możesz podłączyć inne pliki, np. z opisami klas. W przypadku uruchomienia testowego w tym pliku możesz wprowadzić najprostsze instrukcje.

klasa sudo (

Plik("/etc/sudoers":

Właściciel => root,

Grupa => korzeń,

Tryb => 440,

domyślny węzeł (

Dołącz sudo

Wszystkie pliki konfiguracyjne, zarówno serwera, jak i klienta, znajdują się w /etc/puppet. Plik fileserver.conf, o którym już mówiliśmy, jest opcjonalny i używany tylko wtedy, gdy Puppet będzie działał również jako serwer plików. W systemie Ubuntu ten plik eksportuje podkatalog /etc/puppet/files. Podkatalog ssl zawiera certyfikaty i klucze, które będą używane do szyfrowania podczas łączenia klientów. Klucze są tworzone automatycznie przy pierwszym uruchomieniu puppetmasterd; możesz je utworzyć ręcznie za pomocą polecenia:

$ sudo /usr/bin/puppetmasterd --mkusers

Pliki puppetd.conf i puppetmasterd.conf są podobne. Wskazują niektóre parametry działania demonów na systemie klienckim i serwerze. Plik klienta różni się jedynie obecnością parametr serwera, wskazując na komputer z uruchomionym puppetmasterd:

serwer = grinder.com

logdir = /var/log/puppet

vardir = /var/lib/puppet

rundir = /var/uruchom

# wyślij raport na serwer

raport = prawda

Aby uniknąć wpisywania wszystkiego ręcznie, możesz utworzyć szablon za pomocą samego puppetd:

$ puppetd --genconfig > /etc/puppet/puppetd.conf

Podobnie możesz utworzyć site.pp na serwerze:

$ puppetd --genmanifest > /etc/puppet/manifests/site.pp

Kolejny plik tagmail.conf pozwala określić adresy e-mail, na które będą wysyłane raporty. W najprostszym przypadku możesz użyć jednej linii:

Wszystko: [e-mail chroniony]

Pliki konfiguracyjne nie wystarczą, aby klient mógł połączyć się z serwerem. Aby to zrobić, musisz również podpisać certyfikaty.

Najpierw, aby serwer wiedział o nowym komputerze, wpisz w systemie klienckim komendę:

$ Sudo puppetd --server grinder.com --waitforcert 60 –test

Zapora sieciowa musi umożliwiać połączenia na porcie 8140.

Na serwerze otrzymujemy listę certyfikatów, które należy podpisać:

$ sudo marionetka – lista

nomad.grinder.com

I podpisz certyfikat klienta:

$ sudo puppetca – podpisz nomad.grinder.com

Teraz klient może swobodnie łączyć się z serwerem i odbierać ustawienia.

Niestety nie sposób w artykule pokazać wszystkich możliwości Puppeta. Ale jak widać, jest to funkcjonalne i elastyczne narzędzie, które pozwala rozwiązać większość problemów związanych z jednoczesnym administrowaniem dużą liczbą systemów. A co najważniejsze, projektowi udało się zgromadzić małą, ale stale rosnącą społeczność. Miejmy zatem nadzieję, że dobry pomysł nie pozwoli umrzeć lub odejść na bok.

Powodzenia!

  1. Strona projektu BladeLogic – http://www.bladelogic.com.
  2. Strona internetowa projektu OpsWare to http://www.opsware.com.
  3. Strona internetowa projektu Cfengine to http://www.cfengine.org.
  4. Strona internetowa projektu Puppet to http://reductivelabs.com/projects/puppet.
  5. Książka kucharska dla lalek — http://www.reductivelabs.com/trac/puppet/tagspuppet%2Crecipe.
  6. Szybsza biblioteka –

© 2024 ermake.ru - O naprawie komputerów PC - Portal informacyjny