Schlagwörter

, , , , ,

Eine vernünftige Buildumgebung gehört in den Werkzeugkoffer eines guten Softwareentwicklers. Ohne diese ist man mit jeder Menge manuellem Kleinkram beschäftigt, der einem die Zeit für die Entwicklung nimmt und kann keine Software in vernünftiger Qualität ausliefern.

So sehr ich das in meinen professionellen Projekten beherzige, so deletantisch habe ich mich anfangs bei meinen privaten Projekten angestellt. Da wurden Sourcen per Mail zwischen Rechnern ausgetauscht, manuell erstellte Jars auf Server deployed und andere Sünden begangen. Doch dann kam jener glorreiche Tag, an dem im Java Magazin ein Artikel mein Interesse für Amazon Webservices weckte. Schon ziemlich bald setzte ich mir einen Server auf, auf dem ich ein SVN hostete. Nach und nach baute ich den Server dann weiter aus.

Bevor jemand fragt: Ja ich lebe damit, dass Amazon Zugriff auf meinen Sourcecode hat. Ja, ich habe einen Teil meiner privaten Daten und auch Schlüssel auf einem Server im Nicht-Europäischen Ausland liegen. Und nein, ich glaube nicht, dass es Angestellte bei Amazon gibt, die nichts besseres zu tun haben, als sich durch die etlichen Petabyte an Daten in ihren Rechenzentren zu wühlen, um meine Daten zu klauen.

Folgende Dienste bietet mein Server an:

  • Versionsverwaltung: Angefangen hat alles mit einem SVN. Inzwischen fühle ich mich ziemlich Oldschool und werde wohl auch noch ein Git installieren 😉
  • CI-Server: Um Binaries zu erzeugen, automatisierte Tests durchzuführen und meine Deployment-Pipeline durchzulaufen, habe ich einen Jenkins installiert.
  • Binary-Repository: Brauche ich weniger, um Binaries mit anderen Team-Mitgleidern auszutauschen, sondern als zentralen Bestandteil meiner Deployment Pipeline, die fürs Staging Binaries aus dem Repository lädt. Hierfür verwende ich Nexus.
  • Konfiguration-Management: Um Kosten für die Testumgebung zu sparen, ziehe ich meine Testinstanzen on demand hoch. Für die Konfiguration der Instanzen verwende ich Puppet, der Buildserver dient auch als Puppet Master.

Zugegeben ziemlich viele Diente auf der einen Kiste. Da es sich aber um kleine Projekte handelt, mache ich mir keine Sorgen, dass das nicht skaliert. Tatsächlich kam ich bis vor kurzem mit einer Micro-Instanz aus, die gerade mal 615 MB Speicher hat.

Doch erst mal der Reihe nach. Welche Dienste von AWS brauchen wir überhaupt? Wir brauchen einen Server, auf dem wir die ganze Software installieren können und wir brauchen eine Sicherheit, dass die Daten (insbesondere die Sourcen), die wir ablegen nicht plötzlich durch Datenfehler weg sind. 3 Dienste sind für uns interessant:

  • EC2 (Elastic Compute Cloud): Dieser Dienst stellt uns den eigentlichen Server mit CPU, Speicher und Betriebssystem zur Verfügung. Dieser ist die Ausgangsbasis meines Buildservers. Zu beachten bei EC2 ist, dass Amazon keinerlei Gewährleistung für die Verfügbarkeit von Server oder auch nur einen konsistenten Zustand des unterliegegenden Filesystems übernimmt.
  • EBS (Elastic Block Storage): Dieses ist einer der vielen Persistenz-Dienste von AWS. Im Wesentlichen kann man EBS mit einem Storage aus einem SAN vergleichen. Es kann ins Betriebssystem gemountet werden und erlaubt schnelle Zugriffe. EBS Volumes wird 99,5% Bestängigkeit pro Jahr zugesichert => Mit einer Wahrscheinlichkeit von 0,5% verliert man in einem Jahr alle seine Daten auf dem Drive
  • S3 (Simple Storage Service): Das ist Amazons Persistenz-Dienst fürs Grobe. Man kann TB-weise Daten ablegen, hat diese bei Bedarf direkt per http im Zugriff und eine zugesicherte Beständigkeit von 99,999999999%. Der Preis dafür ist, dass es sich um einen Webservice handelt, der nicht direkt gemountet werden kann und entpsrechend langsam ist.

