Chef: Korrekturlesen

This commit is contained in:
Jörg Thalheim 2014-04-06 02:54:54 +02:00
parent 9acc0bd116
commit 39c78d41fd
6 changed files with 429 additions and 404 deletions

View File

@ -4,147 +4,150 @@
\href{http://www.getchef.com/chef/}{Chef} ist ein Framework, welches eine \href{http://www.getchef.com/chef/}{Chef} ist ein Framework, welches eine
automatisierte Serverkonfiguration und -verwaltung ermöglicht. Chef übernimmt automatisierte Serverkonfiguration und -verwaltung ermöglicht. Chef übernimmt
dabei Aufgaben der Provisionierung (Installation der grundlegenden Dienste, dabei Aufgaben der Provisionierung (Installation der grundlegenden Dienste,
Resourcenverwaltung, Einrichtung und Konfiguration von Middleware) bis hin zu Ressourcenverwaltung, Einrichtung und Konfiguration von Middleware) bis hin zum
Deployment (Verteilung der eigentlichen Business-Anwendung). Deployment (Verteilung der eigentlichen Business-Anwendung).
Der Endanwender beschreibt hierbei die Systemressourcen und ihre Zustände in der Der Endanwender beschreibt hierbei die Systemressourcen und ihre Zustände in der
Programmiersprache \href{https://www.ruby-lang.org/}{Ruby}. Diese Definitionen Programmiersprache \href{https://www.ruby-lang.org/}{Ruby}. Diese Definitionen
werden von dem Program \emph{Chef-Client} eingelesen und in notwendige Aktionen werden von dem Programm \texttt{Chef-Client} eingelesen und in notwendige Aktionen
übersetzt, welche ausgeführt werden müssen, um den beschriebenen Zustand übersetzt, welche ausgeführt werden müssen, um den beschriebenen Zustand
umzusetzen. umzusetzen.
Die Gesamtheit aller Definitionen/Einstellungen nennt man das \emph{Chef-repo}. Die Gesamtheit aller Definitionen/Einstellungen nennt man das \texttt{Chef-Repo}.
Ein solches untergliedert sich in mehrere \emph{Cookbooks}\label{cookbook}. Ein Ein solches untergliedert sich in mehrere \texttt{Cookbooks}\label{cookbook}. Ein
Cookbook ist die Grundverwaltungseinheit in Chef. Es erfüllt einen bestimmten Cookbook ist die Grundverwaltungseinheit in Chef. Es erfüllt einen bestimmten
Teilaspekt des Systems (z.B. die Einrichtung eines Webservers Teilaspekt des Systems (z.B. die Einrichtung eines Webservers
\href{https://github.com/opscode-cookbooks/apache2}{Apache}). Cookbooks können \href{https://github.com/opscode-cookbooks/apache2}{Apache}). Cookbooks können
versioniert werden. Es können Abhängigkeiten zwischen mehreren Cookbooks versioniert werden. Es können Abhängigkeiten zwischen mehreren Cookbooks
angegeben werden. angegeben werden.
Physikalische oder virtuelle Maschinen werden als \emph{Nodes} bezeichnet. Physikalische oder virtuelle Maschinen werden als \texttt{Nodes} bezeichnet.
Einer Node können \emph{Attributes}, \emph{Roles} und Cookbooks zugewiesen Der Node werden \texttt{Attribute}, \texttt{Rollen} und Cookbooks zugewiesen.
werden. Roles und Cookbooks werden dazu in die sogenannte \emph{Run-List} der Rollen und Cookbooks werden dazu in die sogenannte \texttt{Run-List} eingefügt.
Node eingefügt. Diese gibt die Reihenfolge an, in welcher Roles und Cookbooks Diese gibt die Reihenfolge an, in welcher Rollen und Cookbooks angewendet
angewendet werden. Roles bieten eine Möglichkeit, Nodes zu gruppieren, welche die werden. Rollen bieten eine Möglichkeit, Nodes zu gruppieren, welche die gleichen
gleichen Aufgaben in einer Organisation erfüllen (z.B. Webserver). Aufgaben in einer Organisation erfüllen (z.B. Webserver).
Es gibt mehrere Möglichkeiten \emph{Chef} zu betreiben: Es gibt mehrere Möglichkeiten \texttt{Chef} zu betreiben:
\begin{description} \begin{description}
\item[Chef-Solo] Chef-Solo ist die einfachste Ausführungsform. Alle nötigen \item[Chef-Solo] Chef-Solo ist die einfachste Ausführungsform. Alle nötigen
Daten werden aus einem lokalen Verzeichnis geladen. Im Gegensatz zu Daten werden aus einem lokalen Verzeichnis geladen. Im Gegensatz zu
\emph{Chef-Server} und \emph{Enterprise Chef} wird bei Chef-Solo das \texttt{Chef-Server} und \texttt{Enterprise-Chef} wird bei Chef-Solo das
Programm \emph{chef-solo} an Stelle von \emph{chef-client} ausgeführt. Diese Programm \texttt{chef-solo} an Stelle von \texttt{chef-client} ausgeführt. Diese
Form wurde für die Umsetzung der Aufgabenstellung in Form wurde für die Umsetzung der Aufgabenstellung in
Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} gewählt. Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} gewählt.
\item[Chef-Server] Hierbei authentifiziert sich \emph{Chef-Client} über eine \item[Chef-Server] Hierbei authentifiziert sich \texttt{Chef-Client} über eine
\emph{REST-Api} zu einem \emph{Chef-Server} mittels eines privaten RSA-Keys. \texttt{REST-Api} zu einem \texttt{Chef-Server} mittels eines privaten
Auf diesem wird das Chef-repo zentral verwaltet. Der Chef-Client bekommt von RSA-Keys. Der Server verwaltet zentral das Chef-Repo. Der Chef-Client
diesem alle nötigen Informationen für die zu provisionierende \emph{Node}. bekommt von diesem alle nötigen Informationen für die zu provisionierende
Chef-Server bietet eine webbasierte GUI für die Administration an. Die \texttt{Node}. Chef-Server bietet eine webbasierte GUI für die
Attributes aller Nodes sind über die eingebaute Suchmaschine Administration an. Die Attribute aller Nodes sind über die eingebaute
\href{https://lucene.apache.org/solr/}{\emph{Solr}} durchsuchbar. Suchmaschine \href{https://lucene.apache.org/solr/}{\texttt{Solr}}
durchsuchbar.
\item[Enterprise-Chef/Hosted-Enterprise-Chef] Enterprise-Chef bietet \item[Enterprise-Chef/Hosted-Enterprise-Chef] Enterprise-Chef bietet
zusätzlich zu den Funktionen der Opensource-Version Chef-Server eine zusätzlich zu den Funktionen der Opensource-Version Chef-Server eine
rollenbasierte Benutzerverwaltung, bessere Überwachung, eine verbesserte rollenbasierte Benutzerverwaltung, bessere Überwachung, eine verbesserte
Weboberfläche sowie Push-Deployment an. Während bei Hosted-Enterprise-Chef Weboberfläche sowie Push-Deployment an. Während bei Hosted-Enterprise-Chef
die Firma Chef den Serverteil betreibt und die Skalierung des Dienstes die Firma Chef die Infrastruktur des Chef-Server betreibt und die Skalierung
übernimmt, ist bei Enterprise-Chef der Server in der eigenen des Dienstes übernimmt, befindet sich im Falle von Enterprise-Chef der
Organisation~\cite{chefenterprise}. Server in der eigenen Organisation~\cite{chefenterprise}.
\end{description} \end{description}
\subsubsection{Aufbau eines Cookbooks} \subsubsection{Aufbau eines Cookbooks}
\label{aufbau_eines_cookbook} \label{aufbau_eines_cookbook}
Nachfolgend ist die Ordnerstruktur eines Cookbooks am Beispiel von \begin{figure}[h]
\href{https://github.com/opscode-cookbooks/apt}{apt} dargestellt. \centering
\caption{Ordnerstruktur eines Cookbooks am Beispiel des \href{https://github.com/opscode-cookbooks/apt}{apt}-Cookbooks dargestellt.}
\begin{tikzpicture} \begin{tikzpicture}
\treeroot{apt-2.3.4} \treeroot{apt-2.3.4}
\altentry{attributes}{1} \altentry{attributes}{1}
\altentry{default.rb}{2} \altentry{default.rb}{2}
\altentry{files}{1} \altentry{files}{1}
\altentry{default}{2} \altentry{default}{2}
\altentry{apt-proxy-v2.conf}{3} \altentry{apt-proxy-v2.conf}{3}
\altentry{libraries}{1} \altentry{libraries}{1}
\altentry{helpers.rb}{2} \altentry{helpers.rb}{2}
\altentry{network.rb}{2} \altentry{network.rb}{2}
\altentry{providers}{1} \altentry{providers}{1}
\altentry{preference.rb}{2} \altentry{preference.rb}{2}
\altentry{repository.rb}{2} \altentry{repository.rb}{2}
\altentry{recipes}{1} \altentry{recipes}{1}
\altentry{cacher-client.rb}{2} \altentry{cacher-client.rb}{2}
\altentry{cacher-ng.rb}{2} \altentry{cacher-ng.rb}{2}
\altentry{default.rb}{2} \altentry{default.rb}{2}
\altentry{resources}{1} \altentry{resources}{1}
\altentry{preference.rb}{2} \altentry{preference.rb}{2}
\altentry{repository.rb}{2} \altentry{repository.rb}{2}
\altentry{templates}{1} \altentry{templates}{1}
\altentry{debian-6.0}{2} \altentry{debian-6.0}{2}
\altentry{default}{2} \altentry{default}{2}
\altentry{01proxy.erb}{3} \altentry{01proxy.erb}{3}
\altentry{acng.conf.erb}{3} \altentry{acng.conf.erb}{3}
\altentry{ubuntu-10.04}{2} \altentry{ubuntu-10.04}{2}
\altentry{acng.conf.erb}{3} \altentry{acng.conf.erb}{3}
\altentry{CHANGELOG}{1} \altentry{CHANGELOG}{1}
\altentry{metadata.json}{1} \altentry{metadata.json}{1}
\altentry{metadata.rb}{1} \altentry{metadata.rb}{1}
\altentry{README.md}{1} \altentry{README.md}{1}
\end{tikzpicture} \end{tikzpicture}
\end{figure}
Die Verzeichnisnamen sind fest vorgeben. Jedes Verzeichnis hat seine eigene Die Verzeichnisnamen und die Datei \texttt{metadata.rb} sind fest vorgeben.
Funktion. Dies hat den Vorteil, das man sich schnell in neuen Cookbooks zurecht Jedes Verzeichnis hat seine eigene Funktion. Dies hat den Vorteil, das man sich
findet. Hier nochmal die einzelnen Verzeichnisse im Überblick: schnell in neuen Cookbooks zurecht findet.
\begin{description} \begin{description}
\item[attributes] Attributes sind einfache Schlüssel-Wert-Beziehungen und \item[attributes] Attribute sind einfache Schlüssel-Wert-Beziehungen und
setzen Standardwerte für das Cookbook. Die Schlüssel sind hierarchisch setzen Standardwerte für das Cookbook. Die Schlüssel sind hierarchisch
organisiert. In der Regel ist die höchste Ebene der Name des Cookbooks (z.B. organisiert. In der Regel ist die höchste Ebene der Name des Cookbooks (z.B.
\emph{normal.mysql.client.packages}). Werte können Strings, Zahlen oder \texttt{normal.mysql.client.packages}). Werte können Strings, Zahlen oder
Arrays sein. Die gesetzten Attributes können in Roles, Nodes oder von Arrays sein. Die gesetzten Attribute können in Rollen, Nodes oder von
anderen Cookbooks überschrieben werden. Hierfür werden die Attributes mit anderen Cookbooks überschrieben werden. Hierfür werden die Attribute mit den
den verschiedenen Prioritäten default, force\_default, normal und override verschiedenen Prioritäten \texttt{default}, \texttt{force\_default},
gesetzt (aufsteigender Wertigkeit) gesetzt, wobei eine höhere Priorität eine \texttt{normal} und \texttt{override} (aufsteigender Wertigkeit) gesetzt.
Niedrigere überschreibt. Attribute mit einer höheren Priorität überschreiben den Wert von Attributen
mit einer niedrigeren Priorität.
\item[files] In diesem Verzeichnis können statische Dateien eingefügt werden, \item[files] In diesem Verzeichnis können statische Dateien eingefügt werden,
welche auf dem Zielsystem in das entsprechende Verzeichnis kopiert werden welche auf dem Zielsystem in das entsprechende Verzeichnis kopiert werden
können. können.
\item[libraries] In diesem Pfad können Hilfsfunktionen und \item[libraries] In diesem Pfad können Hilfsfunktionen und
Spracherweiterungen definiert werden. Spracherweiterungen definiert werden.
\item[resources] Ressourcen beschreiben die Bestandteile eines Systems. Eine \item[resources] Ressourcen beschreiben die Bestandteile eines Systems. Eine
Resource kann z.B. eine Datei, ein Prozess oder ein Paket sein. Man Ressource kann z.B. eine Datei, ein Prozess oder ein Paket sein. Man
beschreibt, welchen Zustand (Action in Chef genannt) diese Ressource haben beschreibt, welchen Zustand (Action in Chef genannt) diese Ressource haben
soll und Chef versucht, diesen Zustand herzustellen. Chef liefert bereits soll und Chef versucht, diesen Zustand herzustellen. Chef liefert bereits
viele wichtige Ressourcen mit. In Cookbooks können darüber hinaus eigene viele wichtige Ressourcen mit. In Cookbooks können darüber hinaus eigene
Resources definiert werden. Ressourcen definiert werden.
\item[providers] Während Ressourcen nur die Schnittstelle mit allen Attributes \item[providers] Während Ressourcen nur die Schnittstelle mit allen Attribute
beschreiben, die gesetzt werden können, ist der Provider eine konkrete beschreiben, die gesetzt werden können, ist der Provider eine konkrete
Implementierung. Deswegen muss für jede Ressource mindestens ein Provider Implementierung. Deswegen muss für jede Ressource mindestens ein Provider
existieren. Es kann mehrere Provider für eine Ressource geben, um zum existieren. Es kann mehrere Provider für eine Ressource geben, um zum
Beispiel um mehrere Plattformenvarianten oder Betriebssysteme abdecken zu Beispiel mehrere Plattformenvarianten oder Betriebssysteme abdecken zu
können (z.B. bei Paketmanagern oder Initsystemen - \ref{sec:initsysteme}). In können (z.B. bei Paketmanagern oder Initsystemen - \ref{sec:initsysteme}). In
eigenen Cookbooks erstellte Resources/Provider nennt man LWRP eigenen Cookbooks erstellte Ressourcen/Provider nennt man LWRP
(Lightweight-Resource/Provider). (englische Abkürzung für \texttt{Lightweight Resources and Providers}).
\item[recipes] In Recipes werden Ressourcen instanziiert, welche nötig sind, \item[recipes] In Recipes werden Ressourcen instantiiert, welche nötig sind,
um die gewünschte Ziel zu erreichen. Dabei können Abhängigkeiten zwischen um das gewünschte Ziel zu erreichen. Dabei können Abhängigkeiten zwischen
Recipes angegeben werden. Recipes angegeben werden.
\item[definitions] Ressources, welche häufiger in verschiedenen Recipes in \item[definitions] Ressourcen, welche häufiger in verschiedenen Recipes in
ähnlicher Form benötigt werden, können in eine \emph{Definition} ähnlicher Form benötigt werden, können in eine \texttt{Definition}
ausgelagert werden. Ein Beispiel ist das Generieren eines SSH-Schlüssels ausgelagert werden. Ein Beispiel ist das Generieren eines SSH-Schlüssels
für verschiedene Nutzer auf dem System. Für komplexere Konstrukte sollten für verschiedene Nutzer auf dem System. Für komplexere Konstrukte sollten
jedoch LWRPs (siehe oben) bevorzugt werden. jedoch LWRPs (siehe oben) bevorzugt werden.
\item[templates] Häufig werden dynamisch generierte Dateien benötigt, um zum \item[templates] Häufig werden dynamisch generierte Dateien benötigt, um zum
Beispiel Konfigurationsdateien zu erzeugen. In Chef wird für diesen Zweck Beispiel Konfigurationsdateien zu erzeugen. In Chef wird für diesen Zweck
die Templatesprache eRuby (Embedded Ruby) verwendet. In ERB-Templates wird die Templatesprache eRuby (Embedded Ruby) verwendet. In ERB-Templates wird
Rubycode ausgeführt, der sich zwischen den Tags \emph{<\%} und \emph{\%>} Rubyquellcode ausgeführt, der sich zwischen den Tags \texttt{<\%} und \texttt{\%>}
befindet. Dies erlaubt es einerseits den Inhalt von Variablen oder den befindet. Dies erlaubt es einerseits den Inhalt von Variablen oder den
Rückgabewert von Methoden zu interpolieren, andererseits können in Templates Rückgabewert von Methoden einzufügen, andererseits können in Templates
Kontrollstrukturen wie If-Statements und Schleifen verwendet werden. Kontrollstrukturen wie If-Statements und Schleifen verwendet werden.
\item[metadata.rb] In der Datei \emph{metadata.rb} kann der Name des Cookbook, \item[metadata.rb] In der Datei \texttt{metadata.rb} kann der Name des Cookbook,
die eigene Version, eine Beschreibung sowie Abhängigkeiten zu anderen die eigene Version, eine Beschreibung sowie Abhängigkeiten zu anderen
Cookbooks angegeben werden. Cookbooks angegeben werden.
\end{description} \end{description}
\begin{lstlisting}[caption={Beispiel ERB-Template:}] \begin{lstlisting}[caption={Beispiel ERB-Template:},label={lst:erb-templates}]
Diese Zeile wird beim Rendern ohne Aenderung uebernommen Diese Zeile wird beim Rendern ohne Aenderung uebernommen
<%# Ein Kommentar%> <%# Ein Kommentar%>
@ -156,134 +159,142 @@ findet. Hier nochmal die einzelnen Verzeichnisse im Überblick:
Diese Zeile erscheint auf nicht Ubuntu-basierten Nodes. Diese Zeile erscheint auf nicht Ubuntu-basierten Nodes.
<% end -%> <% end -%>
<%# Listet in einer Schleife alle Blockdevices der Node auf %> <%# Listet in einer Schleife alle Blockdevices des Node auf %>
<% @node.block_device.each do |block_device, attributes| %> <% @node.block_device.each do |block_device, attributes| %>
<%= block_device %>: <%= attributes.join(", ") %> <%= block_device %>: <%= attributes.join(", ") %>
<% end %> <% end %>
\end{lstlisting} \end{lstlisting}
\subsubsection{Ablauf einer Provisonierung} \subsubsection{Ablauf einer Provisionierung}
\label{ablauf_einer_provisionierung} \label{ablauf_einer_provisionierung}
Der genaue Ablauf wurde der Onlinedokumentation (\cite{chefrun}) von Chef Der genaue Ablauf wurde der Onlinedokumentation (\cite{chefrun}) von Chef
entnommen. Wie schon zu Beginn erwähnt, wird die Provisonierung von einem entnommen. Wie schon zu Beginn erwähnt, wird die Provisionierung von einem
Programm namens \emph{Chef-Client} durchgeführt. Je nach gewählter Umgebung kann Programm namens \texttt{Chef-Client} durchgeführt.
dieser periodisch vom Scheduler \emph{Cron} gestartet, permanent als
Systemdienst laufen (z.B. bei Enterprise Chef) oder manuell gestartet werden Je nach gewählter Umgebung kann dieser unterschiedlich gestartet werden:
(z.B. bei Vagrant - siehe~\ref{sub:einrichtung-der-netzwerkdienste}).
\begin{itemize}
\item periodisch vom Scheduler \texttt{Cron}
\item permanent als Systemdienst (z.B. bei Enterprise Chef)
\item manuell (z.B. bei Vagrant - siehe~\ref{sub:einrichtung-der-netzwerkdienste})
\end{itemize}
Als erstes lädt dieser Prozess seine Konfiguration aus der Datei Als erstes lädt dieser Prozess seine Konfiguration aus der Datei
\emph{client.rb}. In dieser stehen beispielsweise die URL des Chef-Server, in \texttt{client.rb}. In dieser stehen beispielsweise die URL des Chef-Server und
welchem Pfad temporäre Dateien gespeichert werden und der Name der Node. der Name des Node. Letzteres ist wichtig, um die Node in Chef einordnen zu
Letzteres ist wichtig, um die Node in Chef einordnen zu können und die richtigen können und die richtigen Einstellungen zuzuweisen. Alternativ kann der Name auch
Einstellungen zuzuweisen. Alternativ kann der Name auch von der Bibliothek von der Bibliothek \href{http://docs.opscode.com/ohai.html}{Ohai} gesetzt
\href{http://docs.opscode.com/ohai.html}{Ohai} gesetzt werden, in dem auf den werden, in dem auf den Hostnamen oder der FQDN (Fully Qualified Domain Name)
Hostnamen oder der FQDN (Fully Qualified Domain Name) zurückgegriffen wird. zurückgegriffen wird. Ohai sammelt systemrelevante Daten wie Details über
Ohai sammelt systemrelevante Daten wie Details über Hardwarekomponenten (Anzahl Hardwarekomponenten (Anzahl der CPUs, Größe und Art des RAMs, Netzwerkanbindung,
der CPUs, Größe und Art des RAMs, Netzwerkanbindung, Festplatten/SSDs, \dots), Festplatten/SSDs, \dots), Informationen über die Plattform (Art des
Informationen über die Plattform (Art des Betriebssystems und sowie dessen Version, Betriebssystems und sowie dessen Version, installierte Anwendungssoftware) und
installierte Anwendungssoftware) und die laufenden Prozesse. Diese Informationen sind die laufenden Prozesse. Diese Informationen sind durch eigene Ohai-Plugins
durch eigene Ohai-Plugins erweiterbar und können im Provisionierungsprozess erweiterbar und können im Provisionierungsprozess genutzt werden, um weitere
genutzt werden, um weitere Entscheidungen zu treffen. Sie sind darüber hinaus Entscheidungen zu treffen. Sie sind darüber hinaus auch auf dem Server
auch auf dem Server gespeichert und für andere Clients abrufbar. gespeichert und für andere Clients abrufbar.
Nach dem alle Einstellungen eingelesen sind, verbindet sich Chef-Client mit Nach dem alle Einstellungen eingelesen sind, verbindet sich der Chef-Client mit
Chef-Server. Die Authentifizierung erfolgt über den vorher auf der Node dem Chef-Server. Die Authentifizierung erfolgt über dem vorher auf dem Node
abgelegten RSA-Schlüssel. Für Administratoren gibt es einen Validator-Key. Im abgelegten RSA-Schlüssel. Für Administratoren gibt es einen Validator-Key. Mit
\href{http://docs.opscode.com/knife\_bootstrap.html}{Bootstraprozess}, in diesem kann ein Node auf dem Server registriert werden und so ein
welchem Chef initial auf der Node installiert, kann mit diesem eine Node auf dem Client-Schlüssel generiert werden.
Server registriert werden und ein Clientkey generiert werden.
Anschließend werden alte gesetzte Attributes und die Run-List vom Server Anschließend werden zuvor gesetzte Attribute und die Run-List vom Server
übertragen. Im 1. Durchlauf oder bei Verwendung von Chef-Solo sind diese Daten übertragen. Im 1. Durchlauf oder bei Verwendung von Chef-Solo sind diese Daten
nicht vorhanden. Stattdessen kann eine Datei im JSON-Format angegeben werden, nicht vorhanden. Stattdessen kann eine Datei im JSON-Format angegeben werden,
um die Attributes und der Run-List für die Node zu spezifizieren. Außerdem ist um die Attribute und die Run-List für die Node zu spezifizieren. Außerdem ist
es möglich eine Run-List auf dem Chef-Server einzustellen, welche ausgeführt es möglich eine Run-List auf dem Chef-Server einzustellen, welche ausgeführt
wird, wenn die Node keine eigene Run-List besitzt. wird, wenn die Node keine eigene Run-List besitzt.
Durch Auswertung der eingebunden Rollen und Recipes werden die benötigen Durch Auswertung der eingebunden Rollen und Recipes werden die benötigen
Cookbooks ermittelt. Der Client fordert eine Liste aller darin enthaltenen Cookbooks ermittelt. Der Client fordert eine Liste aller darin enthaltenen
Dateien und deren Checksumme an. Alle geänderten oder neuen Dateien werden Dateien und deren Checksumme an. Alle geänderten oder neuen Dateien werden
heruntergeladen und im lokalen Cache gespeichert. heruntergeladen und lokal gespeichert.
Nun werden die Attribute zurückgesetzt und aus den Cookbooks, Roles und der Node Nun werden die Attribute zurückgesetzt und aus den Cookbooks, Rollen und dem
neu generiert und entsprechend ihrer Priorität gesetzt. Die, in den Cookbooks Node neu generiert und entsprechend ihrer Priorität gesetzt. Die Ressourcen aus
definierten, Resources werden geladen und mit den, von Chef mitgelieferten, den Cookbooks werden geladen und in der Ressource-Collection zusammengefasst.
Resources in der Resource-Collection zusammengefasst. Nachdem alle Definitions Nachdem alle Definitionen und Bibliotheken geladen wurden, werden schließlich die
und Libraries geladen wurden, werden schließlich die Recipes verarbeitet. Die Recipes verarbeitet. Die darin erstellten Ressourcen beschreiben das System. Für
darin erstellten Resources beschreiben das System. Für jede Resource wird eine jede Ressource wird der Zustand festgelegt.
Action festgelegt, was gleichbedeutend mit deren Zustand ist.
Im nächsten Schritt folgt das sogenannte Converging (englisch für Im nächsten Schritt folgt das sogenannte \texttt{Converging} (englisch für
\emph{Angleichen}). Es werden alle Resources Schritt für Schritt abgearbeitet. Angleichen). Es werden alle Ressourcen Schritt für Schritt abgearbeitet. Dabei
Dabei wird für jede Resource, der für die Plattform zugehörige, Provider wird für jede Ressource der für die Plattform zugehörige Provider ausgewählt.
ausgewählt. Dieser überprüft den aktuellen Zustand der Resource und verändert, Dieser überprüft den aktuellen Zustand der Ressource und verändert falls
wenn notwendig, das System, um den Sollzustand zu erreichen. Zum Schluss überträgt notwendig das System, um den Sollzustand zu erreichen. Zum Schluss überträgt
Chef-Client die aktualisierten Attributes auf den Server, von welchem sie in Chef-Client die aktualisierten Attribute auf den Server, von welchem sie in
Solr indexiert werden. \texttt{Solr} indexiert werden.
Es besteht die Möglichkeit Handler vor oder nach dem Provisioning auszuführen. Es besteht die Möglichkeit, Handler vor oder nach der Provisionierung auszuführen.
Diese können im Fehlerfall Benachrichtigungen an das Monitoringssystem oder per Diese können im Fehlerfall Benachrichtigungen an das Monitoringssystem oder per
Email verschicken. In letzten Abschnitt (\ref{minitest_handler}) wird dieser Email verschicken. In letzten Abschnitt (\ref{minitest_handler}) wird dieser
Mechanismus genutzt um Tests auszuführen. Mechanismus genutzt, um Tests auszuführen.
\subsubsection{Vergleich mit puppet} \subsubsection{Vergleich mit puppet}
\label{vergleich_mit_puppet} \label{vergleich_mit_puppet}
Ein ebenfalls weit verbreitetes Konfigurationsmanagmentsystem ist Puppet. Es ist
das Ältere der beiden Projekte. Während das erste Puppetrelease bereits im Jahr \paragraph{Historischer Kontext}
2005 von den Puppet Labs veröffentlicht wurde, erschien Chef erst 4 Jahre später Ein ebenfalls weit verbreitetes Konfigurationsmanagementsystem ist Puppet. Es ist
im Jahre 2009. Chef wurde stark von Puppet beeinflusst. Der Erfinder von Chef, das Ältere der beiden Projekte. Während das erste Puppet-Release bereits im
Jahre 2005 von den Puppet Labs veröffentlicht wurde, erschien Chef erst 4 Jahre später
im Jahr 2009. Chef wurde stark von Puppet beeinflusst. Der Erfinder von Chef,
Adam Jacob, war selbst langjähriger Puppetnutzer, bevor er Chef schrieb. Seine Adam Jacob, war selbst langjähriger Puppetnutzer, bevor er Chef schrieb. Seine
damalige Konsultantfirma betreute mehrere Firmen bei der Provisionierung der damalige Firma betreute als Unternehmensberater mehrere Firmen bei der
Infrastruktur bis hin zum Deployment der Anwendung. Dabei kam Puppet zum Provisionierung der Infrastruktur bis hin zum Deployment der Anwendung. Dabei
Einsatz. Mit steigender Anzahl der Kunden, wuchs nach Aussagen von Adam Jacob kam Puppet zum Einsatz. Mit steigender Anzahl der Kunden, wuchs nach Aussagen
der Aufwand bei der Verwaltung der Puppet-Konfiguration. Diese mussten häufig von Adam Jacob der Aufwand bei der Verwaltung der Puppet-Konfiguration. Diese
für jeden Kunden stark angepasst oder neugeschrieben werden. Aus diesem Grund mussten häufig für jeden Kunden stark angepasst oder neu geschrieben werden. Aus
begann er an ein neues Deploymentsystem zu schreiben. Damals trug es noch den diesem Grund begann er an ein neues Deploymentsystem zu schreiben. Damals trug
Namen \emph{Marionette}. Dabei verwendete er ebenfalls, wie schon bei Puppet, es noch den Namen \texttt{Marionette}. Dabei verwendete er, wie schon bei
die Programmiersprache Ruby zur Implementierung des Clients. Ein wichtiges Puppet, die Programmiersprache Ruby zur Implementierung des Clients. Ein
Designziel seines neuen System war es, bessere Abstraktionsmöglichkeiten zu wichtiges Designziel seines neuen System war es, bessere
schaffen, um damit die Wiederverwendbarkeit zu erhöhen (Quelle: Abstraktionsmöglichkeiten zu schaffen, um damit die Wiederverwendbarkeit zu
\cite{chefhistory}). Anzumerken ist, dass seit der damals veröffentlichten erhöhen (Quelle: \cite{chefhistory}). Anzumerken ist, dass seit der damals
Puppetversion veröffentlichten Puppetversion
(\href{https://github.com/puppetlabs/puppet/commit/ce964ecb6d6a38cb7fb9f0b13a7e6b2eb4c381c3}{0.24.5}) (\href{https://github.com/puppetlabs/puppet/commit/ce964ecb6d6a38cb7fb9f0b13a7e6b2eb4c381c3}{0.24.5})
neue Funktionen und Spracherweiterungen zu Puppet hinzugefügt wurden, um dieses neue Funktionen und Spracherweiterungen zu Puppet hinzugefügt wurden, um dieses
Problem zu adressieren. (\cite{puppetlanguagechangelog}) Problem zu adressieren. (\cite{puppetlanguagechangelog})
Während bei Chef die Konfiguration in Ruby geschrieben wird, besitzt Puppet \paragraph{Sprache}
seine eigene Konfigurationssprache. Puppets Sprache ist im Gegensatz zu Während bei Chef die Konfiguration in Ruby geschrieben wird, besitzt Puppet eine
General-Purpose-Languages wie Ruby, Java oder C/C++ eine eigene Konfigurationssprache. Puppet's Sprache ist im Gegensatz zu allgemeinen
Domain-Specific-Language (DSL). Eine DSL ist eine speziell für den verwendeten Sprachen (engl. General-Purpose-Languages, kurz GPL) wie Ruby, Java
Anwendungszweck geschriebene und optimierte Sprache. Sie enthält häufig Elemente oder C/C++ eine domänspezifische Sprache (engl. Domain-Specific-Language - DSL).
und Ausdrücke, welche es erlauben, Probleme der Anwendungsdomain effizient zu Eine DSL ist eine speziell für den Anwendungszweck geschriebene und optimierte
lösen. Es wird häufig auf umfangreiche Standardbibliotheken und Sprachkonstrukte Sprache. Sie enthält häufig Elemente und Ausdrücke, welche es erlauben, Probleme
verzichtet, die in General-Purpose-Languages üblich sind. Puppets Sprache wurde der Anwendungsdomäne effizient zu lösen. Es wird häufig auf umfangreiche
an das Konfigurationsformat der Überwachungssoftware Nagios angelehnt Standardbibliotheken und Sprachkonstrukte verzichtet, die in GPLs üblich sind.
(\cite{puppetlanguage}). Sie ist deklarativ gehalten und soll möglichst einfach Puppet's Sprache wurde an das Konfigurationsformat der Überwachungssoftware
erlernbar für Administratoren, auch ohne programmiertechnischen Hintergrund, Nagios angelehnt (\cite{puppetlanguage}). Sie ist deklarativ gehalten und soll
sein. Der Schwerpunkt liegt auf der Beschreibung von \emph{Resources}. Die möglichst einfach erlernbar sein (auch für Administratoren ohne programmiertechnischen
Sprache besitzt Kontrollstrukturen wie Case- und If-Statements. Es gibt Hintergrund). Der Schwerpunkt liegt auf der Beschreibung von
Datentypen wie \emph{Strings}, \emph{Booleans}, \emph{Arrays}, \emph{Reguläre \texttt{Ressourcen}. Die Sprache besitzt Kontrollstrukturen wie Case- und
Ausdrücke} und \emph{Hashes}. Diese können in Variablen gespeichert werden. Die If-Statements. Es gibt Datentypen wie \texttt{Strings}, \texttt{Booleans},
\texttt{Arrays}, \texttt{Reguläre Ausdrücke} und \texttt{Hashes}. Diese können
in Variablen gespeichert werden. Die
\href{https://forge.puppetlabs.com/puppetlabs/stdlib}{Standardbibliothek} von \href{https://forge.puppetlabs.com/puppetlabs/stdlib}{Standardbibliothek} von
Puppet stellt Funktionen bereit, um auf diesen Datentypen einfache Operationen Puppet stellt Funktionen bereit, um auf diesen Datentypen einfache Operationen
auszuführen. Allerdings ist es nicht möglich, Schleifen auszuführen. (Diese auszuführen. Allerdings ist es nicht möglich, Schleifen auszuführen. (Diese
\href{http://docs.puppetlabs.com/puppet/latest/reference/experiments_lambdas.html}{Funktion} \href{http://docs.puppetlabs.com/puppet/latest/reference/experiments_lambdas.html}{Funktion}
ist momentan als \emph{experimental} markiert). Funktionen können nicht direkt in ist momentan als \texttt{experimentell} markiert). Funktionen können nicht
Puppets Sprache definiert werden. Stattdessen werden diese als Erweiterung des direkt in Puppet's Sprache definiert werden. Stattdessen werden diese als
Parsers in Ruby implementiert, was wiederum den Nachteil hat, dass dafür Erweiterung des Parsers in Ruby implementiert, was wiederum den Nachteil hat,
eine weitere Sprachen erlernt werden muss. Manche Unternehmen und Organisationen dass dafür eine weitere Sprachen erlernt werden muss. Manche Unternehmen und
greifen bevorzugt auf Puppet zurück, weil es einfacher ist, neue Mitarbeiter ohne Organisationen greifen bevorzugt auf Puppet zurück, weil es einfacher ist, neue
Rubykenntnisse in diesem Framework zu schulen. Andere wiederum bevorzugen die Mitarbeiter ohne Rubykenntnisse in diesem Framework zu schulen. Andere wiederum
Flexibilität von Ruby. Facebook gab dies als einen der Grund an für einen bevorzugen die Flexibilität von Ruby. Facebook gab dies als einen der Grund an
Umstieg im Jahre 2013 von \emph{CFEngine2} auf \emph{Chef 11} für einen Umstieg im Jahre 2013 von \texttt{CFEngine2} auf \texttt{Chef 11}
\cite{facebooklikeschef}. \cite{facebooklikeschef}.
Das strukturelle Gegenstück zu \emph{Cookbooks} in Chef ist das \paragraph{Communities}
\emph{Puppet-Module} in Puppet. Diese werden in der Community entwickelt. Da Das strukturelle Gegenstück zu \texttt{Cookbooks} in Chef ist das
Puppet älter ist, ist anzunehmen, dass hierfür mehr Puppet-Module zur Verfügung \texttt{Modul} in Puppet. Diese werden in der Nutzergemeinschaft entwickelt. Da
Puppet älter ist, ist anzunehmen, dass hierfür mehr Module zur Verfügung
stehen, als Cookbooks für Chef. Die primäre Distributionsquelle ist stehen, als Cookbooks für Chef. Die primäre Distributionsquelle ist
\href{https://forge.puppetlabs.com/}{Puppet-Forge}, in dem \textbf{2206} \href{https://forge.puppetlabs.com/}{Puppet-Forge}, in dem \textbf{2206}
\href{https://forge.puppetlabs.com/modules?supported=yes}{Module} zur Verfügung \href{https://forge.puppetlabs.com/modules?supported=yes}{Modul} zur Verfügung
stehen (Stand: 31.03.2014). Für Chef gibt es eine ähnliche stehen (Stand: 31.03.2014). Für Chef gibt es eine ähnliche
\href{http://community.opscode.com/}{Community-Seite} mit \textbf{1368} Modulen, \href{http://community.opscode.com/}{Community-Seite} mit \textbf{1368} Modulen,
(Stand: 31.03.2014 - ermittelt über die (Stand: 31.03.2014 - ermittelt über die
@ -295,11 +306,11 @@ Vergleich wurde die Anzahl der Suchtreffer für Projekte, die die Begriffe
filtert Forks (Abspaltungen) von Projekten aus den Suchergebnissen heraus und filtert Forks (Abspaltungen) von Projekten aus den Suchergebnissen heraus und
schlüsselt die Ergebnisse nach Programmiersprache auf. Es wurden alle Sprachen schlüsselt die Ergebnisse nach Programmiersprache auf. Es wurden alle Sprachen
in beiden Projekte mit weniger als 100 Suchtreffer aus Übersichtlichkeitsgründen in beiden Projekte mit weniger als 100 Suchtreffer aus Übersichtlichkeitsgründen
nicht in das Diagramm übernommen (siehe Tabelle). Eine Stichproben der nicht in das Diagramm übernommen (siehe Tabelle~\ref{tab:rohdaten}). Eine
Ergebnisse, dass die Suchtreffer sich überwiegend mit den eigentlichen Projekten Stichproben der Ergebnisse, dass die Suchtreffer sich überwiegend mit den
Chef und Puppet beschäftigen. Anzumerken ist, dass Zielgruppe von Puppet eigentlichen Projekten Chef und Puppet beschäftigen. Anzumerken ist, dass
überwiegend Systemadminstratoren aus besteht, während Chef auch von vielen Zielgruppe von Puppet überwiegend Systemadminstratoren aus besteht, während Chef
Entwicklern genutzt wird. Letztere verwenden bevorzugt Github. auch von vielen Entwicklern genutzt wird. Letztere verwenden bevorzugt Github.
\begin{figure}[h] \begin{figure}[h]
\pgfplotstableread{ \pgfplotstableread{
@ -346,6 +357,7 @@ Puppet Ruby Shell Python Javascript Perl Andere
\end{tikzpicture} \end{tikzpicture}
\caption{Anzahl der Suchtreffer auf Github aufgeschlüsselt nach \caption{Anzahl der Suchtreffer auf Github aufgeschlüsselt nach
Programmiersprache für die Begriffe ``Chef'' und ``Puppet''.} Programmiersprache für die Begriffe ``Chef'' und ``Puppet''.}
\label{tab:rohdaten}
\end{figure} \end{figure}
\begin{table}[h] \begin{table}[h]
@ -359,63 +371,60 @@ Programmiersprache für die Begriffe ``Chef'' und ``Puppet''.}
\vspace{0.5cm} \vspace{0.5cm}
Eine weitere wichtige Statistik für Opensourceprojekte ist die Anzahl der Eine weitere wichtige Statistik für Opensource-Projekte ist die Anzahl der
Abonnenten auf den jeweiligen Mailinglisten. Abonnenten auf den jeweiligen Mailinglisten. Engagierte und aktive
Nutzer/Entwickler abonnieren häufig diese, wodurch sich die Größe der Community
qualitativ vergleichen lassen.
\begin{description} \begin{description}
\item[chef@lists.opscode.com] Community-Mailingliste, 1620 Abonnenten, \href{http://lists.opscode.com/sympa/info/chef}{Quelle}, Stand: 31.03.2014 \item[chef@lists.opscode.com] Community-Mailingliste, 1620 Abonnenten, Quelle:~\cite{chefcommunitylist}, Stand: 31.03.2014
\item[chef-dev@lists.opscode.com] Entwickler-Mailingliste, 652 Abonnenten, \href{http://lists.opscode.com/sympa/info/chef-dev}{Quelle}, Stand: 31.03.2014 \item[chef-dev@lists.opscode.com] Entwickler-Mailingliste, 652 Abonnenten, Quelle:~\cite{chefdeveloperlist}, Stand: 31.03.2014
\item[puppet-users@googlegroups.com] Community-Mailingliste, \item[puppet-users@googlegroups.com] Community-Mailingliste, \textasciitilde{}7000 Abonnenten, Quelle:~\cite{puppetcommunitylist}, Stand: 01.04.2014
\textasciitilde{}7000 Abonnenten, Quelle: \href{https://twitter.com/puppetlabs/status/450760644329881600}{Anfrage per Twitter}, Stand: 01.04.2014
\end{description} \end{description}
Mailinglisten eignen sich, um qualitiv die aktiven Nutzer beider Projekte zu Die Anzahl der verfügbaren Module, veröffentlichte Githubprojekte und der
vergleichen. Neben dem Bugtracker ist stellt die Mailingliste ein wichtiges Abonnenten auf den Mailinglisten weisen darauf hin, dass Puppet nach wie vor
Kommunikationsmittel dar. eine größere Community hat.
Die Zahlen weisen darauf hin, dass Puppet nach wie vor eine größere Community \paragraph{Funktionsweise}
hat. Anstelle von Recipes werden in Puppet Manifeste geschrieben. Das sind Dateien,
die auf den Suffix .pp enden und sich in dem Ordner \texttt{manifests} im Modul
befinden. Jedes Manifest definiert eine Klasse, eingeleitet durch das
Schlüsselwort \texttt{class}. Der Namen dieser Klasse wird aus dem Modulnamen
und dem Manifest-Namen gebildet. Wenn das Modul \texttt{foo} das Manifest
\texttt{bar} enthält, ist der Name der Klasse \texttt{foo::bar}. Eine Ausnahme
bildet das Manifest \texttt{init.pp}, bei dem die Klasse nur \texttt{bar} lauten
würde. Diese Benennungskonvention wurde in Chef übernommen, um Recipes in
Cookbooks zu referenzieren. Allerdings werden in Recipes keine separaten Objekt
definiert und der ganze Inhalt der Datei bildet das Recipe.
Anstelle von Recipes werden in Puppet Manifests geschrieben. Das sind Dateien, Eine Klasse in Puppet kann über Parameter konfiguriert werden. Parameter werden
die auf den Suffix .pp enden und sich in dem Ordner \emph{manifests} im im Kopfteil der Klasse deklariert und können Standardwerte besitzen. Chef
Puppet-Module befinden. Jedes Manifest definiert eine \emph{Class}, eingeleitet besitzt mit \texttt{Attributen} ein vergleichbares Konzept. Allerdings werden
durch das Schlüsselwort \emph{class}. Der Namen dieser Klasse wird aus dem Attribute getrennt von den Recipes definiert und sie werden dem Node-Objekte
Module-Namen und Manifest-Namen gebildet. Wenn das Module ``foo'' das Manifest zugewiesen. Die Attribute stehen somit allen Recipes zu Verfügung und können an
``bar'' enthält, ist der Name der Class ``foo::bar''. Eine Ausnahme bildet das
Manifest \emph{init.pp}, bei dem die Class nur ``bar'' lauten würde. Diese
Benennungskonvention wurde in Chef übernommen, um Recipes in Cookbooks zu
referenzieren (anstelle von \emph{init.pp} lautet die Datei \emph{default.rb}).
Allerdings werden in Recipes keine separaten Objekt definiert und der ganze
Inhalt der Datei bildet das Recipe.
Eine Class in Puppet kann über Parameter konfiguriert werden. Parameter werden
im Kopfteil der Class deklariert und können Standardwerte besitzen. Chef besitzt
mit \emph{Attributes} ein vergleichbares Konzept. Allerdings werden Attributes
getrennt von den Recipes definiert und sie werden dem Node-Objekte zugewiesen.
Die Attributes stehen somit allen Recipes zu Verfügung und können an
verschiedenen Stellen überschrieben werden. In Puppet 3 wurde diese Trennung verschiedenen Stellen überschrieben werden. In Puppet 3 wurde diese Trennung
von Code und organsationsspezifischen Daten durch die Erweiterung \emph{Hiera} von Code und organsationsspezifischen Daten durch die Erweiterung \texttt{Hiera}
ebenfalls eingeführt. Class-Parameter werden automatisch in der \emph{Hieradb} ebenfalls eingeführt. Klassenparameter werden automatisch in der
gesucht und gegebenfalls überschrieben. Hiera-Attribute können spezifisch für \texttt{HieraDB} gesucht und gegebenenfalls überschrieben. In älteren Versionen
einzelne Nodes oder für die gesamte Organisation gesetzt werden. In älteren von \texttt{Puppet} wurden Einstellungen für die Nodes in der zentralen
Versionen von \emph{Puppet} wurden Attributes und Module für die einzelnen Nodes \texttt{site.pp}-Manifest verwaltet. Hiera ersetzt die \texttt{site.pp} weitest
in der zentralen \emph{site.pp}-Manifest verwaltet. Hiera ersetzt die gehend. Durch die Funktion \texttt{hiera\_include} können Klassen im
\emph{site.pp} weitest gehend. Durch die Funktion \emph{hiera\_include} können Hiera-Backend gesetzt werden (ähnlich der Run-List in Chef).
Classes im Hiera-Backend gesetzt werden (ähnlich der Run-List in Chef).
Resources heissen in Puppet Types. Puppet liefert wie Chef bereits eine Reihe Ressourcen heißen in Puppet \texttt{Types}. Puppet liefert wie Chef bereits eine Reihe
von Types mit. Diese werden Core-Types genannt. Wie auch in Chef können Types in von Types mit. Diese werden Core-Types genannt. Wie auch in Chef können Types in
Puppet mehrere plattformspezifische Provider besitzen. Es ist möglich, eigene Puppet mehrere plattformspezifische Provider besitzen. Es ist möglich, eigene
Types zu definieren, auch Custom-Types genannt (Ähnlich LRWP in Chef). Die Types zu definieren, auch Custom-Types genannt (Ähnlich LRWP in Chef). Die
Implementierung der Types/Provider erfolgt in Ruby im Verzeichnis Implementierung der Types/Provider erfolgt in Ruby im Verzeichnis
\emph{lib/puppet}. Die Zustände einer Resource können in Puppet über das Setzen \texttt{lib/puppet}. Die Zustände einer Ressource können in Puppet über das Setzen
des Parameters \emph{ensure} festgelegt werden (vergleichbar mit \emph{action} des Parameters \texttt{ensure} festgelegt werden (vergleichbar mit \texttt{action}
in Chef). in Chef).
Ein weiteres häufig genutztes Pattern, um Resources zu gruppieren, ist der Ein weiteres häufig genutztes Entwurfsmuster, um Ressourcen zu gruppieren, ist
\emph{Defined-Type}. Dieser ist das Äquivalent zur aus Chef bekannte der \texttt{Defined-Type}. Dieser ist das Äquivalent zur aus Chef bekannten
\emph{Definition}. Ein Defined-Type kann im Gegensatz zum Custom-Type auch \texttt{Definition}. Ein Defined-Type kann im Gegensatz zum Custom-Type auch
direkt in der Puppet-Sprache mit dem Schlüsselwort \emph{define} erstellt direkt in der Puppet-Sprache mit dem Schlüsselwort \texttt{define} erstellt
werden. werden.
Vor der eigentlichen Provisionierung werden Informationen über das System zu Vor der eigentlichen Provisionierung werden Informationen über das System zu
@ -424,60 +433,67 @@ gesammelt. Dabei wird auf die Bibliothek
von Chef wurde die gleiche Bibliothek verwendet, bevor später von Chef wurde die gleiche Bibliothek verwendet, bevor später
\href{http://docs.opscode.com/ohai.html}{Ohai} integriert wurde. \href{http://docs.opscode.com/ohai.html}{Ohai} integriert wurde.
Chef benutzt die gleiche Template-Syntax wie Puppet (eRuby). Der einzige Puppet nutzt die gleiche Template-Syntax wie Chef, welche in
Unterschied bei Chef ist die Funktion für verschiedene Plattformen und Quellcodelisting~\ref{lst:erb-templates} vorgestellt wurde, um Dateien auf dem System
-versionen verschiedene Template-Varianten der gleichen Datei im Cookbook zu generieren. Der einzige Unterschied bei Chef ist die Funktion für
vorzuhalten. Die Varianten werden durch Unterordner im Verzeichnis verschiedene Plattformen und -versionen verschiedene Template-Varianten der
\emph{templates/} unterschieden (z.B. \emph{templates/windows} oder gleichen Datei im Cookbook vor halten zu können. Die Varianten werden durch Unterordner
\emph{templates/ubuntu-12.04}). Falls kein der Plattform entsprechende Ordner im Verzeichnis \texttt{templates/} unterschieden (z.B.
existiert sucht Chef im Verzeichnis \emph{templates/default}. \texttt{templates/windows} oder \texttt{templates/ubuntu-12.04}). Falls kein der
Plattform entsprechende Ordner existiert sucht Chef im Verzeichnis
\texttt{templates/default}.
Ein wesentlicher Unterschied zwischen Puppet und Chef ist die Reihenfolge der Ein wesentlicher Unterschied zwischen Puppet und Chef ist die Reihenfolge der
Ausführung von Resources. Chef überprüft die Resources in der Reihenfolge, in Ausführung von Ressourcen. Chef überprüft die Ressourcen in der Reihenfolge, in
der sie in der Run-List und in den Recipes geladen werden. Puppet sortiert der sie in der Run-List und in den Recipes geladen werden. Puppet sortiert
Resources um. Bei Puppet spricht man von modelbasiertem Konfigurationsmanagment, Ressourcen derartig um, dass möglichst wenig Veränderungen am System vorgenommen
während Chef ein \href{http://www.getchef.com/solutions/configuration-management/}{codebasiertes werden müssen um den gewünschten Zustand zu erreichen. Zum Beispiel, wenn an
Konfigurationsmanagment} ist. Da manche Resources voneinander abhängen, kann durch die Angabe der mehreren Stellen eine Konfiguration für einen Dienst verändert wird, sollte
Parameter \emph{before} und \emph{require} die Reihenfolge festgelegt werden. dieser nur einmal neu gestartet werden müssen. Bei Puppet spricht man von
Über die Parameter \emph{notify} und \emph{subscribe} können darüber hinaus modellbasiertem Konfigurationsmanagement, während Chef ein
Resourcen aktualisiert werden, wenn sich eine Abhängigkeit geändert hat (z.B. \href{http://www.getchef.com/solutions/configuration-management/}{codebasiertes
kann ein Dienst neugestartet werden, wenn sich die dazu gehörige Konfiguration Konfigurationsmanagement} ist. Da manche Ressourcen voneinander abhängen, kann
verändert hat). In Chef kann Letzeres über die Parameter \emph{notifies} und durch die Angabe der Parameter \texttt{before} und \texttt{require} die
\emph{subscribes} angegeben werden. Reihenfolge festgelegt werden. Über die Parameter \texttt{notify} und
\texttt{subscribe} können darüber hinaus Ressourcen aktualisiert werden, wenn
sich eine Abhängigkeit geändert hat (z.B. kann ein Dienst neu gestartet werden,
wenn sich die dazu gehörige Konfiguration verändert hat). In Chef kann Letzteres
über die Parameter \texttt{notifies} und \texttt{subscribes} angegeben werden.
Wie auch Chef bietet Puppet verschiedene Betriebsmodi. Im einfachsten Fall wird \paragraph{Architektur} Wie auch Chef bietet Puppet verschiedene Betriebsmodi.
mit dem Befehl \emph{puppet apply} ein lokales Manifest geladen werden Im einfachsten Fall wird mit dem Befehl \texttt{puppet apply} ein lokales
(vergleichbar mit Chef-Solo). Das Äquivalent zu Chef-Server ist der Manifest geladen werden (vergleichbar mit Chef-Solo). Das Äquivalent zum
Puppetmaster, zu welchem sich der Client \emph{Puppetd} verbindet und mittels Chef-Server in Chef ist bei Puppet der Puppet-Master, zu welchem sich der Client
SSL-Zertifikaten authentifiziert. In der Standarteinstellung setzt Puppetmaster \texttt{Puppetd} verbindet und mittels SSL-Zertifikaten authentifiziert. In der
auf den verhältnismäßig einfachen Webserver WEBrick. Dieser skaliert allerdings Standarteinstellung setzt Puppetmaster auf den verhältnismäßig einfachen
nicht über einen CPU-Core. Für größere Installationen werden Passenger oder Webserver \texttt{WEBrick} Dieser skaliert allerdings nicht auf mehrere
Mongrel als Applikationsserver empfohlen, wobei Nginx als Load-Balancer fungiert. Ein CPU-Kerne, da nur ein Prozess und Thread gestartet wird. Für Installationen mit
beliebter Ansatz zum Skalieren größerer Cluster ist das Verwalten der mehr als 10 Knoten werden Passenger oder Mongrel als Applikationsserver
Manifeste in einem Git-Repository, wobei Puppet periodisch über einen Cron-Job empfohlen, wobei Nginx als Load-Balancer fungiert. Ein beliebter Ansatz zum
aufgerufen wird und die ausgecheckten Manifeste ausführt. Während Chef-Server Skalieren größerer Cluster ist das Verwalten der Manifeste in einem
bis zur Version 10 wie Puppet-Master in Ruby geschrieben war, wurde der API-Teil von Git-Repository, wobei ein Cron-Job periodisch die Manifeste vom Git-Server lädt
Chef-Server wurde in Version 11 in der Programmiersprache Erlang neugeschrieben. und Puppet ausführt. Während Chef-Server bis zur Version 10 wie Puppetmaster in
Die Zahl der Nodes, die von einem Server bedient werden, soll sich dabei Ruby geschrieben war, wurde der API-Teil von Chef-Server in Version 11 in der
vervierfacht haben und kann somit bis zu 10.000 Nodes bedienen (Quelle: Programmiersprache Erlang neu geschrieben. Die Zahl der Nodes, die von einem
\cite{chefscale}). Für Puppet wurden keine Statistiken gefunden, die eine Aussage Server bedient werden, soll sich dabei vervierfacht haben und kann somit bis zu
darüber treffen, wieviele Nodes pro Server betreut werden können. Allerdings ist 10.000 Nodes bedienen (Quelle: \cite{chefscale}). Für Puppet wurden keine
anzunehmen, dass die Anzahl der Server, bedingt durch die genutzte Architektur, Statistiken gefunden, die eine Aussage darüber treffen, wie viele Nodes pro
kleiner ist als bei Chef. Server betreut werden können. Allerdings ist anzunehmen, dass die Anzahl der
Server, bedingt durch die genutzte Architektur, kleiner ist als bei Chef.
Zu den, von offiziell von Chef unterstützten, Plattformen gehören Windows, MacOS X, Zu den, von offiziell von Chef unterstützten, Plattformen gehören Windows, Mac OS X,
verschiedene Linuxderivate (Debian, Ubuntu, Redhat, \ldots) und Solaris. Puppet verschiedene Linuxderivate (Debian, Ubuntu, Redhat, \ldots) und Solaris. Puppet
bietet breiteren Support und unterstützt zusätzlich Free- und OpenBSD sowie bietet breiteren Support und unterstützt zusätzlich Free- und OpenBSD sowie
HP-UX und AIX. HP-UX und AIX.
\paragraph{Résumé}
Zusammenfassend lässt sich feststellen, dass Chef und Puppet den gleichen Zusammenfassend lässt sich feststellen, dass Chef und Puppet den gleichen
Funktionsumfang bieten. Die Grundkonzepte sind ähnlich, so ein Anwender des Funktionsumfang bieten. Die Grundkonzepte sind ähnlich, so ein Anwender des
einen Systems mit wenig Aufwand auch das andere System lernen kann. Die beiden einen Systems mit wenig Aufwand auch das andere System lernen kann. Die beiden
Firmen, Puppet Labs und Chef, enwickeln beide ihr Produkt stetig weiter und Firmen, Puppet Labs und Chef, entwickeln beide ihr Produkt stetig weiter und
bieten kommerziellen Support. Während Puppet auf den klassischen bieten kommerziellen Support. Während Puppet auf den klassischen
Systemadminstrator abzielt, ist Chef ein Produkt der Systemadministrator abzielt, Chef spricht den Trend der
\href{http://www.getchef.com/solutions/devops/}{DevOps}-Bewegung, bei welcher \href{http://www.getchef.com/solutions/devops/}{DevOps}-Kultur an, bei welcher
der (operative) adminstrative Teil einer Organisation stärker mit der Administration und Entwicklung stärker ineinander über gehen.
Entwicklung verzahnt wird.
% vim: set spell spelllang=de_de % vim: set spell spelllang=de_de

View File

@ -2,4 +2,3 @@
% welche Erkenntnisse wurden gewonnen % welche Erkenntnisse wurden gewonnen
% Ansible, Salt. % Ansible, Salt.

View File

@ -2,28 +2,28 @@
\label{sub:einrichtung-der-netzwerkdienste} \label{sub:einrichtung-der-netzwerkdienste}
Für die Provisionierung der Netzwerkdienste wurde Für die Provisionierung der Netzwerkdienste wurde
\href{http://vagrantup.com}{Vagrant} verwendet. Dies ist ein Programm, um auf \href{http://vagrantup.com}{Vagrant} verwendet. Dies ist ein Programm, um
der Basis von Virtualbox und anderen Virtualisierungslösungen schnell und schnell und reproduzierbar virtuelle Maschinen für Virtualbox und andere
reproduzierbar virtuelle Maschinen zu starten. Die Einstellungen hierfür werden Virtualsierungslösungen zu erstellen und zu starten. Die Einstellungen hierfür
in der Datei \emph{Vagrantfile} hinterlegt, welche Vagrant beim Start einliest. werden in der Datei \texttt{Vagrantfile} hinterlegt, welche Vagrant beim Start
Vagrant kann Chef beim Erstellen von virtuellen Maschinen integrieren. Es einliest. Vagrant kann Chef beim Erstellen von virtuellen Maschinen integrieren.
bietet Optionen, mit welchen Einstellungen neue virtuelle Maschinen Zum Einsatz kam das Betriebssystem Ubuntu in der Version 12.04. Das Basisimage
provisioniert werden sollen. Zum Einsatz kam das Betriebssystem Ubuntu in der hierfür wurde von \texttt{Chef}, der gleichnamigen Firma, bereitgestellt. Für
Version 12.04. Das Basisimage hierfür wurde von \emph{Chef}, der gleichnamigen die Kommunikation mit Vagrant wurde die virtuelle Netzwerkkarte \texttt{eth0}
Firma, bereitgestellt. Für die Kommunikation mit Vagrant wurde das konfiguriert. Ein weitere Karte (\texttt{eth1}) wird für das interne virtuelle
Netzwerkinterface \emph{eth0} konfiguriert. Ein weiteres Netzwerkinterface Netzwerk zwischen den VMs zum Betreiben der Netzwerkdienste benötigt.
(\emph{eth1}) wird für das interne virtuelle Netzwerk zwischen den VMs zum
Betreiben der Netzwerkdienste benötigt. Vagrant bietet für diese erweiterten
Einstellungen keine Optionen. Um diese dennoch zu übernehmen, waren spezielle
Kommandozeilenargumente an den Befehl \emph{VBoxManage} nötig, welches von
Vagrant für Virtualbox genutzt wird. Dies schränkt die Nutzung allerdings auf
den Hypervisor Virtualbox ein. Vagrant bietet die Möglichkeit, neben
Provisionierungsystemen auch Shellskripte auszuführen. Diese wurde genutzt, um
Chef auf die, zum damaligen Zeitpunkt, aktuellste Version 11.8.2 zu
aktualisieren.
Desweiteren wird Ruby auf dem Host benötigt, um beispielsweise die Tests Vagrant bietet keine Optionen, ein virtuelles Netzwerk zu erstellen, ohne das
ausführen zu können. Auf Unix-Ähnlichen Systemen kann dies mit dem Befehl: jeder VM eine IP-Adresse fest oder DHCP unmittelbar nach dem Start zugewiesen
wird. In dem genannten Netzwerk sollte allerdings DHCP von dem Head-Node bereit
gestellt werden. Deswegen waren zusätzliche Kommandozeilenargumente an den
Befehl \texttt{VBoxManage} im Vagrantfile nötig, welches von Vagrant genutzt
wird um Virtualbox zu verwalten. Dies schränkt die Nutzung allerdings auf den
Hypervisor Virtualbox ein.
Des weiteren wird Ruby auf dem Host benötigt, um beispielsweise die Tests
ausführen zu können. Auf Unix-Ähnlichen Systemen kann man diese
Programmiersprache mit dem Befehl:
\shellcmd{curl -sSL https://get.rvm.io | bash -s stable} \shellcmd{curl -sSL https://get.rvm.io | bash -s stable}
@ -36,12 +36,12 @@ Projektverzeichnis ausgeführt werden:
\shellcmd{bundle install} \shellcmd{bundle install}
Zur Verwaltung der externen und internen Cookbooks wurde die Zur Verwaltung der externen und selbst geschriebenen Cookbooks wurde die
Abhängigkeitsverwaltung \href{http://berkshelf.com}{Berkshelf} verwendet. Bei Abhängigkeitsverwaltung \href{http://berkshelf.com}{Berkshelf} verwendet. Bei
diesem werden die zu ladenden Cookbooks und die gewünschte Version in einer diesem werden die zu ladenden Cookbooks und die gewünschte Version in einer
Datei namens Berkssfile angegeben (vergleichbar mit Datei namens Berksfile angegeben (vergleichbar mit
\href{http://bundler.io/}{Gemfiles} in Ruby). Berkshelf unterstützt dabei \href{http://bundler.io}{Bundler} und Gemfiles in Ruby). Berkshelf unterstützt
verschiedene Quellen (per Api von der Communityseite von Opscode, Git, lokal) dabei verschiedene Quellen (per API von der Communityseite von Chef, Git, lokal)
und kann Abhängigkeiten zu anderen Cookbooks auflösen. Um die Cookbooks initial und kann Abhängigkeiten zu anderen Cookbooks auflösen. Um die Cookbooks initial
zu laden, muss der Befehl: zu laden, muss der Befehl:
@ -54,19 +54,19 @@ Für das Zusammenspiel mit Vagrant gibt es das Plugin
dass die von Berkshelf verwalteten Cookbooks auch in Vagrant zur Verfügung dass die von Berkshelf verwalteten Cookbooks auch in Vagrant zur Verfügung
stehen. stehen.
Für bestimmte Funktionen, wie geteilte Ordner zwischen VM und Host, müssen die Für bestimmte Funktionen, wie Gemeinsame Ordner (shared folders) zwischen VM und
\emph{virtualbox-client-modules} in der VM installiert sein. Diese sind in Host, müssen die \texttt{virtualbox\--client\--modules} in der VM installiert
meisten vielen Images vorhanden, die es für Vagrant gibt. Allerdings muss die sein. Diese sind in vielen Images bereits vorhanden, die es für Vagrant gibt.
Virtualboxversion des Host mit der Version in der VM übereinstimmen. Abhilfe Allerdings muss die Virtualbox-Version des Host mit der Version in der VM
schafft das Vagrantplugin übereinstimmen. Abhilfe schafft das Vagrantplugin
\href{https://github.com/dotless-de/vagrant-vbguest}{vagrant-vbguest}. Beim \href{https://github.com/dotless-de/vagrant-vbguest}{vagrant-vbguest}. Beim
Start installiert das Plugin die die gleiche Version des Modules in der VM. Start der VM installiert das Plugin die gleiche Version des Modul in der VM. Wenn
Wenn Virtualbox mit Linux als Hostsystem ausgeführt wird, sollte das Virtualbox mit Linux als Host-System ausgeführt wird, muss das Kernelmodule
Kernelmodule \emph{vboxdrv} geladen sein. Manche Linux-Distributionen \texttt{vboxdrv} geladen sein. Manche Linux-Distributionen installieren dieses
installieren dieses Module bereits während der Installation von Virtualbox. Module bereits während der Installation von Virtualbox. Auf Mac OS X und
Auf MacOS X und Windows sind keine weiteren Schritte notwendig. Windows sind keine weiteren Schritte notwendig.
Beide Plugins werden den Befehlen: Beide Plugins werden mit den Befehlen:
\shellcmd{vagrant plugin install vagrant-vbguest} \shellcmd{vagrant plugin install vagrant-vbguest}
@ -83,59 +83,59 @@ erneut mit Befehl:
\shellcmd{vagrant provision} \shellcmd{vagrant provision}
gestartet werden: gestartet werden.
Als Netzwerkdienste wurden die Protokolle DHCP, DNS und NTP gewählt. Die VMs Die Netzwerkdienste sollen die Protokolle DHCP, DNS und NTP bereitstellen. Es
wurden in die zwei Gruppen \emph{Headnodes}und \emph{Computenodes} geteilt. Die wird wie im Praktikum zwischen \texttt{Head-Nodes} und \texttt{Compute-Nodes}
Headnode bietet die genannten Dienste an. Die Computenodes fordern auf dem unterschieden. Die Head-Node bietet die genannten Dienste an. Die Compute-Nodes
internen Netzwerk per DHCP eine IP-Adresse an und nutzen den DNS- und NTP-Dienst fordern auf dem internen Netzwerk per DHCP eine IP-Adresse an und nutzen den
der jeweiligen Headnode. DNS- und NTP-Dienst der ihr zugewiesenen Head-Node.
Die Attributes der Roles und der Node wurden in JSON-Dateien in den Die Attribute für die Rollen und den Nodes wurden in JSON-Dateien in den
Verzeichnissen \emph{roles/} und \emph{nodes/} abgelegt. Es gibt je eine Verzeichnissen \texttt{roles/} und \texttt{nodes/} abgelegt. Es gibt je eine
Role-Datei für Computenodes und Headnodes. In der aktuellen Konfiguration Rollen-Datei für Compute-Nodes und Head-Nodes. In der aktuellen Konfiguration
erzeugt Vagrant eine Headnode mit der FQDN \emph{node0.lctp} und zwei erzeugt Vagrant eine Head-Node mit der FQDN \texttt{node0.lctp} und zwei
Computenodes (\emph{node1.lctp} und \emph{node2.lctp}). Compute-Nodes (\texttt{node1.lctp} und \texttt{node2.lctp}).
Für das Deployment wurden fünf Cookbooks geschrieben: Es wurden fünf Cookbooks geschrieben:
\begin{description} \begin{description}
\item[bind] \item[bind]
Als DNS-Server wurde bind gewählt. Das Cookbook richtet diesen Dienst ein Für Bereitstellung des DNS-Dienstes wird Named aus dem BIND-Packet
und fügt, die in den Attributes konfigurierten, DNS-Einträge zu den installiert. Das Cookbook richtet diesen Dienst ein und fügt die in den
entsprechenden Zonen hinzu. Attributen konfigurierten DNS-Einträge zu den entsprechenden Zonen hinzu.
\item[dhcp] \item[dhcp]
Dieses Cookbook richtet den \href{https://www.isc.org/downloads/dhcp/}{ISC-DHCP-Server} ein. Neben der Dieses Cookbook richtet den \href{https://www.isc.org/downloads/dhcp/}{ISC-DHCP-Server} ein. Neben der
Zuordnung von festen IP-Adressen zu Nodes, kann ein DNS-Server und ein Zuordnung von festen IP-Adressen zu Nodes, kann ein DNS-Server und ein
NTP-Server NTP-Server
festgelegt werden. festgelegt werden.
\item[lctp-network] Dieses Cookbook ist ein Wrappercookbook um das \item[lctp-network]
Dieses Cookbook ist ein Wrapper um das
\href{https://github.com/redguide/network_interfaces}{network\_interfaces} \href{https://github.com/redguide/network_interfaces}{network\_interfaces}
Cookbook. Wrappercookbooks werden häufig dazu benutzt um bestehende Cookbooks Cookbook. Wrapper-Cookbooks werden häufig dazu benutzt um bestehende
aus anderen Quellen um Funktionalität zu erweitern. In diesem Fall aktiviert Cookbooks aus anderen Quellen um Funktionalität zu erweitern. Für
das Cookbook für die Computenodes DHCP auf dem interen Netzwerkinterface. Compute-Nodes aktiviert das Cookbook für die DHCP in dem
Auf den Headnodes wird eine statische IP-Adresse gesetzt, der DNS-Server auf virtuellen Netzwerk. Im Falle eines Head-Nodes wird eine statische
localhost festgelegt und IP-Forwarding sowie Masquerading via iptables für IP-Adresse gesetzt, der DNS-Server auf localhost festgelegt und
den Routerbetrieb aktiviert. IP-Forwarding sowie Masquerading via iptables für den Router-Betrieb
aktiviert.
\item[ntp] \item[ntp]
Dieses Cookbook richtet den NTP-Deamon ein, welcher die Zeit zwischen den Dieses Cookbook richtet den NTP-Deamon ein, welcher die Zeit zwischen den
einzelnen Knoten synchron halten soll. einzelnen Nodes synchronisiert.
\item[main] \item[main]
Dieses Cookbook fasst alle oben genannten Cookbooks für Compute- und Dieses Cookbook fasst alle oben genannten Cookbooks für Compute- und
Headnode zusammen. Man könnte dies prinzipiell auch in den jeweiligen Head-Node zusammen. Man könnte dies prinzipiell auch in den jeweiligen
Rollen erledigen. Rollen in Chef haben allerdings den Nachteil, dass diese Rollen erledigen. Rollen haben allerdings den Nachteil, dass diese
nicht versionierbar und (bei Chef-Server) über alle Umgebungen identisch im Gegensatz zu Cookbooks nicht versionierbar sind und (bei Chef-Server) über
sind. Somit ist eine Trennung zwischen Test- und Produktivumgebung alle Umgebungen identisch sind. Somit ist eine Trennung zwischen Test- und
schwierig. Produktivumgebung schwierig.
\end{description} \end{description}
Es wurden folgende externen Cookbooks verwendet: Es wurden folgende externen Cookbooks verwendet:
\begin{description} \begin{description}
\item[apt] bringt die lokalen Paketquellen auf den aktuellen Stand und \item[apt] aktualisert die lokalen Paketlisten und den Paketcache.
aktualisiert den Paketcache. \item[network\_interfaces] verwaltet Debian's Netzkonfiguration
\item[network\_interfaces] verwaltet Debians Netzkonfiguration
/etc/network/interfaces.
\item[minitest-handler] Sammelt alle Tests in den Cookbooks und führt diese \item[minitest-handler] Sammelt alle Tests in den Cookbooks und führt diese
nach der Provisionierung aus (siehe~\ref{minitest_handler}). nach der Provisionierung aus (siehe~\ref{minitest_handler}).
\end{description} \end{description}
% vim: set spell spelllang=de_de % vim: set spell spelllang=de_dihr zugewiesenen e

View File

@ -3,54 +3,50 @@
Wie auch in der Softwareentwicklung müssen Konfigurationssysteme getestet Wie auch in der Softwareentwicklung müssen Konfigurationssysteme getestet
werden. Dies gestaltet sich oft als schwierig, weil nicht immer eine exakte werden. Dies gestaltet sich oft als schwierig, weil nicht immer eine exakte
Kopie des aktuellen Produktionssystem zur Verfügung steht. Mit steigender Kopie des aktuellen Produktionssystems zur Verfügung steht. Mit steigender
Komplexität steigt der Aufwand, geschriebene Cookbooks manuell zu testen. Im Komplexität steigt der Aufwand, Cookbooks manuell zu testen. Im Folgenden werden
Folgenden werden verschiedene Möglichkeiten aufgeführt, wie dies automatisiert verschiedene Möglichkeiten aufgeführt, wie dies automatisiert werden kann.
werden kann.
Die erste und einfachste Methode ist der Befehl: Die erste und einfachste Methode ist der Befehl:
\shellcmd{knife cookbook test [COOKBOOKS...]} \shellcmd{knife cookbook test [COOKBOOKS...]}
Das Kommandozeilenprogramm \emph{knife} ist Teil von Chef. Es ist das primäre Das Kommandozeilenprogramm \texttt{knife} ist ein Teil von Chef. Es ist das
Verwaltungsprogramm für Adminstratoren. Der Unterbefehl \emph{cookbook test} primäre Verwaltungsprogramm für Chef-Administratoren. Der Unterbefehl
überprüft den Rubyquellcode und die Templates des Cookbooks auf Syntaxfehler. \texttt{cookbook test} überprüft den Ruby-Quellcode und die Templates des
Allerdings treten viele Fehler erst zur Laufzeit auf, insbesonderes da Ruby eine Cookbooks auf Syntaxfehler. Allerdings treten viele Fehler erst zur Laufzeit
dynamische Programmiersprache ist. Ein anderes Programm ist foodcritic. Es führt auf, im Besonderen da Ruby dynamisch typisiert ist und der Compiler
eine statische Codeanalyse ähnlich \href{http://www.jslint.com/}{JSlint} oder beispielsweise Tippfehler in Methoden und Variablennamen nicht erkennen kann.
Ein anderes Programm ist foodcritic. Es führt eine statische Codeanalyse ähnlich
\href{http://www.jslint.com/}{JSlint} oder
\href{http://perl-critic.stacka.to/}{Perl::Critic} auf der eigenen Codebasis \href{http://perl-critic.stacka.to/}{Perl::Critic} auf der eigenen Codebasis
durch. Dabei wird der Rubycode gegen einen Regelsatz getestet, um so häufige durch. Dabei wird der Ruby-Quellcode gegen einen Regelsatz getestet, um so
Programmierfehler zu erkennen oder um Codingstandards innerhalb eines Projekts häufige Programmierfehler zu erkennen oder um Code-Konventionen innerhalb eines
einzuhalten. Dieser Regelsatz kann durch eigene Regeln erweitern werden. Projekts einzuhalten. Dieser Regelsatz kann durch eigene Regeln erweitern
werden.
\subsubsection{Chefspec} \subsubsection{Chefspec}
\label{chefspec} \label{chefspec}
Chefspec baut auf das, in Ruby verbreitete, Testframework Chefspec baut auf das in Ruby verbreitete Testframework
\href{http://rspec.info/}{RSpec} auf. Rspec ist ein Testframework, welches auf \href{http://rspec.info/}{RSpec} auf. Chefspec erweitert dabei RSpec um die
\href{http://dannorth.net/2012/05/31/bdd-is-like-tdd-if/}{Behavior Driven Funktion, Cookbooks zu laden und stellt spezielle Matcher (RSpec-Terminologie
Development} (kurz BDD) basiert. Hierbei dokumentieren sich Testcases selbst für Assertions) bereit, um diese zu testen. Wie bereits in
durch Einfügen von Beschreibungen. RSpec kann Sätze aus diesen Beschreibungen Abschnitt~\ref{ablauf_einer_provisionierung} erwähnt, gibt es zwei Phasen bei
bilden und so im Falle eines fehlgeschlagen Tests schnell darüber Auskunft der Ausführung von Chef. Bei Chefspec wird der Provisionierungsprozess nur bis
geben, was der Test getestet hat und aus welchen Grund dieser fehlgeschlagen zur Convergingphase durchlaufen. Die eigenen Tests überprüfen nur die erzeugten
ist. Chefspec erweitert dabei RSpec um die Funktion, Cookbooks zu laden und \texttt{Ressourcen}. Dies hat den Vorteil, das Tests sehr schnell durchlaufen
stellt spezielle Matcher (RSpec-Terminologie für Assertions) bereit, um diese zu werden, da keine Änderungen an einem System vorgenommen werden müssen. Dies hat
testen. Wie bereits in Abschnitt~\ref{ablauf_einer_provisionierung} erwähnt, Vorteile beim Entwickeln, weil man auf diese Weise schnell Feedback bekommt. Das
gibt es zwei Phasen bei der Ausführung von Chef. Bei Chefspec wird der Zusammenspiel mehrerer Cookbooks lässt sich dadurch gut testen. Außerdem
Provisionierungsprozess nur bis zur Convergingphase durchlaufen. Die eigenen ermöglicht es, verschiedene Konfigurationen/Betriebssysteme zu testen, ohne das
Tests überprüfen nur die erzeugten \emph{Resources}. Dies hat den Vorteil, das diese (zeit)aufwendig aufgesetzt werden müssen. Da Chefspec allerdings zu keinen
Tests sehr schnell durchlaufen werden, da keine Änderungen an einem System Zeitpunkt Code auf dem System ausführt, sind weitere Integrationstest
vorgenommen werden müssen. Dies hat Vorteile beim Entwickeln, weil man auf diese unerlässlich.
Weise schnell Feedback bekommt. Das Zusammenspiel mehrerer Cookbooks lässt sich
dadurch gut testen. Außerdem ermöglicht es, verschiedene
Konfigurationen/Betriebssysteme durchzutesten, ohne das diese (zeit)aufwendig
aufgesetzt werden müssen. Da Chefspec allerdings zu keinen Zeitpunkt Code auf
dem System ausführt, sind weitere Integrationstest unerlässlich.
Der folgende Test wurde aus dem selbst geschriebenen NTP-Cookbook Der folgende Test wurde aus dem selbst geschriebenen NTP-Cookbook
(\ref{sub:einrichtung-der-netzwerkdienste}) entnommen. (\ref{sub:einrichtung-der-netzwerkdienste}) entnommen.
\begin{lstlisting}[language=Ruby,caption={Chefspec-Test für das NTP-Cookbook}]
\begin{lstlisting}[language=Ruby]
require_relative '../spec_helper' require_relative '../spec_helper'
describe 'ntp::default' do describe 'ntp::default' do
@ -67,45 +63,39 @@ describe 'ntp::default' do
end end
\end{lstlisting} \end{lstlisting}
Im \emph{chef\_run}-Block wird der fiktiven Node Attribute zugewiesen und das zu Im \texttt{chef\_run}-Block wird dem fiktiven Node Attribute zugewiesen und das zu
testende Cookbook ausgeführt. Das Ergebnis wird in diesem Beispiel in dem Objekt testende Cookbook ausgeführt. Das Ergebnis wird in diesem Beispiel in dem Objekt
\emph{chef\_run} gespeichert. Gegen dieses Objekt wird getestet, ob bestimmte \texttt{chef\_run} gespeichert. Gegen dieses Objekt wird getestet, ob bestimmte
\emph{Resources} korrekt initialisiert wurden. In diesem Fall wird überprüft, ob \texttt{Ressourcen} korrekt initialisiert wurden. In diesem Fall wird überprüft, ob
das Paket \emph{ntp} installiert werden soll und ob das Subnetz in dem Template das Paket \texttt{ntp} installiert werden soll und ob das Subnetz in dem Template
in der Konfigurationsdatei \emph{/etc/ntp.conf} richtig gesetzt wird. in der Konfigurationsdatei \texttt{/etc/ntp.conf} richtig gesetzt wird.
Die Tests werden mit dem Befehl \emph{rspec} ausgeführt. Wenn keine weiteren Argumente Die Tests werden mit dem Befehl \texttt{rspec} ausgeführt. Wenn keine weiteren Argumente
angegeben sind, führt dieses Programm alle Dateien unterhalb des Ordners \emph{spec} angegeben sind, führt dieses Programm alle Dateien unterhalb des Ordners \texttt{spec}
aus, dessen Dateinamen auf \emph{\_spec.rb} enden. aus, dessen Dateinamen auf \texttt{\_spec.rb} enden.
Um alle drei oben genannten Testmethoden gleichzeitig ausführen zu lassen, wurde Um alle drei oben genannten Testmethoden gleichzeitig ausführen zu lassen, wurde
ein Rakefile geschrieben. \href{http://rake.rubyforge.org/}{Rake} ist das, in ein Rakefile geschrieben. \href{http://rake.rubyforge.org/}{Rake} ist das in
Ruby geschriebene Äquivalent, zu Make, welches ein verbreitetes Buildprogramm Ruby geschriebene Äquivalent zu Make, welches ein verbreitetes Buildprogramm
auf Unix-Ähnlichen Plattformen ist. Die Tests werden durch den Task \emph{test} auf UNIX-ähnlichen Plattformen ist. Die Tests werden durch den Befehl:
ausgeführt:
\shellcmd{rake test} \shellcmd{rake test}
Dieser muss innerhalb Projektverzeichnises aufgerufen werden. ausgeführt.
Dieser muss innerhalb Projektverzeichnisses aufgerufen werden.
\subsubsection{Minitest-Handler} \subsubsection{Minitest-Handler}
\label{minitest_handler} \label{minitest_handler}
\href{https://github.com/btm/minitest-handler}{Minitest-Handler} hingegen wird \href{https://github.com/btm/minitest-handler}{Minitest-Handler} hingegen wird
nach jedem Provisionierungsdurchgang ausgeführt. Im Gegensatz zu Chefspec nutzt nach jedem Provisionierungsdurchgang ausgeführt. Im Gegensatz zu Chefspec nutzt
es das Minitest-Framework, welches schon mit Ruby mitgeliefert wird. Allerdings es das Minitest-Framework, welches schon mit Ruby mitgeliefert wird. Um
kann man durch einbinden, der Zeile: Minitest-Handler zu nutzen, muss das Recipe aus
\texttt{Minitest-Handler-Cookbook} als erstes Recipe in der Node geladen werden.
\begin{lstlisting} Minitest-Handler durchsucht beim Durchlauf in jedem anderen Cookbook, in den
require "minitest/spec" Unterordnern in \texttt{files/} nach dem Verzeichnis \texttt{test} und lädt alle
\end{lstlisting} Tests aus diesem Verzeichnis. Über die Zeile:
eine Syntax benutzen, die RSpec sehr ähnliche ist. Um Minitest-Handler zu
nutzen, muss das Recipe aus \emph{Minitest-Handler-Cookbook} als erstes Recipe
in der node geladen werden. Minitest-Handler durchsucht beim Durchlauf in jedem
anderen Cookbook, in den Unterordnern in \emph{files/} nach dem Verzeichnis
\emph{test} und lädt alle Tests aus diesem Verzeichnis. Über die
Beschreibungszeile:
\begin{lstlisting}[language=Ruby] \begin{lstlisting}[language=Ruby]
describe_recipe "ntp::default" do # describe_recipe "ntp::default" do #
@ -113,14 +103,14 @@ describe_recipe "ntp::default" do #
end end
\end{lstlisting} \end{lstlisting}
wird angeben, für welches Recipe der Test gedacht ist (In diesem Fall das wird angeben, zu welchem Test das Recipe gehört (In diesem Fall das
Defaultrecipe aus dem NTP-Cookbook). Wenn das entsprechende Recipe von der Node Recipe aus dem NTP-Cookbook). Wenn das entsprechende Recipe von dem Node
ausgeführt wird, wird der dazugehörige Test nach dem Provisionierungsdurchlauf ausgeführt wird, wird der dazugehörige Test nach dem Provisionierungsdurchlauf
ebenfalls ausgeführt. Minitest-Handler erweitert RSpec um nützliche Methoden, um ebenfalls ausgeführt. Minitest-Handler erweitert RSpec um nützliche Methoden, um
den Status des Systems zu überprüfen. Nachfolgend ein Beispiel aus dem Bind-Cookbook, den Status des Systems zu überprüfen. Nachfolgend ist ein Beispiel aus dem Bind-Cookbook,
welches in Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} erwähnt wurde: welches in Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} erwähnt wurde:
\begin{lstlisting}[language=Ruby] \begin{lstlisting}[language=Ruby, caption={\texttt{Minitest}-Test für das Bind-Cookbook}]
describe_recipe 'bind::default' do describe_recipe 'bind::default' do
it "starts the named daemon" do it "starts the named daemon" do
service("bind9").must_be_running service("bind9").must_be_running
@ -131,9 +121,9 @@ describe_recipe 'bind::default' do
end end
\end{lstlisting} \end{lstlisting}
Die Methode \emph{assert\_sh} überprüft den Exitstatus eines Befehls und schlägt Die Methode \texttt{assert\_sh} überprüft den Exit-Code eines Befehls und schlägt
fehl, wenn dieser ungleich Null ist, während die \emph{service}-Methode den fehl, wenn dieser ungleich der Zahl Null ist, während die \texttt{service}-Methode den
Status eines Systemdienst sicherstellt. Weitere Testmedhoden sind zum Beispiel Status eines Systemdienst überprüft. Weitere Testmethoden sind zum Beispiel
das Überprüfen von Verzeichnissen, Inhalte von Dateien oder Mountpoints. Viele das Überprüfen von Verzeichnissen, Inhalte von Dateien oder Mountpoints. Viele
Fehler werden in der Regel schon von den Provider erkannt und festgestellt. Fehler werden in der Regel schon von den Provider erkannt und festgestellt.
Minitest-Handler kann dies Erweitern um protokollspezifische Tests durchzuführen Minitest-Handler kann dies Erweitern um protokollspezifische Tests durchzuführen

View File

@ -1,4 +1,4 @@
\section{Chef - Provisionierungssystem (Jörg Thalheim)} \section{Chef - Konfigurationsmanagementsystem (Jörg Thalheim)}
\input{chef/chef-task} \input{chef/chef-task}
\input{chef/chef-comparison} \input{chef/chef-comparison}

View File

@ -1,5 +1,5 @@
@misc{chefenterprise, @misc{chefenterprise,
author = {chef}, author = {Chef},
title = {Enterprise-class features and support}, title = {Enterprise-class features and support},
url = {http://www.getchef.com/enterprise-chef/#features-and-support}, url = {http://www.getchef.com/enterprise-chef/#features-and-support},
year = {2014}, year = {2014},
@ -7,7 +7,7 @@
} }
@misc{chefrun, @misc{chefrun,
author = {chef}, author = {Chef},
title = {About the chef-client Run}, title = {About the chef-client Run},
url = {http://docs.opscode.com/essentials_nodes_chef_run.html}, url = {http://docs.opscode.com/essentials_nodes_chef_run.html},
year = {2014}, year = {2014},
@ -15,7 +15,7 @@
} }
@misc{chefhistory, @misc{chefhistory,
author = {chef}, author = {Chef},
title = {History of Chef: What's in a Name?}, title = {History of Chef: What's in a Name?},
url = {http://www.youtube.com/watch?v=Ia2ItmjRsw8&feature=plcp}, url = {http://www.youtube.com/watch?v=Ia2ItmjRsw8&feature=plcp},
year = {2014}, year = {2014},
@ -23,7 +23,7 @@
} }
@misc{puppetlanguage, @misc{puppetlanguage,
author = {puppetlabs}, author = {Puppet-Labs},
title = {Docs: Language: Basics}, title = {Docs: Language: Basics},
url = {http://docs.puppetlabs.com/puppet/latest/reference/lang_summary.html#compilation-and-catalogs}, url = {http://docs.puppetlabs.com/puppet/latest/reference/lang_summary.html#compilation-and-catalogs},
year = {2014}, year = {2014},
@ -31,7 +31,7 @@
} }
@misc{puppetlanguagechangelog, @misc{puppetlanguagechangelog,
author = {puppetlabs}, author = {Puppet-Labs},
title = {Docs: History of Puppet Language Features}, title = {Docs: History of Puppet Language Features},
url = {http://docs.puppetlabs.com/guides/language_history.html#puppet-language-features-by-release}, url = {http://docs.puppetlabs.com/guides/language_history.html#puppet-language-features-by-release},
year = {2014}, year = {2014},
@ -39,7 +39,7 @@
} }
@misc{chefscale, @misc{chefscale,
author = {chef}, author = {Chef},
title = {Opscode Unleashes New Generation of Chef}, title = {Opscode Unleashes New Generation of Chef},
url = {http://www.getchef.com/press-releases/opscode-unleashes-new-generation-of-chef/}, url = {http://www.getchef.com/press-releases/opscode-unleashes-new-generation-of-chef/},
year = {2013}, year = {2013},
@ -47,13 +47,33 @@
} }
@misc{facebooklikeschef, @misc{facebooklikeschef,
author = {chef}, author = {Chef},
title = {Scaling systems configuration at Facebook - Phil Dibowitz}, title = {Scaling systems configuration at Facebook - Phil Dibowitz},
url = {http://www.youtube.com/watch?v=SYZ2GzYAw_Q}, url = {http://www.youtube.com/watch?v=SYZ2GzYAw_Q},
year = {2013}, year = {2013},
month = {April} month = {April}
} }
@misc{chefcommunitylist,
author = {Chef},
title = {Opscode Mailing Lists},
url = {http://lists.opscode.com/sympa/info/chef},
year = {2014},
month = {März}
}
@misc{chefdeveloperlist,
author = {Chef},
title = {Opscode Mailing Lists},
url = {http://lists.opscode.com/sympa/info/chef-dev},
year = {2014},
month = {März}
}
@misc{puppetcommunitylist,
author = {Puppet-Labs},
title = {Anfrage auf Twitter},
url = {https://twitter.com/puppetlabs/status/450760644329881600},
year = {2014},
month = {März}
}