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
© Copyright 2024 ExpyDoc