Das ganze wird wie folgt zusammengestöpselt:

ScreenHunter_01 Apr. 21 22.23

Der Buildserver selber ist eine Ec2-Instanz, auf der alle Tools installiert sind. Diese werden einmalig manuell installiert, anschließend wird aus der Installation ein Image erstellt, aus dem man den Server jederzeit wieder herstellen kann. Da sich an der Serverkonfiguration selber nicht so viel ändert, ist das recht schwergewichtige Erstellen eines Images als Backup ein gangbarer Weg.

Anders sieht es bei den Daten aus, die durch die Tools erzeugt werden. Diese ändern sich ständig (mit jedem Commit) und haben einen hohen Wert in Form von Arbeit, die drin steckt. Diese brauchen eine höhere Zusage an die Datensicherheit als 0. Daher wird ein EBS Volume erzeugt und dem Buildserver zugewiesen. Das Home für die genutzten Tools wird auf diesem Volume angelegt.

Da 99,95% Beständigkeit nicht die Welt sind und Daten auch mal durch Layer-8 Fehler verloren gehen können, erzeuge ich regelmäßig ein Snapshot des Daten-Volums, das dann in S3 abgelegt wird.

Der Jenkins selber hat Jobs, die andere EC2-Instanzen starten und stoppen, um Test-Instanzen und Last-Generatoren zur Verfügung zu haben.

So haben alle Dienste, die ich zum Glücklichsein bauche, ein Zuhause gefunden und werden optimal gesichert. Das Sichern des Daten-Volumes und das Erzeugen des Images sind Jenkins Jobs, die manuell oder zeitgesteuert werden können. Das hat was für sich: Der Jenkins ha Jobs, um sich selbst zu sichern.

Kosten

Die Aufschlüsselung der Kosten ist bei AWS sehr feingranular nach Laufzeit von Instanzen, belegten GB, I/O-Zugriffen, …

Um ein Gefühl für die Zahlen zu bekommen: Mein Daten-Volume 10 GB groß. Für die gesamte Persistierung inkl. Backups gebe ich ~€2 / Monat aus. Spannender weil teurer sind die EC2 Instanzen. Als Buildserver habe ich bis vor kurzem die Micro-Instanz verwendet, diese kostet $0,02 pro Stunde. Das macht pro Monat ~$15,36 oder ~€11. Verbessert wird die Bilanz durch einen kostenlosen Schnupperkurs in AWS, bei dem man 1 Jahr lang einige Dienste von Amazon in geringem Umfang kostenlos testen kann. Die Verwendung einer Microinstanz ist da drin. Meine Testserver sind m1.small-Instanzen, diese kosten $0,044 pro Stunde. Mit einer Stunde komme ich für meine automatisierten Tests aus, damit kostet mich jedes Commit noch mal zusätzliche 3 c€nt.

Leider komme ich seit kurzem nicht mehr mit der Microinstanz als Buildserver aus, da der physikalische Speicher für einen Buildjob nicht mehr ausreicht. Mit der m1.small wäre ich jetzt bei €25 pro Monat. Da hat bei mir jetzt der Geiz zugeschlagen, und ich habe mich auf die Vorteile von Cloud besonnen: „Nimm nur was du brauchst, zahle was du nimmst“. Ich entwickele keine 24h am Tag und arbeite nicht mal annähernd jeden Tag an meinen privaten Projekten. Warum soll ich dann 24/7 einen Buildserver bezahlen?

Also habe ich mich noch mal hingesetzt und die Start-Skripte des Servers geradegezogen, so dass dieser ohne manuelles Eingreifen nach einem Neustart alle seine Dienste bereitstellt. Dann habe ich mir eine dynamischen Dns-Adresse bei Freedns geholt (Dyndns ist ja bald nicht mehr kostenlos) und mit den EC2 Api Tools Start/Stop Skripte erstellt und auf meinem Desktop abgelegt. Nun ruht mein Buildserver, wenn ich nicht gerade am Werkeln bin und kostet mich kein Futter. Wie sich das auf meine Rechnung auswirkt, kann ich noch nicht sagen, ich gehe aber davon aus, dass ich nun trotz mehr Power bei deutlich unter €10 pro Monat liege.

Advertisements