diff --git a/bericht/abschluss.tex b/bericht/abschluss.tex index 5536b7d..46f7f84 100644 --- a/bericht/abschluss.tex +++ b/bericht/abschluss.tex @@ -1,3 +1,4 @@ \section{Abschlussaufgaben} \input{nftables/nftables} +\input{chef/chef} diff --git a/bericht/bericht.tex b/bericht/bericht.tex index fac113e..6421c08 100644 --- a/bericht/bericht.tex +++ b/bericht/bericht.tex @@ -20,6 +20,9 @@ \usepackage{pgfplotstable} \usepackage{csquotes} \usepackage{float} +\usepackage[utf8]{inputenc} +\usepackage{ucs} + \RequirePackage{mymacros} @@ -62,4 +65,6 @@ \input{anhang} +\bibliography{sources}{} +\bibliographystyle{plain} \end{document} diff --git a/bericht/bs/bs.tex b/bericht/bs/bs.tex index e8342ba..fbaa29c 100644 --- a/bericht/bs/bs.tex +++ b/bericht/bs/bs.tex @@ -42,6 +42,6 @@ dem {\tt eth0}-Interface setzen (siehe \emph{aufgabe2.3/iptables.rules}) und mit \input{bs/bs-git} -\input{bs/bs-pdsh} +\input{bs/bs-pdsh} \pagebreak diff --git a/bericht/chef/chef-comparison.tex b/bericht/chef/chef-comparison.tex new file mode 100644 index 0000000..8f63935 --- /dev/null +++ b/bericht/chef/chef-comparison.tex @@ -0,0 +1,127 @@ +\subsubsection{Funktionsweise von Chef} +\label{ssub:funktionsweise_von_chef} + +\href{http://www.getchef.com/chef/}{Chef} ist ein Framework, welches es +ermöglicht automatisiert Server zu konfigurieren und zu verwalten. Der +Endanwender beschreibt hierbei die Systemresourcen und ihre Zustände in der +Programmiersprache \href{https://www.ruby-lang.org/}{Ruby}. Diese Definitionen +werden von \emph{Chef-client} eingelesen und in notwendige Aktionen übersetzt, +welche ausgeführt werden müssen, um den beschriebenen Zustand umzusetzen. + +Die Gesamtheit aller Definitionen/Einstellungen nennt man das \emph{Chef-repo}. +Diese untergliedert sich in mehrere \emph{Cookbooks}\label{cookbook}, welche die +Grundverwaltungseinheit darstellt. Jedes dieser Cookbooks, erfüllt einen +bestimmten Teilaspekt des Systems, (z.B. die Einrichtung eines Webservers +\href{https://github.com/opscode-cookbooks/apache2}{Apache}). Coobooks +können versioniert werden. Es können Abhängigkeiten zwischen mehreren +Cookbooks angegeben werden. + +Eine physikalische oder virtuelle Maschine wird als \emph{node} bezeichnet. +Einer Node können \emph{Attributes}, \emph{Roles} und Cookbooks zugewiesen +werden. Roles bieten eine Möglichkeit Nodes, welche die gleiche +Aufgaben in einer Organisation besitzen, zu gruppieren (z.B. webserver). + +Es gibt mehrere Möglichkeiten \emph{Chef} zu betreiben: + +\begin{description} + \item[chef-solo] Dies ist die einfachste Ausführungsform. Hierbei wird lädt + \emph{Chef-client} alle nötigen Daten aus einem lokalen Verzeichnis. Diese + Form wurde für die Umsetzung der Aufgabenstellung. + \item[chef-server] Hierbei authentifiziert sich \emph{Chef-client} über eine + \emph{REST-Api} zu einem \emph{chef-server} mittels Zertifikaten. Auf diesem + wird das Chef-repo zentral verwaltet. Der Chef-client bekommt von diesem + alle nötigen für die zu provisionierende \emph{node}. Chef-server bietet + eine Weboberfläche für die Administrierung an. Die Attribute aller Nodes sind + über die eingebaute Suchemaschine \emph{Solr} durchsuchbar. + \item[Enterprise Chef/Hosted Enterprise Chef] Ähnlich wie Chef-server aber + bietet bessere Skalierbarkeit, rolenbasierte Benutzerverwaltung, bessere Überwachung, + Push-Deployment und eine verbesserte Weboberfläche~\cite{chefenterprise} +\end{description} + +\textbf{Aufbau eines Cookbook} +\label{aufbau_eines_cookbook} + +Hier ist die Ordnerstruktur des Cookbook apt (TODO Link) dargestellt: + +\begin{lstlisting} +> apt-2.3.4/ + > attributes/ + default.rb + > files/ + > default/ + apt-proxy-v2.conf + > libraries/ + helpers.rb + network.rb + > providers/ + preference.rb + repository.rb + > recipes/ + cacher-client.rb + cacher-ng.rb + default.rb + > resources/ + preference.rb + repository.rb + > templates/ + > debian-6.0/ + > default/ + 01proxy.erb + acng.conf.erb + > ubuntu-10.04/ + acng.conf.erb + CHANGELOG.md + metadata.json + metadata.rb + README.md +\end{lstlisting} + +Die Verzeichnisnamen sind fest vorgeben. Jedes Verzeichnis hat seine eigene +Funktion. Dies hat den Vorteil, das man sich schnell in neuen Cookbooks zurecht +findet. Hier nochmal die einzelnen Verzeichnisse im Überblick: + +\begin{description} + \item[attributes] setzt Standardwerte (Attribute) für das Cookbook. Dies + können Strings, Zahlen oder Arrays sein. Die gesetzten Attribute können in + Roles, Nodes oder anderen Cookbooks überschrieben werden. Hierfür gibt es + die Prioritäten default, force\_default, normal und override um das + überschreiben deterministisch zu machen. Attributes sind hierarchisch + organisiert. In der Regel ist die höchste Ebene der Name des Cookbooks. + (z.B. normal.mysql.client.packages) + \item[files] Hier können statische Dateien eingefügt werden, welche dann auf + dem Zielsystem in das entsprechende Verzeichnis kopiert werden können. + \item[libraries] In diesem Verzeichnis können Hilfsfunktionen definiert werden. + \item[resources] Ressourcen beschreiben, die Bestandteile eines Systems. Eine + Ressource kann z.B. eine Datei, ein Prozess oder ein Packet sein. Man + beschreibt, welchen Zustand (action in Chef genannt) diese Ressource haben + soll und Chef versucht diesen Zustand herzustellen. Chef liefert von Haus + viele wichtige Ressourcen mit. In Cookbooks kann man darüber hinaus eigene + Ressourcen definieren. + \item[providers] Während Ressourcen nur die Schnittstelle beschreiben, mit + allen Attributen, die gesetzt werden können, ist der Provider eine konkrete + Implementierung. Deswegen muss jede Ressource mindestens einen Provider + besitzen. Es kann mehrere Provider für eine Ressource geben, um zum Beispiel + um mehrere Plattformen/Betriebssysteme abzudecken (z.B. bei Packetmanagern + oder Initsystemen). + \item[recipes] In Recipes werden Ressourcen instantiiert, welche nötig sind + um die gewünschte Aufgabe zu erreichen. Dabei können Abhängigkeiten zwischen + diesen angegeben werden. + \item[templates] Häufig werden dynamisch generierte Dateien benötigt, um zum + Beispiel Konfigurationsdateien zu erzeugen. Chef bindet hierfür die + Templatesprache eRuby (Embedded Ruby) ein. Diese führt in den Templates + Rubycode, der sich zwischen den Tags \emph{<\%} und \emph{\%>} befindet, aus. + Dies erlaubt es Variablen zu interpolieren, sowie If-Statements und + Schleifen. + \item[metadata.rb] In dieser Datei kann der Name des Cookbook, die Version, + eine Beschreibung sowie Abhängigkeiten zu anderen Cookbooks angeben werden. +\end{description} + +\textbf{Durchlauf eines Recipes} +\label{durchlauf_eines_recipes} + +TODO Runlist + +\textbf{Vergleich mit puppet} +\label{vergleich_mit_puppet} + +% vim: set spell spelllang=de_de diff --git a/bericht/chef/chef-services.tex b/bericht/chef/chef-services.tex new file mode 100644 index 0000000..d6329ac --- /dev/null +++ b/bericht/chef/chef-services.tex @@ -0,0 +1,90 @@ +\subsubsection{Einrichtung der Netzwerkdienste} +\label{ssub:einrichtung-der-netzwerkdienste} + +Für die Provisionierung der Netzwerkdienste wurde +\href{http://vagrantup.com}{\emph{vagrant}} verwendet. Dies ein Programm um auf +der Basis von Virtualbox und anderen Virtualisierungslösungen schnell und +reproduzierbar virtuelle Maschinen zu starten. Die Einstellungen hierfür werden +in der datei \emph{Vagrantfile} geschrieben, welches vagrant beim Start +einliest. Vagrant bietet eine gute Integration für Chef. Es kann direkt +eingestellt werden, mit welchen Einstellungen neue virtuelle Maschinen +provisioniert werden sollen. Zum Einsatz kam das Betriebssystem Ubuntu 12.04 +LTS. Das Basisimage hierfür wurde von \emph{opscode}, der Firma hinter Chef, +bereitgestellt. Es wurde ein Netzwerkinterface konfiguriert für die +Kommunikation mit vagrant und ein weiteres Internes für ein virtuelles Netzwerk +zwischen den VMs zum Betreiben der Netzwerkdienste. + +Gestartet wird die VM mit dem Befehl: + +\shellcmd{vagrant up} + +Beim 1. Start wird die VM mit Chef provisioniert. Spätere kann Chef erneut mit +folgenden Befehl gestartet werden: + +\shellcmd{vagrant provision} + +Für bestimmte Funktionen wie geteilte Ordner zwischen VM und Host müssen die +\emph{virtualbox-client-modules} in der VM installiert sein. Diese sind zwar in +vielen Images vorhanden, die es für vagrant gibt. Allerdings muss die +Virtualboxversion des Host mit dem der VM übereinstimmen. Abhilfe schafft das +Vagrantplugin \emph{vagrant-vbguest} (TODO link). Dieses überprüft beim +Start die Versionen und installiert gegebenfalls eine Andere in der VM. + +Als Netzwerkdienste wurden die Protokolle DHCP, DNS und NTP gewählt. Die +VMs wurden in 2 Gruppen geteilt, \emph{Headnodes}, die die genannten Dienste anbieten +und \emph{Computenodes}. Die Computenodes fordern auf dem internen Netzwerk per +DHCP eine IP-Adresse an und nutzen den DNS- und NTP-Dienst des jeweiligen +Headnode. + +Für das Deployment wurden fünf Cookbooks geschrieben: +\begin{description} + \item[bind] + Als DNS-Server wurde bind gewählt. Dieses Cookbook diesen Dienst ein und + fügt die in den Attributen konfigurierten DNS-Einträge hinzu zu den + entsprechenden Zonen hinzu. + \item[dhcp] + Dieses Cookbook richtet den ISC DHCP-Server ein. Neben der Zuordnung von + festen IP-Adressen zu Nodes, kann ein DNS-Server und ein NTP-Server + festgelegt werden. + \item[lctp-network] + Dieses Cookbook ist ein Wrappercoobook um das network\_interfaces + (TODO link) Cookbook. Wrappercookbook werden häufig dazu benutzt um bestehende + Cookbooks aus anderen Quellen um Funktionalität zu erweitern. In diesem Fall + aktiviert das Cookbook für die Computenodes dhcp auf dem interen + Netzwerkinterface. Auf den Headnodes wird eine statische IPadresse gesetzt, + der DNS-Server auf localhost festgelegt und Ipforwarding sowie + Masquerading via iptables für den Routerbetrieb aktiviert. + \item[ntp] + Dieses Cookbook richtet den NTP-Deamon ein, welcher die Zeit zwischen den + einzelnen Knoten synchron halten soll. + \item[main] + Dieses Cookbook fast alle oben genannten Cookbooks für Compute- und + Headnode zusammen. Man könnte dies prinzipiell auch in den jeweiligen + Rollen erledigen. Rollen in Chef haben allerdings den Nachteil, dass diese + nicht versionierbar sind und (bei Chef-server) über alle Umgebungen gleich + sind. Somit ist eine Trennung zwischen Test- und Produktivumgebung + schwierig. +\end{description} + +Es wurden folgende externen Cookbooks verwendet: +\begin{description} + \item[apt] bringt die lokalen Packetquellen auf den aktuellen Stand und + aktualisiert den Packetcache. + \item[network\_interfaces] verwaltet Debians Netzkonfiguration + /etc/network/interfaces + \item[minitest-handler] Sammelt alle Tests in den Cookbooks führt diese + nach der Provisionierung aus (siehe~\ref{chef_minitest_handler}) +\end{description} + +Zur Verwaltung der externen und internen Cookbooks wurde +\href{http://berkshelf.com}{Berkshelf} verwendet. Bei diesem gibt man die +Abhängigkeiten und die gewünschte Version in einer Datei namens Berkssfile an +(vergleichbar mit Gemfile in Ruby). +Berkshelf lädt diese Abhängigkeiten aus verschiedenen Quellen herunter. (per Api +von der Communityseite von Opscode, git, lokal) Für das Zusammenspiel mit +vagrant gibt es das Plugin vagrant-berkshelf (TODO link), so dass die von Berkshelf +verwalten Cookbooks auch in vagrant zur Verfügung stehen. + +TODO Roles und Nodes json + +% vim: set spell spelllang=de_de diff --git a/bericht/chef/chef-task.tex b/bericht/chef/chef-task.tex new file mode 100644 index 0000000..b96dfa2 --- /dev/null +++ b/bericht/chef/chef-task.tex @@ -0,0 +1,13 @@ +\subsubsection{Aufgabenstellung} +\label{ssub:aufgabenstellung} + +\begin{itemize} +\item Analysieren Sie die Funktionsweise von Chef und gehen Sie auf + Unterschiede zwischen Chef und Puppet ein +\item WählenSie zwei Netzwerkdienste aus die während der Lehrveranstaltung + besprochen wurden und erstellen Sie Provisionierungsvorlagen für diese +\item Beschreiben Sie wie die Verifikation von Provisionierungsvorlagen + bei der Bereitstellung von HPC-Software verwendet werden kann +\end{itemize} + +% vim: set spell spelllang=de_de diff --git a/bericht/chef/chef-tests.tex b/bericht/chef/chef-tests.tex new file mode 100644 index 0000000..737642f --- /dev/null +++ b/bericht/chef/chef-tests.tex @@ -0,0 +1,115 @@ +\subsubsection{Verifikation} +\label{ssub:verifikation} + +Wie auch Software müssen auch Provisionierungsskripte getestet werden. +Dies gestaltet sich oft als schwierig, weil nicht immer eine Kopie des +aktuellen Produktionssystem zur Verfügung steht. Mit steigender Komplexität +steigt der Aufwand geschriebene Cookbooks manuell zu testen. Im Folgenden +werden verschiedene Möglichkeiten aufgeführt, wie dies automatisiert werden +kann. + +Die erste und einfachste Methode ist der Befehl: + +\shellcmd{knife cookbook test [COOKBOOKS...]} + +Dieser überprüft den Rubyquellcode und die Templates des Cookbooks auf Syntaxfehler. +Allerdings treten viele Fehler erst zur Laufzeit auf, insbesonderen da Ruby +eine dynamische Programmiersprache. Ein anderes Programm ist foodcritic. Dies +ist eine statische Codeanalyse ähnlich jslint oder perlcritics. Dabei wird der +Rubycode gegen Regelsatz getestet, um so schlechten Stil zu erkennen oder +um Codeingstandards innerhalb eines Projekts einzuhalten. Diesen Regelsatz kann +man durch eigene Regeln erweitern. + +\textbf{Chefspec} +\label{chefspec} + +Chefspec baut auf das in Ruby verbreitete Testframework Rspec auf. Dies ist ein +Vertreter des BDD (TODO mehr Infos zu BDD, Integration von Chefspec). Wie +bereits in Abschnitt ~\ref{durchlauf_eines_recipes} erwähnt, gibt es 2 Phasen +bei der Ausführung von Chef. Bei Chefspec wird die 1. Phase, die (TODO +\$Phase)-phase, durchlaufen und danach die eigenen Tests ausgeführt. Dies hat +den Vorteil, das Tests sehr schnell durchlaufen werden, da keine Änderungen an +einem System vorgenommen werden müssen. Dies hat Vorteile beim Entwickeln, weil +man auf diese 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 aufwendig +aufgesetzt werden müssen. Da Chefspec allerdings nicht wirklich Code auf dem +System ausführt, sind Integrationstest unerlässlich. + +Der folgende Test wurde aus dem NTP-Cookbook +(~\ref{ssub:einrichtung-der-netzwerkdienste}) entnommen. + +\begin{lstlisting} +require_relative '../spec_helper' + +describe 'ntp::default' do + let(:chef_run) do + ChefSpec::Runner.new do |node| + node.set["ntp"]["subnets"] = ["::1", "127.0.0.1", "172.28.128.0 mask 255.255.255.0 nomodify notrap nopeer"] + end.converge(described_recipe) + end + + it "should setup ntp" do + chef_run.should install_package("ntp") + chef_run.should render_file("/etc/ntp.conf").with_content("172.28.128.0") + end +end +\end{lstlisting} + +Im \emph{chef\_run}-Block wird der fiktiven Node Attribute zugewiesen und das zu +testende Cookbook ausgeführt. Das Ergebnis wird in diesem Beispiel in dem Objekt +\emph{chef\_run} gespeichert. Gegen dieses Objekt wird getestet, ob bestimmte +Resourcen korrekt initialisiert wurden. In diesem Fall wird überprüft, ob + +TODO Ausführung + +TODO rake test + +\textbf{Minitest Handler} +\label{minitest_handler} + +\href{https://github.com/btm/minitest-handler}{Minitest Handler} hingegen wird nach jedem Provisionierungsdurchgang +ausgeführt. Im Gegensatz zu Chefspec nutzt es das Minitest Framework, welches +schon mit Ruby mitgeliefert wird. Allerdings kann man durch einbinden, der Zeile: + +\begin{lstlisting} +require "minitest/spec" +\end{lstlisting} + +eine Rspec sehr ähnliche Syntax benutzen. Um Minitest Handler zu nutzen, muss +das Recipe aus minitest-handler-cookbook als erstes Recipe in der node geladen +werden. Minitest Handler durchsucht beim Durchlauf in jedem anderen cookbook, in +den Unterordnern von \emph{files/} nach dem Verzeichnis \emph{test} und lädt +alle Tests aus diesem Verzeichnis. Über die Beschreibungszeile: + +\begin{lstlisting} +describe_recipe "ntp::default" do # +#... +end +\end{lstlisting} + +wird angeben für, welches Recipe der Test gedacht ist (In diesem Fall das +Defaultrecipe aus dem NTP-Cookbook). Wenn das entsprechende Recipe von der Node +ausgeführt wird, wird nach der entsprechende Test nach dem +Provisionierunsdurchlauf ebenfalls ausgeführt. Minitest Handler erweitert Rspec +um nützliche Methoden um den Status des Systems zu überprüfen. Hier ein Beispiel +aus dem bind cookbook, welches in +Abschnitt~\ref{ssub:einrichtung-der-netzwerkdienste} erwähnt wurde: + +\begin{lstlisting} +describe_recipe 'bind::default' do + it "starts the named daemon" do + service("bind9").must_be_running + end + it "should resolve dns" do + assert_sh("dig localhost @localhost") + end +end +\end{lstlisting} + +Die Methode \emph{assert\_sh} überprüft den Exitstatus eines Befehls und schlägt +fehl, wenn dieser ungleich null ist, während der \emph{service} den Status eines +Systemdienst sicherstellt. Es gibt noch weitere Testmethoden, wie das Überprüfen +von Verzeichnissen, Inhalte von Dateien oder Mountpoints. + +% vim: set spell spelllang=de_de diff --git a/bericht/chef/chef.tex b/bericht/chef/chef.tex new file mode 100644 index 0000000..95a0095 --- /dev/null +++ b/bericht/chef/chef.tex @@ -0,0 +1,5 @@ +\subsection{Chef - Provisionierungssystem} +\input{chef/chef-task} +\input{chef/chef-comparison} +\input{chef/chef-services} +\input{chef/chef-tests} diff --git a/bericht/sources.bib b/bericht/sources.bib new file mode 100644 index 0000000..9e654e2 --- /dev/null +++ b/bericht/sources.bib @@ -0,0 +1,8 @@ +@online{chefenterprise, + author = {chef}, + title = {{Enterprise-class features and support }}, + howpublished = + "\url{http://www.getchef.com/enterprise-chef/#features-and-support}", + year = {2014}, + note = "[Online; 06.03.2014]" +}