Das DevOps-Konzept und die Organisations

Real life in Java
Das DevOps-Konzept
und die Organisationsschwächen bei der
Durchführung in
der Praxis (Auszug)
Masroor Ahmad
Die Geschichte von DevOps nahm ihren Anfang mit den sogenannten
„DevOps Days“, die der IT-Experte Patrick Debois das erste Mal im
Jahr 2009 in Belgien initiierte und damit die Grundlage für weitere
Konferenzen weltweit legte, die die Kluft zwischen Entwicklung und
Betrieb thematisieren. Das Programm umfasst in der Regel ein breites
Themenspektrum, neben Grundsatzdiskussionen zur Bedeutung von
DevOps bis hin zu Vorträgen namhafter Vertreter der Szene, die den
aktuellen technischen Stand wiedergeben; der deutsche Ableger tagte
zuletzt 2014 in Berlin. Innerhalb weniger Jahre erreichte die DevOpsBewegung eine enorme Popularität, nicht zuletzt mit der plakativen
Nutzung des DevOps-Begriffs durch die Konfigurationsmanagement
Tools Puppet und Chef. Auch die Online Community trug ihren Anteil zur Verbreitung des DevOps-Gedankens bei: Eine Suchanfrage in
der Google-Blogsuche liefert aktuell über 11 Mio. Treffer, der Hashtag
#devops wird im Minutentakt getwittert.
Die Erfolgsgeschichte von DevOps und eine fehlende Referenz führten
jedoch auch zu einer Reihe von Kontroversen. Unter anderem diskutiert
man über die Frage, ob die Jobbezeichnung „DevOps Engineer“ kompatibel zur ursprünglichen Idee sei. Nicht die Schaffung einer neuen Abteilung mit neuen Rollen stehe laut DevOps im Vordergrund, sondern
vielmehr die bessere Zusammenarbeit der bereits existierenden Kräfte
im Unternehmen.
Systemarchitektur
Die Implementierung eines Softwaresystems beginnt in
der Regel mit dem Softwareentwurf und dem Aufbau
der zugrunde liegenden Makroarchitektur. Soll es sich um eine Zwei-Schichten- oder ein Drei-Schichten Anwendung handeln? Welche Server- und Datenbanktechnologien sollen zum
Einsatz kommen? Neben der Auswahl der Architekturkomponenten und ihrer Aufgabenbereiche legt man sich in der initialen Projektphase auch auf geeignete Frameworks und Serverprodukte fest. Die hierbei getroffenen Entscheidungen haben
einen erheblichen Einfluss auf die zukünftige Qualität der erbrachten Dienstleistungen, insbesondere bei der Realisierung
der nicht-funktionalen Anforderungen.
Dem DevOps-Gedanken nach sollte der IT-Betrieb daher
frühzeitig in die wichtigen Architekturentscheidungen eines
neuen Softwareprojekts einbezogen werden. Im Gegenzug erwarten Entwickler tiefere Einblicke in die Funktionsweise und
E
www.javaspektrum.de
Topologie der Firmennetze, um die Bedürfnisse des Betriebs
besser zu verstehen und eine Sensibilität für Sicherheits- und
Kapazitätsthemen zu entwickeln.
Performance
Auch in Zeiten kostengünstiger Hardware und neuer Rekorde
in der Verarbeitungsgeschwindigkeit von Mikroprozessoren
spielt die Performanceoptimierung von Geschäftsanwendungen eine wichtige Rolle. Zum einen entfaltet sich das Potenzial moderner Hardware erst in vollem Maße, wenn die Rechenleistung tatsächlich auf mehrere Recheneinheiten verteilt wird,
sprich die Algorithmen für die parallele Ausführung optimiert
sind. Zum anderen unterliegen Zugriffszeiten und Latenzzeiten, wie in verteilten Systemen üblich, natürlichen Grenzen.
In der Anwendungsentwicklung herrscht nicht immer Konsens darüber, dass Änderungen an zeitkritischen Systemen
durch Last- und Performancetests begleitet werden sollten, um
frühzeitig Engpässe zu beheben. Dies ist jedoch ein wichtiger
Aspekt des DevOps-Gedankens, denn entwicklungsbedingte
Performanceprobleme schlagen als erstes beim IT-Betrieb auf
und lassen sich nicht immer als solche identifizieren. Weil die
Verwaltung der Systemkapazität in der Verantwortung des ITBetriebs liegt, gerät er oftmals zu Unrecht in Erklärungsnot.
Erst die aufwendige Analyse mit geeigneten Profiling Tools
fördert die Ursachen zutage.
Die Entwicklungsabteilung sollte daher ein vitales Interesse
daran haben, performanceoptimierten und ressourcenschonenden (z. B. Netwerk I/O) Code an den IT-Betrieb auszuliefern. Auf der Codeebene gibt es eine Reihe von gut dokumentierten Performance-Tipps, je nach verwendeter Programmiersprache und Plattform. In Java kann man bereits durch
die richtige Verwendung der Basisbibliotheken (Collections
Framework) erste Erfolge erzielen. Statische Codeanalysen
können helfen, mangelhaften Programmierstil oder Ressourcen-Lecks aufzuspüren. Letztendlich sollten sich Entwickler
bei der Konzeption der Lasttests aktiv einbringen, um eine
möglichst realistische Simulation der Produktivumgebung zu
erreichen.
Sicherheit
Bei der IT-Sicherheit handelt es sich um ein weites Feld, das
beide Abteilungen, Entwicklung und Betrieb gleichermaßen
betrifft. Im Kern geht es der IT-Sicherheit um nichts Geringeres,
als den Schutz der kritischen Systeme, und damit den Schutz
des Unternehmens vor externen und internen Gefahren. Die
Verfügbarkeit der elektronischen Systeme soll sichergestellt
werden, die Vertraulichkeit der Daten gewährleistet, bestehende Risiken sollen minimiert werden.
Thematisch ist ein Großteil der Sicherheitsaspekte bei der ITInfrastruktur angesiedelt, weshalb der IT-Betrieb traditionell
die Hoheit über die einzuleitenden Maßnahmen besitzt. Jedoch
ist die Umsetzung der Sicherheitsrichtlinien fast immer mit zusätzlichem Aufwand auf allen Seiten verbunden, insbesondere bei den Entwicklungsabteilungen, die den Mehrwert nicht
immer nachvollziehen können. Die anwendungsbezogenen
Sicherheitsthemen genießen im Anforderungsmanagement erfahrungsgemäß nicht den gleichen Stellenwert wie die fachlichen Anforderungen. Konflikte sind daher vorprogrammiert.
1
Was nützt eine 64-bit verschlüsselte Übertragung der Formulareingaben, wenn die übermittelten Daten anschließend
im Klartext an Drittsysteme weitergereicht werden? Ebenso
bietet eine öffentlich zugängliche Webapplikation potenziellen Eindringlingen ausreichend Angriffsfläche, wenn die Entwickler schwache Verschlüsselungsalgorithmen nutzen, oder
das sogenannte Cross-Site-Scripting ignorieren. Wie bereits
angesprochen, besitzen die Mitarbeiter aus dem IT-Betrieb traditionell ein solides Grundwissen über die Kryptografie und
sind über aktuelle Sicherheitsfragen gut informiert. Entwickler sollten das vorhandene Expertenwissen im Unternehmen
gezielt abgreifen. Bei genauer Betrachtung ergeben sich vielfältige Möglichkeiten für das gemeinsame Erarbeiten von Sicherheitskonzepten. An sicherheitsrelevanten Themen in der
IT-Industrie mangelt es kaum: Security Updates, Hashalgorithmen, Firewalling, SSL, Public Clouds u.v.m.
Im Gegenzug sind SysAdmins dazu angehalten, den Sicherheitsgedanken nicht zu überdehnen, so dass ein Arbeiten für
die Entwickler bzw. Endkunden unnötig erschwert wird. Eine
ausführliche Diskussion über das Finden eines Gleichgewichts
zwischen Freiheit und Sicherheit würde an dieser Stelle sicherlich den Rahmen sprengen.
Skalierbarkeit
Die Schaffung von hochskalierbaren Anwendungen, die zusammen mit der Unternehmensgröße bzw. dem Kundenstamm wachsen, zählt zu den großen Versprechen des aktuellen Cloud-Trends: CPU- und Speicherressourcen können einem laufenden System nach Belieben hinzugefügt oder weggenommen werden. Die Fähigkeit von Softwaresystemen,
flexibel auf verändernde Lastsituationen zu reagieren, wird gemeinhin als „Skalierbarkeit“ beschrieben.
Ein skalierbares System hat jedoch einen Preis, der zunächst
von den Entwicklungsabteilungen gezahlt werden muss.
Denn nicht jede verteilte Anwendung ist von Anfang an skalierbar oder gar „cloud-konform“. Große Serververbünde, die
über Load Balancer zusammen geschaltet werden, unterliegen
Ausgangsbedingungen, die die Entwickler zunächst schaffen
müssen. Wenn das Anforderungsmanagement die technischen
Merkmale der Skalierbarkeit von Entwicklungsbeginn an berücksichtigt, erleichtert es dem IT-Betrieb, die ausgehändigte Software auf eine skalierbare Plattform zu betreiben. Eine
nachträgliche Anpassung ist immer mit einem höheren Implementierungsaufwand verbunden, wenn nicht gar ausgeschlossen.
Üblicherweise verantwortet der IT-Betrieb die Kapazitätsplanung und muss auf Kapazitätsengpässe zeitnah reagieren.
Da der vertikalen Skalierung physikalische Grenzen gesetzt
sind (z. B. Anzahl freier CPU-Sockel auf einer Maschine), muss
das System notgedrungen horizontal wachsen: Die softwareoder hardwareseitige Lastverteilung übernimmt, wie der Name andeutet, die Verteilung der Nutzeranfragen auf verschiedene, gleichartig aufgebaute Knoten. Neue Knoten können sich
dem Verbund in praktisch unbegrenzter Anzahl anschließen.
Die hierbei gewonnene Ausfallsicherheit ist ein willkommener
Nebeneffekt: Fällt ein einzelner Knoten unvorhergesehen aus,
können die restlichen Knoten die Anfragen des ausgefallenen
Knoten gemeinsam schultern.
2
Ein guter Programmierstil zeichnet sich dadurch aus, dass
zunächst die CPU-Ressourcen eines einzelnen Knoten optimal
genutzt werden. Große, rechenintensive Verarbeitungsroutinen zerlegt man hierzu in Teilaufgaben und führt sie daraufhin
parallel auf mehreren Rechenkernen aus. Moderne Programmiersprache bieten von Haus aus die nötigen Sprachmittel und
Bibliotheken zur Entwicklung derartiger Ausführungsstränge
(Threads) an. Bereits früh haben entsprechende Multi-Threading-Bibliotheken und Entwurfsmuster in Java Einzug gehalten. Seit Version 8 unterstützt Java auch das Map-ReduceProgrammiermodell, das technische Paradigma von Big-DataAnwendungen.
Die Voraussetzungen für den parallelen Betrieb der Software
auf mehreren gleichartigen Knoten ähneln den Vorgaben aus
bekannten Standardarchitekturen für verteilte Systeme (Java
EE). Klassenvariablen gilt es zu meiden; der Zugriff auf das
lokale Dateisystem ist tabu – als Datenablage dient ausschließlich eine zentrale Datenbank, welche allen Knoten gleichermaßen zur Verfügung steht. Dies gilt auch für sitzungsbezogene
Informationen (Session Data). Obwohl moderne Load Balancer
eingehende Anfragen klassifizieren und dedizierten Knoten
zuordnen können (Sticky Sessions), ist die konsequente Einhaltung dieser Regeln aus Skalierungsgesichtspunkten zu bevorzugen. Der Betreuungsaufwand für die Ops-Mitarbeiter sinkt.
Abbildung 1: Schematische Darstellung einer typischen Load Balancing Architektur
06/2015
Robustheit
Die Fehlertoleranz, auch Robustheit genannt, beschreibt die
Fähigkeit eines Systems, auch außerhalb seiner Spezifikation
zuverlässig zu funktionieren. Zu den typischen Laufzeitanforderungen, die ein System an seine Umwelt stellt, zählen beispielsweise das Vorhandensein notwendiger Hardwareressourcen oder der Zugriff auf das Netzwerk. Ein verteilter Persistenzdienst kann seine Kernaufgaben ohne funktionierende
Datenbankanbindung nicht erfüllen.
Der IT-Betrieb wappnet sich vor derartigen, unvorhergesehenen Laufzeitbedingungen mit ausgefeilten Ausfallstrategien,
die beispielsweise redundante Netzwerksegmente vorhalten
oder partielle Backups bis hin zu vollständigen Hot-SpareSystemen vorsehen. Sie greifen bei schwerwiegenden, zum Teil
katastrophalen Ereignissen wie zum Beispiel dem Ausfall ganzer Rechenzentren.
Die Entwicklung kann hier die betriebsseitigen Bemühungen
zusätzlich mit softwareseitigen Vorkehrungen flankieren. Sollte ein zwingend benötigter fremder Dienst im Internet nicht
erreichbar sein, darf das System nicht ohne weiteres anhalten.
Vielmehr kann es eigenständig seinen Betriebsmodus wechseln, eingehende Anfragen eventuell in eine Warteschleife legen und den Vorfall an die Betriebsverantwortlichen melden.
Sobald der besagte Dienst wieder verfügbar ist, kann der Betriebsmodus eigenständig zurückgesetzt und die Verarbeitung
fortgesetzt werden. In Anlehnung an den Begriff „Resilienz“
(Widerstandsfähigkeit) aus der Psychologie spricht man bei
derartig robuster Software auch von „resilienten“ Systemen.
Auf Modulebene kann das Konzept der vertragsbasierten
Programmierung („Design by Contract“) frühzeitig invalide
Dateneingaben zurückweisen, um die Wahrscheinlichkeit von
Laufzeitfehlern bei einer Fehlbedienung zu minimieren.
Continous Delivery
DevOps beschreibt die Automatisierung des Entwicklungsund Bereitstellungsprozesses als wichtigen Stützpfeiler für die
reibungslose Zusammenarbeit der Abteilungen. Dabei kann
ein effizienter und risikoarmer Bereitstellungsprozess ohne
die automatische Ausführung wichtiger Etappen, wie die des
Builds oder des Deployments in einem komplexen Geflecht
aus Kollaboration und Verantwortung nicht funktionieren. Die
Fehlerquote sinkt drastisch, wenn wiederkehrende und aufwendige Aufgaben nicht mehr von Hand ausgeführt, sondern
der Maschine überlassen werden.
Um zuverlässige und schnelle Releasezyklen zu erlangen,
schlagen die Autoren Humble und Farley in ihrem Standardwerk „Continous Delivery – Reliable Software Releases Through
Build, Test And Deployment Automation“ den Einsatz einer überwiegend automatisierten „Deployment Pipeline“ vor. Viele
Unternehmen haben begonnen, Continous Delivery (CD) Prozesse zu etablieren. Mit Hilfe der kontinuierlichen Integration
(Continous Integration - CI) werden bereits neue Codeänderungen zeitnah gebaut und getestet. Der Weg von CI nach CD
gestaltet sich schwieriger, weil nun auch der IT-Betrieb in die
Prozesse eingebunden werden muss. DevOps fordert, diesem
eingeschlagenen Weg weiter zu folgen.
www.javaspektrum.de
Nach einem erfolgreichen Bau und den fehlerfrei ausgeführten Modultests sollte der neue Softwarestand, idealerweise
vollautomatisch, in die Integrations- bzw. Abnahmeumgebungen transportiert werden. Es folgen weitere automatische und
manuelle Tests, sowie Kapazitätstests; mit jedem erfolgreich
durchlaufenen „Stage“ wächst zugleich das Vertrauen in die
Funktionstüchtigkeit des Softwarestandes. Die Codeänderung
wandert dabei schrittweise in die höheren Umgebungen, bis
sie schlussendlich die Produktionsumgebung erreicht. Die konkrete Ausprägung der Deployment Pipeline darf sich durchaus
von dem hier vorgestellten Muster unterscheiden.
Abbildung 2: Ausprägung einer Deployment Pipeline
Infrastructure as Code
Wie bereits angesprochen, haben sich die Anforderungen an
das Konfigurationsmanagement in den letzten Jahren deutlich verändert. Mit dem verstärkten Einzug der Virtualisierung
hat sich nicht nur die Anzahl der Systemknoten schlagartig erhöht, auch die Releasezyklen werden mit Continuous Delivery immer kürzer. Haben die SysAdmins in der Vergangenheit
noch diverse Konfigurationen per Hand vorgenommen, so findet man heute komplexe Systemlandschaften vor, die ohne entsprechend automatisierte Routinen und Skripten nicht zu bewältigen sind.
Die „Infrastructure as Code“ (IaC) Strategie führt den Automatisierungsgedanken konsequent zu Ende. Sie fordert, dass
der Aufbau und die Anpassung der Infrastrukturkomponenten, analog zum Quelltext der zu installierenden Endanwendung, ebenfalls einheitlich in einem Versionsverwaltungssystem vorliegen müssen. Ziel ist es, die Gesamtheit aller Maschinen bzw. Knoten einer Systemumgebung, samt Betriebssystem
und Systemkonfiguration auf Knopfdruck von Grund auf neu
aufzubauen. Die wiederholt auszuführenden und oft fehlerträchtigen Nacharbeiten an einem frisch installierten System
sollen dadurch gänzlich entfallen.
Eine deskriptive Beschreibung der Systemumgebungen ermöglicht eine Vielzahl neuer Anwendungsszenarien, die dem
DevOps-Gedanken Rechnung tragen. Der IT-Betrieb kann auf
Verlangen der Entwicklungsabteilung relativ schnell eine neue
Testumgebung einrichten, die beispielsweise die Verhältnisse
der Produktionsumgebung abbildet. So können die Entwickler
eigenständig die Kompatibilität ihrer neuen Softwarestände
prüfen und gegebenenfalls Änderungswünsche an den Betrieb
frühzeitig melden. Mit IaC unterliegt die Provisionierung der
Server einem transparenten Prozess, der alle Beteiligten gleichermaßen zugutekommt.
Zu den wichtigsten Open-Source-Systemkonfigurationswerkzeugen, die IaC umsetzen, zählen Puppet und Chef. Beide
Tools verwenden einen ähnlichen Ansatz, in dem der Soll-Zu3
ten dominiert wird. Beim
BPM handelt es sich um einen systematischen Ansatz,
um Geschäftsprozesse zu
modellieren, sie auszuführen und zu überwachen –
mit dem Ziel, sie einfacher
steuern und verbessern zu
können. Softwareentwicklung hat als Geschäftsdomäne schon immer mit Entwicklern, Testern und Systemadministratoren als ihren Fachexperten existiert.
Daher fördert das Studium
der klassischen Disziplin
der Geschäftsprozessmodellierung unter dem DevOpsAspekt neue Erkenntnisse
zutage.
Ein sinnvoller Gegenstand der Modellierung im
Abbildung 3: Deklarative Beschreibung einer Betriebssystem Ressource (Benutzer) in Puppet
DevOps-Kontext bietet die
Deployment Pipeline, in der
stand eines Rechnerknotens (Ressourcen, Dienste, etc.) mittels sich zahlreiche, automatisiert ablaufende Prozessschritte mit
manuellen Tasks abwechseln. Die erste Voraussetzung ist eine
einer Programmiersprache deskriptiv festgelegt wird.
geschickte Integration einer Process Engine, derjenigen Instanz, die die Ausführung maschineller Aktivitäten, als auch die
Koordination der menschlichen Akteure sicherstellt, in die beModellierung von DevOps Prozessen
stehende DevOps-Toollandschaft. Damit versetzt man die ProDie Vertreter der Blogger-Szene bestätigen, dass DevOps kein cess Engine in die Lage, die automatisierten Build-, Test- und
ausschließlich technologisches Problem betrachtet, sondern in Deploymentschritte, planmäßig und eigenständig zu starten.
erster Linie ein Geschäftsproblem. Dies gibt Anlass, sich mit Menschliche Akteure der Deployment Pipeline können über
Business Process Management (BPM) auseinanderzusetzen – übliche Kommunikationskanäle ebenfalls vollautomatisch an
einem Feld, das bisher weitestgehend von Business-Analys- ihre Aufgaben erinnert werden.
Abbildung 4: Strategisches Prozessdiagramm einer Deployment Pipeline
4
Abbildung 5: Integration der Process Engine in einer DevOps-Toollandschaft
06/2015
Ein weiterer Anwendungsfall für BPM wäre die automatische Initiierung von Deeskalationsprozessen. Die Engine ermittelt auf Grundlage aktueller Monitoringwerte eine präzise
Definition der hierfür benötigten Akteure und Aktivitäten. Auf
diese Weise führt man, ganz im Sinne von DevOps, einen geregelten Umgang mit Fehlern ein.
Auf abstrakter Ebene bildet jedes Entwicklungs- und
Deployment Werkzeug einen eigenen Geschäftsprozess ab.
Zum Beispiel beginnt der automatische Snapshot-Build auf
einem CI-Server zu einem definierten Startzeitpunkt (CodeCheck-in) und endet mit einem Ergebnis, den erfolgreich
gebaut Zielartefakten im Artefact-Repository. Es wäre nicht
Aufgabe einer Workflow Engine, die bereits existierenden
Prozesse abzulösen. Stattdessen obliegt ihr die Aufwertung,
Kapselung und Integration der Prozesse in eine bestehende
DevOps-Tool-Landschaft.
Masroor Ahmad ist freiberuflicher Trainer und
Softwareberater im Java-Umfeld und unterstützt
Unternehmen bei der Planung und Entwicklung
komplexer Geschäftsanwendungen. Seine Schwerpunkte liegen im Aufbau von Build- und DeploymentInfrastrukturen sowie dem Qualitätsmanagement.
Aktuell unterstützt er als externer Mitarbeiter das
Konfigurations- und Releasemanagement des DVAG
Online-Systems.
E-Mail: [email protected]
Das komplette ebook zum Thema DevOPs
lesen Sie unter bit.ly/devops_ebook
www.javaspektrum.de
5