Wir bei VSHN betreiben Applikationen auf Servern und Container Plattformen für Kunden mit verschiedensten Anforderungen. Dabei bilden neben dem Konfigurationsmanagement und der wöchentlichen Maintenance auch die täglichen Backups und natürlich das Monitoring die zentralen Punkte des proaktiven DevOps Betriebs. Bei aktuell über 600 managed Servern mit mehr als 30’000 Services wäre die manuelle Konfiguration sowie das Tuning des Monitorings und der Umsysteme wie InfluxDB, Grafana, etc. recht mühsam – darum haben wir dies komplett automatisiert.
In diesem Blog-Post zeigen wir, wie wir dies bewerkstelligen und wohin die Monitoring-Reise bei VSHN geht.
Architektur
Icinga2 ermöglicht ein komplett verteiltes Monitoring Setup, in dem auf jedem zu überwachenden System eine Icinga2 Instanz läuft. Jeder Client verbindet dann, meistens mit einer ausgehenden TCP Verbindung, verschlüsselt und über x509 authentifiziert, zur Master- oder der überliegenden Satelliten-Zone. Dies ist wichtig, da wir oft Systeme im Enterprise Umfeld betreiben, bei denen wir dann meistens auf einem Jumphost oder dediziert einen Satelliten betreiben. Anschliessend benötigt ausschliesslich dieser eine Verbindung ins Internet zu unserem Monitoring Master. Des Weiteren kann so ein Server tagelang offline sein und trotzdem haben wir rückwirkend die komplette History und die Performance Daten (man kann auch rückwirkend Performance Daten in die InfluxDB schreiben), weil jede Icinga Instanz lokal ein Replay Log speichert und dieses anschliessend wieder an die überliegende Zone senden kann. Eine Zone kann auch aus mehreren Icinga2 Instanzen (Servern) bestehen, um die Last zu verteilen und die Verfügbarkeit zu erhöhen. Für die Authentifizierung und Autorisierung der VSHN- und Kunden-Benutzer ist Icingaweb2 ausserdem an unser zentrales LDAP angebunden. Eine Integration mit Grafana ermöglicht die Vorschau von Performance Data Grafiken direkt in Icingaweb2. Grafana greift auf InfluxDB zu, die wiederum von der Icinga2 Master Instanz mit Performance Daten befüllt wird.
Automatische Konfiguration
Alle unsere Server werden vollständig automatisiert mit Puppet konfiguriert. Dabei weisen wir via Hiera den Servern Rollen zu. Eine Rolle besteht wiederum aus Puppet Profilen (VSHN eigene Puppet Module, die meist auf einem Puppet Base Modul aufbauen). Das Profil steuert immer auch Backup, Firewall und Monitoring. So ist sichergestellt, dass jeder Server eine korrekte Backup-Konfiguration und die richtigen Firewall Rules hat und eben auch automatisch im Monitoring eingerichtet wird. Das heisst, es ist ausgeschlossen, dass ein managed Server nicht im Monitoring eingerichtet ist.
Cluster Konfiguration
Ein Icinga2 Cluster wird immer mittels Zonen und Endpoints konfiguriert. Zonen können mehrere Endpoints (Server mit Icinga2 Instanz) enthalten.
Die manuelle Konfiguration dazu würde vereinfacht so aussehen:
Das muss dann noch auf allen beteiligten Server so gemacht werden. Ausserdem müssen neben der Icinga2 Grund- und Feature-Konfiguration entweder die Icinga2 eigene x509 PKI konfiguriert und verwendet oder die Zertifikate auf andere Weise ausgestellt und verteilt werden. Details zur manuellen Konfiguration sind hier zu finden: https://www.icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/ Bei uns wird das natürlich alles via Puppet gemacht. In der Regel reicht folgende Konfiguration aus Hiera (Beispiel für einen Client, der zu einem Satelliten verbindet): Beispiel Client hinter Satellite
profile_icinga2::parent_zone: 'sat1.vagrant.dev'
profile_icinga2::parent_endpoints:
'sat1.vagrant.dev':
host: '192.168.12.102'
profile_icinga2 kümmert sich dann um alles, inklusive der Zonen / Endpoint Konfiguration und konfiguriert die sowieso vorhanden Zertifikate der PuppetCA für die Icinga2 API. Das offizielle Puppet Modul für Icinga2 gibt es hier: https://github.com/Icinga/puppet-icinga2
Host und Service Checks – Konfigurations-Flow
1. Puppet Run auf einem Server inkludiert profile_icinga2 und Service Profile (z.B. profile_mariadb), Beispiel Hieradata:
3. Puppet run auf Monitoring Master 4. Im selben Puppet run auf dem Monitoring Master werden alle Host Objects und Service Objects gesammelt und in Icinga2 angelegt 5. Die Hosts und Services werden im Config Sync Verzeichnis (zones.d) der jeweiligen Client Zone von Puppet angelegt 6. Icinga2 config check wird von Puppet durchgeführt und Icinga2 reloaded 7. Icinga2 synchronisiert die Config via Top-Down-ConfigSync auf alle Satelliten und Clients
Jede Satellite und Client Instanz bekommt dabei nur die Config, die ihn auch wirklich betrifft
Jede Instanz validiert und aktiviert die Config
8. Icinga2 Satelliten syncen die Configs auf ihre Clients 9. Check ist im Monitoring:
Die Nachteile von Exported Resources
Puppet ist unser primäres Konfigurationsmanagement und Automatisierungs-Werkzeug. Allerdings ist bei der Verwendung von Exported Resources immer Vorsicht geboten.
Verlust der PuppetDB Daten führt zum Wegräumen aller Hosts und Services im Monitoring, was sich zwar wieder – nachdem jeder Server wieder einen Puppet run gemacht hat – von selbst „heilt“. Trotzdem unschön.
Die ganze Sache ist sehr träge, da jede Änderung einen Puppet run auf dem Server (Icinga2 Client) und auf dem Icinga2 Master benötigt, bevor die Änderungen wirksam sind.
Der Puppet run auf dem Monitoring Master sammelt tausende Zone-, Endpoint-, Host- und zehntausende Service-Objects Resources zusammen und ergibt somit einen Puppet run, der locker länger als 20-30 Minuten dauert. Das System wird somit noch träger.
Mögliche Lösungen
Wir wollen in Zukunft auf das Einsammeln von Exported Resources verzichten und Icinga2 direkt mit den Daten aus der PuppetDB konfigurieren. Warum? Weil ein Puppet Run auf fast allen Servern im 1-2 Minuten-Bereich oder weniger liegt, der Puppet Run auf dem Monitoring Master jedoch das Problem ist. Es gibt auch bereits eine Lösung: Icinga2 Director mit PuppetDB Anbindung
Dabei würden die Server weiterhin Host und Service Objects via Puppet exportieren, jedoch sammelt ein Import / Sync Job (3) des Directors die Objekte direkt aus der PuppetDB zusammen, filtert und konfiguriert daraus Icinga2 Objekte.
Resultat
Nur noch ein schneller Puppet Run auf den eigentlich betroffenen Server, Änderungen sind innert 1-2 Minuten in Icinga2 aktiv. Der Puppet Run auf dem Monitoring Master gerät in der Hintergrund und ist maximal noch für die Zonen Konfiguration und PKI zuständig, welche im Vergleich zu Service Checks und dem damit verbundenen Tuning eher statisch ist.
Verglichen mit der manuellen Konfiguration von Hosts und Services in einem Monitoring System oder der für uns fast komplett unbrauchbaren Auto-Discovery Funktionen anderer Systeme, haben wir mit top Open Source Software eine Lösung geschaffen, die unsere Anforderungen erfüllt, sich komplett in unsere DevOps Arbeitsweise integriert und uns somit den proaktiven Betrieb für unsere Kunden ermöglicht sowie extrem vereinfacht. Es gibt aber an zahlreichen Punkten Verbesserungspotential und uns wird es darum sicher nie langweilig. Mehr zu Distributed Monitoring mit Icinga2: https://www.icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/ Dies wird sicher nicht der letzte Blog Post zu Icinga2, Icinga2 Director, Monitoring usw. gewesen sein.
Marco Fretz
Marco ist einer der General Manager von VSHN und Chief Operating Officer.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Einen eigenen Tomcat Server zu betreiben, kann unter gewissen Umständen ein aufwendiges und mühsames Unterfangen sein. Daher haben wir mithilfe von Puppet ein eigenes Tomcat-Hosting-Profil entwickelt. Dabei greifen wir auf das bestehende Puppet Modul von Puppetlabs zurück. Ziel dieses Puppetmodules ist es, in kurzer Zeit einen Tomcatserver bereitzustellen, der alle nötigen Konfigurationen beinhaltet sowie in einer einheitlichen und standardisierten Art und Weise aufgesetzt ist. So soll ein Update der Tomcat Version einfach und schnell möglich sein.
In diesem Blog-Post erläutern wir kurz, was unser Puppet-Modul alles kann und zeigen auf, wie einfach es ist, eine neue Tomcat Instanz aufzusetzen.
Architektur
Bevor wir zur Beschreibung des eigentlichen Moduls kommen, zeigen wir kurz auf, welche Komponenten installiert und konfiguriert werden.
Im oben stehenden Diagramm sehen wir die Grundarchitektur eines klassischen Tomcathostings. Wir verwenden für unser Setup:
ein Nginx als Reverse-Proxy für die SSL-Terminierung
optional Varnish für das Caching
Mysql/Mariadb und/oder PostgreSQL als Datenbank-Server
Der komplette Server lässt sich dabei in einem yaml-file konfigurieren:
Dies reicht schon, um einen Server mit Tomcat7 sowie Tomcat8 zu installieren, sowie zwei Instanzen, die jeweils einen der beiden installierten Tomcats verwendet. Die Konfiguration im oben stehenden Listing installiert unter /opt/tomcat8.5.15 sowie unter /opt/tomcat7 jeweils einen Tomcat. So werden zwei neue User angelegt (mytomcathosting und legacy_tomcathosting) mit dem Homeverzeichnis unter /home (default ist /var/lib/tomcat, wenn tomcat_base nicht angegeben wird). Dort wird von Puppet im Unterordner tomcat/ die Verzeichnisstruktur für eine Tomcatinstanz eingerichtet. Des Weiteren erstellt Puppet auch die Konfigurationsdateien von Tomcat im Ordner: tomcat/config/. Für mytomcathosting wird zusätzlich ein Ordner static im Homeverzeichnis angelegt. Wenn wir uns die generierte nginx config genauer ansehen, sehen wir, dass für mytomcathosting eine zusätzliche Location für static content konfiguriert wurde. Zudem leitet die proxy_pass Direktive nicht zur Tomcatinstanz, sondern zum installierten Varnish. Damit Varnish die verschiedenen vhosts unterscheiden kann, setzten wir zusätzlich den varnish_host Header: mytomcathosting.com Nginx config server
Die angegebenen Zertifikate wurden via Let’s Encrypt erstellt und werden automatisch erneuert. Zusätzlich wird für mytomcathosting eine mariadb Datenbank und für legacy-tomcathosting eine PostgresSQL Datenbank konfiguriert. Damit sichergestellt ist, dass die Tomcat Instanzen auch laufen, erstellt unser Puppet Modul Systemd Unit-Files. Dabei wird als CATALINA_HOME der Pfad zum ausgewählten Tomcatserver verwendet und als CATALINA_BASE der Pfad zum Tomcatverzeichnis der Instanz. Das Unitfile für mytomcathosting sieht daher wie folgt aus: mytomcathosting Unitfile
Backup und Monitoring gehören bei uns zur Selbstverständlichkeit. So wird jede konfigurierte Instanz automatisch ins Backup aufgenommen (User Homeverzeichnis, sowie DB Dumps). Monitoringchecks, die überprüfen, ob die Tomcat Instanzen laufen, werden automatisch eingerichtet. Ebenfalls vollautomatisch wird geprüft, ob der konfigurierte Servername erreichbar ist und einen validen HTTP Code zurückgibt.
Tomcat aktualisieren
Eine bestehende Instanz auf eine neuere Tomcatversion zu aktualisieren ist sehr einfach und in wenigen Minuten erledigt. Dabei muss nur im profile_tomcathosting::servers Hash ein neuer Server mit der gewünschten Version installiert werden und dann in der zu aktualisierenden Instanz im tomcat_serverFeld referenziert werden. Sollte ein Tomcat Server nicht mehr verwendet werden, kann dieser durch das Setzen des ensure: ‚absent‘ Parameters im profile_tomcathosting::servers Hash einfach entfernt werden.
Fazit
Der Betrieb einer Tomcatumgebung ist dank unserem Puppet Modul sehr einfach, schnell und zuverlässig. Dank dem modularen Aufbau der Puppet Module, können wir mit sehr geringem Aufwand verschiedene Tomcat Szenarien abdecken. In nur 15 Minuten können wir eine neue VM (z.b. bei Cloudscale.ch) hochfahren und mit Puppet so konfigurieren, dass wir eine einsatzbereite Tomcatumgebung haben.
Nicolas Bigler
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Alles über Update-Prozesse und Paketaktualisierungen auf verteilten Systemen
2. Juni 2017
Die zunehmende Virtualisierung von Maschinen hat viele Vorteile, bringt aber auch eine Reihe von Herausforderungen mit sich. Eine davon ist die kontinuierliche Aktualisierung der Pakete auf einer stetig wachsenden Anzahl von Systemen. Das eine Mal soll ein aktueller Sicherheitspatch möglichst zeitnah eingespielt werden, ein anderes Mal muss die Applikation des Kunden im vordefinierten Zeitfenster auf den neuesten Stand gebracht werden: Die Anforderungen sind unterschiedlich und nicht immer einfach unter einen Hut zu bringen. Und je mehr der Serverpark wächst, desto schwieriger wird es, die Übersicht zu wahren.
Bei VSHN machen wir Systemupdates üblicherweise einmal pro Woche, jeweils dienstags. Dies ermöglicht es uns, bei eventuellen Problemen in aller Ruhe reagieren zu können, bevor alle ins Wochenende abgerauscht sind und lässt gleichzeitig zu Beginn der Woche genügend Zeit um aktuelle Probleme wahrnehmen und entsprechend planen zu können. Im Laufe der Zeit sind wir auf so manche Herausforderungen gestossen, die die Problematik mit sich bringt. Nicht für alle haben wir bereits befriedigende Lösungen gefunden – bei einigen scheint es uns gar keine „wirkliche“ Lösung zu geben – doch möchten wir hier die Möglichkeit wahrnehmen, unsere Überlegungen und Lösungen zu einigen der Schwierigkeiten darzulegen, die wohl verbreiteter auftreten dürften.
Kundeninformation
Viele Aktualisierungen betreffen Details: es werden spezifische Fehler gefixt, von denen der Kunde üblicherweise gar nichts mitbekommt. Innerhalb einer OS-Revision sollten Updates normalerweise die Funktionsweise nicht verändern (vorausgesetzt, Programmfehler wurden nicht explizit ausgenutzt). Dennoch gibt es immer wieder Aktualisierungen, die Kernfunktionalitäten des Kundensystems betreffen – ein Update der eingesetzten Datenbanksoftware zum Beispiel, oder des Webservers – oder einen Neustart von Teilen des Systems, manchmal auch der ganzen Maschine erfordern. In jedem Fall ist damit zu rechnen, dass ein Serviceunterbruch stattfindet, und sei es auch nur für wenige Sekunden. Entsprechend ist es wichtig, dass der Kunde rechtzeitig und umfassend informiert ist. Dies gestaltet sich aber nicht immer einfach, da die Kundenbedürfnisse teils sehr unterschiedlich sind:
Die meisten unserer Kunden verstehen Deutsch und wünschen auch, in ihrer Muttersprache zu kommunizieren. Mit anderen hingegen wird Englisch gesprochen, wenn nicht gar Portugiesisch, Holländisch oder Finnisch.
Ein individuelles Ansprechen der Kunden mit Namen ist wünschenswert, aber bei manueller Ausführung sehr zeit-intensiv und tendenziell fehleranfällig.
Die verschiedenen Systeme haben verschiedene Anforderungen: einen Kunden mit mariadb interessiert es nicht, ob ein Upgrade von postgresql ansteht und jenem, der nginx einsetzt, sind die Sicherheitsprobleme von Apache egal.
Je nach SLA („Service Level Agreement“) findet die Ausführung zu verschiedenen Zeiten statt. Manche Kunden wünschen die Aktualisierung aus Kostengründen stets zu Bürozeiten, andere nur diejenigen von unkritischen Paketen ohne erwartete Auswirkung auf die Kundenapplikation und bei dritten wiederum finden alle Updates grundsätzlich im „Maintenance Window“ in der Nacht statt. Idealerweise wird dem Kunden die geltende Abmachung regelmässig kommuniziert – und zwar rechtzeitig vor dem Update, so dass er falls nötig für diese Woche ein anderes Vorgehen beantragen kann – zum Beispiel, weil an diesem Tag eine Präsentation stattfindet.
Ursprünglich informierten wir jeden Kunden einzeln per E-Mail, doch konnte sich dieses Modell nicht allzu lange halten. Nur schon aus Zeitgründen kamen wir nicht umhin, stattdessen auf eine generelle Webseite zu verweisen, auf der über die jeweils anstehenden Subsysteme informiert wird. Dafür setzen wir heute Cachet ein und benutzen es auch als generelle Status-Informationsseite bei auftretenden Störungen. Der Kunde kann sich die Informationen selbstständig abonnieren und erhält damit nicht nur die wöchentliche e-Mail über anstehende Updates automatisch, sondern wird auch zeitnah informiert, wenn einmal generelle Probleme mit der Infrastruktur auftreten. Der Server läuft selbstverständlich in einem anderen Rechenzentrum und in einem unabhängig gerouteten Netz, damit bei eventuell auftretenden Problemen auch tatsächlich informiert werden kann. Gibt es schliesslich während des Update-Prozesses Schwierigkeiten, so sollen die Kunden auch darüber zeitnah informiert werden – so detailliert wie nötig (aber auch nicht übertrieben pointiert) und mit einer Angabe, wie wir planen, die Herausforderung in Zukunft anzugehen.
Checkliste
Mitarbeiter, die selbst nicht an der Aktualisierung teil nahmen, sollten zumindest grob darüber Auskunft geben können, was geschah und weshalb. Gerade wenn einmal etwas Gröberes schief läuft und die ausführenden Mitarbeiter vielleicht bis frühmorgens mit Reparaturarbeiten beschäftigt waren, ist es wichtig, dass ausgeschlafene Kollegen informieren können. Eine entsprechende Dokumentation ist deshalb unumgänglich, wenn auch – gerade, wenn’s mal wieder etwas länger dauerte – nicht immer ganz einfach fertigzustellen. Wir setzen auf eine technisch simple, aber in der Praxis recht effektive Checkliste in unserem internen Wiki; das zugehörige Template wird fast jede Woche angepasst, erweitert und mit Links zu Hinweisen, wie bei eventuellen Problemen vorgegangen werden kann versehen. Nach jeder Gruppe von Servern die gleichzeitig abgearbeitet wurden, wird alles Unvorhergesehene protokolliert und das entsprechende Häkchen gesetzt. Dies ermöglicht es uns auch, im Nachhinein nachzuvollziehen, wo der Prozess noch verbessert werden kann.
Aktualisierungstools
Die Effizienz der Updates steht und fällt mit dem verwendeten Werkzeug. Leider ist uns bis anhin kein abschliessend befriedigendes Tool untergekommen; die Umsetzung einiger wünschenswerter Features ist aber auch nicht ganz trivial. Da wir momentan nur Debian- oder RedHat-basierte Linuxdistributionen einsetzen, reicht es glücklicherweise bisher zumindest aus, dass das eingesetzte Tool nebst apt und deb auch noch yum/dnf und rpm versteht. Zur Zeit setzen wir apt-dater der IBH IT-Service GmbH ein, das wir im Laufe der Zeit in der Konfiguration an unsere Bedürfnisse angepasst haben. Es gibt durchaus noch Verbesserungspotential, aber der Aufwand, selbst etwas zu entwickeln dürfte doch ziemlich hoch sein. Folgende Anforderungen wären grundsätzlich wünschenswert:
Schnelle Übersicht über anstehende Aktualisierungen. Eine Idee wäre, anstatt zu jedem Server die veralteten Pakete aufzulisten, den umgekehrten Ansatz zu implementieren: Eine Liste aller Pakete, die auf mindestens einem Host ein Update benötigen. Super wäre dann ein Interface, in dem man unkritische Pakete ausblenden könnte (Stichwort „Tinder-Style“), um sich schnell auf die wesentlichen, kritischen Pakete zu konzentrieren.
Updaten soll einfach sein – aber doch nicht zu einfach. Es ist in der Vergangenheit schon vorgekommen, dass Server versehentlich aktualisiert wurden, weil ein einzelner Tastendruck eine ganze Reihe von Aktionen ausführen kann – praktisch nicht unterbrechbar. Dass „Update“ im apt-Jargon dann auch noch fürs Updaten der Metainformationen (und nicht der eigentlichen Pakete) steht macht die Ausgangslage auch nicht einfacher. In der Praxis ist dies aber nur ein Problem, wenn stets neue Mitarbeiter die Upgrades übernehmen.
Nebst der Update-Funktionalität sollten auch auto-removes automatisiert ausgeführt werden können.
apt-dater parst die Ausgaben der apt-Prozesse auf den Zielsystemen und warnt zum Beispiel bei Vorkommen des Worts „error“. Prinzipiell eine gute Idee – aber wenn der Update-Prozess den Satz „no error occured“ enthält kann das Abnicken jeder einzelnen Meldung ziemlich mühsam werden. Dieses Problem haben wir mittlerweile mittels detaillierterer Konfiguration lösen können.
Anders als yum verlangt apt standardmässig gerne mal eine manuelle Intervention. Das hat durchaus seine Vorteile; auch hier gilt aber: muss das auf jedem Server einzeln bestätigt werden (teilweise auch mehrfach, wenn beispielsweise noch mehrere ältere Kernel installiert sind), so kann einiges an Zeit verloren gehen.
Paket – Cache
Ein Problem, das uns lange beschäftigte, war der Umgang mit Repositories, die zeitweise nicht erreichbar oder in inkonsistem Zustand sind. Gerade bei Ubuntu-Mirrors kommt es immer mal wieder vor, dass die Indizes nicht korrekt erstellt werden und eine Viertelstunde gewartet werden muss, bis der nächste cronjob diese flickt. Das bedeutete dann Zwangspausen – manchmal mehrmals täglich. Auch gibt es immer mal wieder Pakete, die während des Tages neu hinzukommen. Werden diese dann eingespielt, so geht das „Kanarienvogelprinzip“ – wir wollen zuerst auf Staging- und weniger wichtigen Systemen updaten, um eventuelle Probleme frühzeitig zu erkennen – verloren. Und last but not least sind viele Mirrors so konfiguriert, dass sie nur eine begrenzte Zahl von Anfragen von einer IP oder einem IP-Range zulassen, um DOS-Attacken zu verhindern. Kommen nun eine grosse Anzahl von Anfragen praktisch gleichzeitig, zum Beispiel von einem Kunden, bei dem alle Systeme hinter einer gemeinsamen Firewall stehen, so kann nur ein kleiner Teil davon beantwortet werden und der Vorgang muss mehrere Male wiederholt werden, bis alle Systeme einmal bedient wurden. Einen grossen Fortschritt erreichten wir für all diese Probleme mit der Einführung eines Paket-Caches. Grob gesagt führten wir einen Proxy ein, über den alle Repositories geleitet werden. Am Morgen des Update-Tages holen nun alle Systeme die anstehenden Pakete ab, ohne sie zu installieren – sie versuchen dies drei Mal, um die obengenannten Probleme mit Indizes zu umgehen. Der Paket-Cache lädt die Pakete herunter, liefert sie aus und speichert die Versionen. Der erste Schritt der eigentlichen Update-Prozedur besteht sodann im „Einfrieren“ dieses Caches: ab diesem Zeitpunkt werden nur noch genau die Versionen von Indizes und Paketen ausgeliefert, die dann aktuell waren (Ausnahme: Wird im Laufe des Tages ein Paket angefordert, das noch nicht im Cache vorhanden ist, zum Beispiel bei einer Neuinstallation, so lädt der Cache die zu diesem Zeitpunkt aktuelle Version nach). Während das Einpflegen der entsprechenden Konfigurationen einen gewissen – pro Repository einmaligen – Zusatzaufwand bedeutet, konnten wir mit dieser Methode die Updateprozedur deutlich beschleunigen – ganz zu schweigen von der massiven Diminuierung des Frustfaktors.
Systemgruppierung
Wie bereits bei der Kundeninformation ausgeführt, haben unterschiedliche Systeme unterschiedliche Anforderungen. Eine Testumgebung, wenn auch aus der selben Anzahl und Typisierung an Servern wie ein Livesystem bestehend, kann typischerweise gut zu Bürozeiten aktualisiert werden – ja, soll dies sogar explizit, um eventuelle Probleme rechtzeitig festzustellen und entsprechend darauf reagieren zu können – während die Produktivumgebung nur eine minimale Downtime in der Nacht erlaubt. Gleichzeitig ist es aber für einen effizienten Vorgang auch wünschenswert, möglichst wenige Gruppen zu bilden, die jeweils gemeinsam aktualisiert werden können. Und selbstredend müssen neu erstellte Systeme automatisiert in den Prozess aufgenommen werden, damit sie nicht vergessen gehen. Wir haben mit einer Reihe von Namensschemen für die Gruppen experimentiert und sind inzwischen dabei angekommen, die gleichzeitig abzuarbeitenden System in Gruppen zusammen zu fassen, die dem Namensschema „hhmm-prio-common_name“ folgen, also z.B. „2200-20-night_main“ für die erste grosse Gruppe der Server, die ab 22:00 Uhr anfallen. Jede Gruppe ist in der Checkliste aufgeführt und erst wenn alle zugehörigen Server fertig gestellt und das Monitoring wieder komplett zufrieden ist schreiten wir zur nächsten Gruppe fort. Um das Problem der Erreichbarkeit zu vereinfachen setzten wir ursprünglich auf die einfache Lösung, das Update-Tool auf einem Monitoring-Host zu installieren, da von da aus sowieso schon VPNs zu allen relevanten Maschinen bestanden. Inzwischen haben wir aber sowohl das Monitoring via VPN als auch die ssh-Zugänge durch bessere Methoden ersetzt. Konkret kennt unser puppet die benötigten Jumphosts, um jeden gemanageten Server zu erreichen und mittels dem selbst entwickelten „sshop“-Tool wird nicht nur die entsprechende ssh-Konfiguration, sondern auch gleich jene für apt-dater geschrieben.
Reboots
Wird ein Sicherheitsleck im Kernel bekannt, so ist ein Reboot unumgänglich; aber auch ein Update einer kritischen Komponente wie openssl kann oft einfacher fertiggestellt werden, indem die ganze Maschine neu gestartet wird (anstatt jeder betroffene Service, der die Bibliothek geladen hat, einzeln). Bei Reboots gibt es aber immer eine Reihe von potentiellen Fehlerquellen, die verstärkter Aufmerksamkeit bedürfen:
Die Sicherheitsanforderungen einer Reihe von Kunden verlangen, dass alle Daten verschlüsselt abgelegt sein müssen. Um die Harddisks verfügbar zu machen, muss bei einem Reboot entsprechend der Schlüssel eingegeben werden. Klassischerweise geschieht dies via Konsole – diese muss also erreichbar sein und das Passwort bekannt (gleichzeitig aber kompliziert genug, um sicher zu sein und nur via speziell und mehrfach abgesicherten Zugang abrufbar). Um dies zu umgehen setzen wir darauf, das Hauptsystem unverschlüsselt zu lassen und nur die kritischen Daten auf einer eigenen Partition zu verschlüsseln, welche dann beim Bootprozess nicht gemountet wird. Wir loggen uns nach dem Reboot normal via ssh auf dem Server ein und starten einen speziellen Service, der die Passworteingabe, das Mounten und das Starten der davon abhängigen Services – je nach System via sysvinit, upstart oder systemd – übernimmt. Selbstverständlich sind die Hosts, auf welchen dies vonnöten ist, in der Checkliste aufgeführt und werden spezifisch gemonitort, damit sie garantiert nicht vergessen gehen können.
Mounts von anderen Servern werden manchmal nicht automatisch geladen, da eine Nichterreichbarkeit des Wirtsystems ansonsten den Bootvorgang unterbrechen oder zumindest massiv verlangsamen würde. Entsprechend sind benötigte Daten teilweise erst nach einem puppet-run erreichbar; dieser soll also zeitnah nach dem Booten erfolgen.
Services müssen reboot-sicher konfiguriert werden; das heisst sie müssen nach einem Reboot wieder gestartet werden und sollen den Betrieb möglichst reibungslos wieder aufnehmen. Das ist manchmal einfacher gesagt als getan: wenn eine Datenbank neu indiziert oder grosse Datenmengen geladen werden müssen kann das schon mal eine Weile dauern.
Die Reihenfolge von Reboots bei mehreren zusammengehörenden Servern ist oft relevant: So sollen Datenbank und Fileserver idealerweise vor Applikationsservern neu gestartet werden und diese wiederum vor Webservern und Applikationsfirewalls. Auch dürfen in Clustern zusammengehörende Server nur sequentiell rebooted werden. Dies stellen wir mit der erwähnten Gruppierung der Systeme sicher.
Ebenfalls mit der Gruppierung lösen wir ein Problem, das zwar trivial erscheint, aber ansonsten in der Hitze des Gefechts dennoch übersehen werden kann: Bei redundanten Systemen ist stets darauf zu achten, dass das Backup erst aktualisiert wird, wenn der gesamte Vorgang auf dem Primärsystem erfolgreich abgeschlossen wurde. So wird nicht nur die Redundanz getestet, sondern es werden eventuelle Probleme auch tatsächlich nach dem Update des ersten Systems entdeckt – und nicht erst, wenn schon beide Maschinen verändert wurden.
Monitoring
Obwohl die heutigen virtuellen Maschinen innert weniger Sekunden wieder betriebsbereit sind, haben Updates und insbesondere Reboots zumindest kurze Ausfälle zur Folge. Ein dadurch verpasster puppet-run kann sich aber schnell mal für eine halbe Stunde im Monitoring niederschlagen. Entsprechend ist immer downtime einzuplanen. Ebenso sollte für mindestens rund eine Stunde nach Abschluss der Arbeiten etwas genauer aufs Monitoring geschaut werden: manchmal offenbaren sich Probleme erst, nachdem puppet auf zwei verschiedenen Maschinen durchgelaufen ist (Stichwort: exportierte Ressourcen). Ausserdem hilft es enorm, wenn Abhängigkeiten im Monitoring korrekt erfasst sind: der zeitweise Unterbruch eines VPN darf nicht dazu führen, dass sämtliche Services auf sämtlichen sich dahinter befindlichen Servern als nicht erreichbar erkannt werden.
Schlussfolgerungen und Ausblick
Der Update-Prozess ist ein sich ständig wandelnder, der kontinuierlich verbessert wird. Währenddem wir im Laufe der Jahre schon viele Details perfektioniert haben gibt es immer noch Verbesserungspotential. Und für die Zukunft planen wir eine gewisse Automatisierung auch dieser Aufgabe; doch wollen wir 100% sicher sein, dass dabei nichts schief gehen kann und so ist hier noch einiges an Entwicklungsarbeit einzubringen. Da es sich aber in der jetztigen Form immer noch um einen recht zeitintensiven und wöchentlichen Prozess handelt lohnt sich dies gewiss. Sind wir dann erst mal soweit, wird dies sicher wieder mit einem ausführlichen Blogpost abgerundet. Bis dann!
peter.rueegg
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
VSHN Startup Boost – Das gratis DevOps-Consulting für Startups und Jungunternehmen
24. Mai 2017
Wir sind ein fast drei Jahre altes Technologie-Startup und kennen die Herausforderungen, die man meistern muss, um ein erfolgreiches Unternehmen zu schaffen. Da wir unser Geschäftsmodell etabliert haben und schnell wachsen, wollen wir uns jetzt auf unsere Wurzeln besinnen und der Community etwas zurückgeben. … this information in english >>
Mit dem VSHN Startup Boost wollen wir anderen Startups die Möglichkeit und den Schub geben, den sie benötigen, um ihre Ideen umzusetzen und sich erfolgreich am Markt zu etablieren. Der VSHN Startup Boost ist ein technisches Mentoringprogramm für Startups in den Bereichen Software, Technik oder im Onlinesektor. In der Regel ist der CTO oder der Leiter des Software-Engineerings die richtige Ansprechperson. Du kannst Dich für das Mentoring mit dem untenstehenden Formular bewerben. In der Regel coachen wir ein Startup pro Monat, obwohl Ausnahmen bestimmen die Regel. Wir werden uns auf jeden Fall mit Dir in Verbindung setzen und weitere Schritte besprechen. In der Regel hat jedes Startup eine klare Vision über das Produkt, das es bauen will, sowie die Technologie, die es nutzen wird (und damit Erfahrungen hat).
der Systemarchitektur für Bootstrapping und die erste Skalierungs-Iteration.
Wie man Continuous Integration und Continuous Delivery mit kostenlosen Services und / oder Open-Source-Tools implementiert.
Wie man die Anwendung, falls nötig, containerisieren / dockerisieren kann.
Wie man eine lokale Entwicklungsumgebung mit allen erforderlichen Container-Service-Abhängigkeiten (Backends, Microservices, Datenbanken, Caches, etc.) schafft.
Zu vergleichen und Dich zu verbinden mit anderen (kostenlosen) Diensten für Startups (z. B. Microsoft BizSpark, Amazon AWS, Heroku, APPUiO.ch usw.)
Und natürlich alles andere, womit man Probleme haben könnte.
Im Einklang mit der DevOps-Philosophie ist das optimale Ergebnis für uns, dass Du am Ende der Mentoring-Session einen Software-Delivery-Prozess (buid, test, deploy) hast. Das Ziel ist es, Dir die Software Operations-Erfahrung zu geben, die Du brauchst. Nun kannst du loszulegen und dein Produkt validieren und mit der Fokussierung auf die Softwareentwicklung wachsen. Der perfekte Grundstein für deinen Erfolg.
Einen 1/2 Tag kostenlose Beratung mit unserem Senior DevOps Engineers.
Einen Gutschein – ein halbes Jahr APPUiO.ch gratis zu nutzen.
Wir würden uns freuen, einen Blogpost über Dich und dein Projekt zu schreiben und geben dir die Möglichkeit, an einem unserer KickOff-Breakfasts aufzutreten, um deine Bekanntheit am Markt zu erhöhen. Wenn Du Dich für den VSHN Startup Boost bewerben möchtest oder wenn Du weitere Fragen hast, kontaktiere uns.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Eine der grössten Herausforderungen für uns als modernes Technologie-Unternehmen ist es, immer auf dem aktuellsten Stand der Technik zu bleiben. VSHN macht das bereits erfolgreich und auch bei APPUiO ist eine stetige Weiterentwicklung spürbar. Nach dem Launch des Beta-Angebotes (mehr …)
Tobias Brunner
Tobias Brunner arbeitet seit über 20 Jahren in der Informatik und seit bald 15 Jahren im Internet Umfeld. Neue Technologien wollen ausprobiert und darüber berichtet werden.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Wir betreiben die Applikationen unserer Kunden auf verschiedenen Cloud-Providern, je nach Anforderungen an Sicherheit, Verfügbarkeit, Skalierbarkeit, geographischer Abdeckung und bestehender Infrastuktur des Kunden. Neben Cloudscale.ch, Exoscale.ch, SafeSwissCloud und Swisscom Enterprise in der Schweiz sind wir auch Partner von Amazon AWSund neu auch zertifizierter Silver Partner für Opensource Software Stacks auf Microsoft Azure.
Die Zertifizierung zeigt dem Kunden, dass VSHN die entsprechenden Erfahrung im Aufbau und Betrieb von Opensource-Applikationsservern (Java, PHP, Python, Ruby, JavaScript, Erlang/Elixir, etc) und Datenbanken (MySQL, MariaDB, PostgreSQL, MongoDB, Cassandra, ElasticSearch, Solr, Redis, etc) hat. Die Partnerschaft steht auch für eine eingespielte, konstruktive Zusammenarbeit im Support – VSHN ist für seine „no finger-pointing policy“ bekannt, also anstatt Schuldzuweisungen zu machen, werden konstruktiv mit allen beteiligten Parteien zusammen Probleme gelöst.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Am 23. und 24. Februar 2017 fand ein Modsecurity Workshop in Zürich statt. André Keller und Nicolas Bigler nutzten die Gelegenheit, ihr Fachwissen zu vertiefen. Der Workshop wurde von Christian Folini durchgeführt. Der Kurs basierte auf seinem eigenen Tutorial. Er gehört, was das Thema Modsecurity anbelangt, zu den erfahrensten (mehr …)
Nicolas Bigler
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Am 28.02 kurz nach 18:30 Schweizer Zeit ist der Simple Storage Service S3 von Amazon AWS an der US-Ostküste für knapp 3 Stunden ausgefallen. Ein kleiner Ausfall eines Services wäre an sich kein Problem, 3 Stunden Ausfall pro Jahr bedeuten auch dann noch eine Verfügbarkeit von über 99.96% und ist eine sehr gute Gesamtverfügbarkeit — besser als die unserer Kunden, welche Ihre Services selber hosten. In der Schweiz war der Ausfall kurz nach den Bürozeiten, in den USA war der Ausfall jedoch kurz vor dem Mittag und dadurch stark auch im Business spürbar.
Das Problem war, dass viele, darunter auch grosse prominente Webapplikationen, aus Kostengründen ihre Daten nicht redundant, also mehrfach in verschiedenen Regionen bei Amazon oder anderen Cloud Service Providern, gespeichert hatten. Dazu kam der Zufall gemäss Murphy dass die „us-east-1“ Region jeweils die erste, bereits ausgewählte, Option beim Erstellen eines neuen Services ist und vermutlich auch darum sehr viele Kunden von Amazon (und auch von VSHN) den Service aus dieser Region beziehen. Bekannte Namen, die vom Ausfall betroffen waren: Docker Hub, Trello, Travis CI, GitHub.com und GitLab.com, Quora, Medium, Signal, Slack, Imgur, Twitch.tv, Razer, Adobes Cloud Services, Zendesk, Heroku, Coursera, Bitbucket, Autodesk Cloud Services, Twilio, Mailchimp, Citrix, Expedia, Flipboard, Salesforce, Giphy, Nest und ironischerweise, die Service-Status-Webseite von Amazon selbst, die erst eine gute Stunde nach dem Ausfall des Services angepasst werden konnte. Die Situation normalisierte sich gegen 22:00 Uhr und ab ca. 23:00 Uhr waren auch die letzten Probleme behoben. Wie kann man einen solchen Ausfall für seine Webapplikation verhindern? Um auch das letzte Quäntchen Verfügbarkeit aus der Applikation zu holen, gibt es, wie immer in den Ingenieurwissenschaften, verschiedene Möglichkeiten, in aufsteigender Kostenreihenfolge:
Statische Assets die in S3 liegen, per Content Delivery Network (CDN) ausliefern: machen die Meisten vermutlich bereits. Das CDN speichert die bereits häufig angefragten Daten und kann so kurze Ausfälle des darunter liegenden Speichersystems (egal ob S3 oder ein anderes) überbrücken. Leider nützt das nichts für gerade neu erstellte oder hochgeladene Daten; immerhin läuft die Webseite mit den „alten Daten“ weiter. Die anderen Vorteile eines CDN (schnellere, weil nähere Auslieferung zum Nutzer, DDoS-Schutz, möglicherweise tiefere Bandbreiten/Traffic-Preise, etc.) gelten natürlich ebenfalls und macht für die meisten Seiten mit globalem Nutzerkreis Sinn.
Redundante Speicherung: Alle Schreib- und Löschoperationen (am besten mittels Queue) in zwei unterschiedliche Speicherservices ausführen, zumindest in unterschiedliche AWS-Regionen oder zu einem anderen Cloud Service Provider, der einen S3-kompatiblen Service anbietet. Beim Zugriff (am besten via CDN zur Zwischenspeicherung, siehe oben) probiert die Applikation wahlweise den einen oder anderen Speicher zu erreichen und liefert die Daten, egal von welchem Storagebackend, an das CDN weiter. Der Nachteil ist neben der zusätzlichen Applikationslogik, die implementiert und gewartet werden muss, natürlich die doppelten Kosten für die Speicherung an zwei Orten.
Ebenfalls sollte dann die Applikation selbst (und ihre anderen Backends wie Datenbanken etc.) an zwei Orten laufen und parallel aktiv-aktiv betrieben werden, um die Gesamtverfügbarkeit nicht zu beeinträchtigen. Auch dafür entstehen Kosten und die Komplexität des Load-balancing über zwei Regionen oder Cloud Service Provider ist nicht zu unterschätzen.
VSHN ist der Schweizer Experte für den sicheren Betrieb von Webapplikationen in den internationalen wie auch den Schweizer Cloud Service Providern. Wir beraten nicht nur, sondern helfen auch gerne dabei, solche Konzepte umzusetzen.
Nachtrag 3. März 2017:
Unterdessen wurde die offizielle Erklärung der Vorkommnisse veröffentlicht: Die Ursache war ein manueller Fehler: beim routinemässigen Entfernen von alten Servern aus dem System hat sich um 18:37 Schweizer Zeit ein Amazon-Mitarbeiter vertippt und aus Versehen auch eine kritische Gruppe von Servern für den internen S3-Metadaten-Dienst und den S3-Allozier-Dienst gelöscht. Daten sind dabei keine verloren gegangen. Das Hochfahren des Metadaten-Dienstes und die Prüfung der Datenintegrität dauerte länger als geplant, ab 21:26 konnten die ersten Lese-Anfragen wieder abgearbeitet werden und ab 22:18 waren die Lesezugriffe komplett wiederhergestellt. Der S3-Allozier-Dienst, der für Schreibzugriffe benötigt wird, wurde anschliessend wieder hergestellt und war ab 22:54 wieder vollständig verfügbar. Fehler passieren – an dieser Stelle ein Kompliment an AWS für die professionell verfasste und transparente Zusammenfassung der Ereignisse und der daraus gezogenen Massnahmen ! Diese sogenannten „Postmortems“ helfen uns allen aus diesen Erfahrungen zu lernen und uns als Industrie weiter zu entwickeln.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Kürzlich habe ich mit einem CTO eines bekannten Schweizer Software-Entwicklungs-Unternehmens gesprochen und natürlich ist das Thema DevOps, Continuous Deployment und das Verpacken eines Software-Release für das Deployment gefallen, für das auch das Software-Entwicklungs-Unternehmen bereits erste Erfahrungen mit Docker gesammelt hat. Zu meinem grossen Erstaunen hat mein Gesprächspartner gemeint er habe keinen Betriebspartner bzw. Hoster für Docker in der Schweiz gefunden. Darum möchten wir unser Angebot für Docker-Hosting in der Schweiz offiziell launchen!
Die verschiedenen Komponenten des Docker-Universums helfen dabei die standardisierten Container zu erstellen, kombinieren und zu betreiben.
Docker Engine
Die Docker Engine ist, was die meisten meinen, wenn sie von „Docker“ sprechen und besteht aus zwei Teilen:
Das Programm „docker“, welches vom Benutzer gesteuert wird.
Dem Docker-Dienst (Docker Daemon, dockerd) welches die Befehle von „docker“ im Hintergrund ausführt.
Die Engine ist damit der Kern der Technologie und das Zentrum des Docker-Ökosystems. Docker Engine kann aktuell auf Linux, macOS und Windows installiert werden, wobei die Container-Technologie selbst auf Linux basiert und macOS und Windows in den aktuellsten Versionen Linux mit den entsprechenden Bordmitteln virtualisieren. Für andere Betriebssysteme sowie für ältere Versionen von macOS und Windows gibt es jeweils die Möglichkeit, den Docker Daemon in einer virtuellen Linux-Maschine zu betreiben (zum Beispiel mit Virtualbox). Die beiden Komponenten sprechen über eine standardisierte Schnittstelle miteinander. Dabei ist es unwichtig ob sie auf demselben Computer bzw. Server liegen oder über das Internet miteinander sprechen. Man muss das lokale „docker“-Programm einfach über die Umgebungsvariable $DOCKER_HOST entsprechend konfigurieren, wo es seinen Docker-Dienst finden soll. Standardmässig erwartet es den Docker-Dienst auf dem lokalen Unix-Socket /var/run/docker.sock, auf TCP-Port 2375 eines zu konfigurierenden Servers unverschlüsselt oder TCP-Port 2376 mit TLS verschlüsselt.
Docker Inc
Docker Inc ist die Firma hinter Docker, also der Hersteller der Software. Leider ist es im mündlichen Gespräch nicht immer einfach zu unterscheiden wenn man von „Docker macht …“ spricht.
Dockerfile
Das Dockerfile ist eine Textdatei, meistens zusammen mit dem Programmcode im Versionskontrollsystem, welche alle benötigten Befehle enthält um eine Umgebung zu erstellen in welcher der Programmcode laufen kann. Je nach Applikation und Programmiersprache installiert es also einen Applikationsserver, alle benötigten Pakete, Module und Bibliotheken. Meistens fängt man nicht mit einer „leeren“ Umgebung an, sondern nutzt eine von einer verlässlichen Firma gepflegte Basis (dazu gleich mehr). Auf diese Basis müssen dann nur noch die applikationsspezifischen Pakete, Module und Bibliotheken installiert. Alle dafür benötigten Schritte sind im Dockerfile aufgelistet und somit auch gleich für das ganze Team dokumentiert. Ausserdem lassen sie sich dadurch auch sehr einfach automatisieren. Ebenfalls im Dockerfile steht, welche Dateien der Applikation in den Container übernommen werden sollen, wie der genaue Befehl für die Applikation lautet, auf welchem Port die Applikation dann erreichbar ist und in welchen Verzeichnissen innerhalb des Containers die Applikation ihre Benutzerdaten ablegt (die sogenannten Volumes). Docker Inc veröffentlicht auch eine Dokumentation was man beim Erstellen des Dockerfiles alles beachten soll. Ein grundlegendes Muster der Zwölf-Faktoren-Methode und der Container-Welt ist, dass die Konfiguration, also alles was sich zwischen zwei verschiedenen Deploys (Staging, Produktion, Entwicklungsumgebungen, usw.) ändert, in Umgebungsvariablen (Environment Variables) der Applikation übergeben werden sollen. Dazu gehören Ort und Zugangsdaten für Backend-Services (Datenbanken, Caches, S3-Storage, etc.), externe APIs, etc. Wenn die Applikation dies selbst nicht unterstützt, muss das Dockerfile ein Start-Skript erstellen welches dann zur Laufzeit die Daten in den Umgebungsvariablen der Applikation übergibt und sie startet. Das Dockerfile ist also die Anleitung für die Build-Phase des „Build, Release, Run“-Patterns.
Docker Image
Ein Image ist das Ergebnis wenn ein Dockerfile ausgeführt wurde. Es enthält also die Applikation in einer bestimmten Version und alle für das Ausführen benötigten Komponenten, also ein Release. Das Docker Image kann von der Docker Engine ausgeführt werden und stellt dann die Applikation unter einem bestimmten Port (z.B. TCP Port 80 für HTTP) zur Verfügung. Nur die im Dockerfile definierten Volumes mit Benutzerdaten werden persistent gespeichert und stehen nach einem Neustart oder Update weiterhin zur Verfügung, der Rest des Container-Inhaltes wird verworfen gemäss dem Faktor des Einweggebrauches der Zwölf-Faktoren-Methode (12 Factor App).
Docker Registry
Die Registry speichert die fertigen Images und stellt sie zum Download auf den/die Server zur Verfügung, auf denen sie ausgeführt werden sollen. Docker Inc betreibt eine öffentliche Registry unter https://hub.docker.com/ (auch „Docker Hub“ genannt) welche auch für die Verteilung der öffentlichen Basis-Images verwendet wird. Die Verwendung des Docker Hubs ist kostenlos, dafür sind aber auch alle Daten öffentlich. Für Open Source also kein Problem. Für Applikationen die nicht öffentlich sein sollen braucht es also eine private Registry zur Software-Verteilung. Zum Glück ist eine private Registry kostenlos unter https://hub.docker.com/_/registry/ erhältlich – natürlich läuft sie ebenfalls in einem Docker-Container. Ganz neu und aktuell noch im Beta-Stadium befindet sich der Docker-Store https://store.docker.com/, welcher wohl irgendwann den Docker Hub ablösen wird.
Docker Machine
Docker Machine ist ein Programm welches entweder auf dem lokalen Computer (mittels Virtualbox) oder in einer Cloud (Liste der unterstützten Cloud-Provider) einen virtuellen Server erstellt und startet um darauf Container auszuführen. Sehr praktisch wenn man Docker nicht nativ auf dem lokalen Computer ausführen kann (z.B. unter Windows) oder der/die Container mehr Ressourcen benötigt als lokal verfügbar sind. Die erstellten virtuellen Server sind aber nur für temporäre Experimente gedacht: sie werden weder überwacht, neu gestartet, mit Backup gesichert oder aktualisiert. Auch ist der virtuelle Server nur auf dem lokalen Computer für den Benutzer sinnvoll nutzbar der ihn erstellt hat: das Programm sichert die Kommunikation mit dem mini-Server mit Schlüsseln ab die nur auf dem lokalen Computer gespeichert werden und startet beim nächsten Verbinden alle Container die bisher liefen ab.
Docker Compose
Im einfachsten Fall besteht eine Applikation nur aus einem Prozess/Container, oft benötigt eine Applikation gemäss der Microservice-Architektur und dem Konzept der Nebenläufigkeit in der Zwölf-Faktoren-Methode einen weiteren Service als Backend, zum Beispiel eine Datenbank oder einen Cache, der wiederum in einem separaten Container läuft. Für viele Standardapplikationen gibt es bereits fertige Docker Images z.B. vom Docker Hub welche durch den Hersteller oder die Community gepflegt werden. Docker Compose besteht wiederum aus dem Programm „docker-compose“ und der Konfigurationsdatei docker-compose.yml (normalerweise in der Versionsverwaltung der Applikation, neben dem Dockerfile, damit auch da alles am selben Ort ist) in welcher die Services, Volumes und Netzwerke definiert werden welche zusammen gestartet, miteinander kommunizieren und einen oder mehrere Services verfügbar machen sollen. Die Services in der Konfiguration referenzieren im einfachsten Fall entweder die aktuelle Applikation gemäss Dockerfile oder aber „fertige Images“ (standardmässig vom Docker Hub) und welche Services mit welchem anderen Service (über die in den Dockerfiles definierten Ports) kommunizieren sollen, zum Beispiel die aktuelle Applikation mit dem Datenbank-Container. Ebenfalls müssen die Namen und Ports der benutzten Services als Konfiguration in Umgebungsvariablen der Applikationscontainer definiert werden, zum Beispiel DATENBANK=“mysql:3306″ wenn der Applikationscontainer den Ort der Datenbank in der Variable „$DATENBANK“ erwartet und der MySQL-Service im docker-compose.yml „mysql“ genannt wird und unter dem Port 3306 (MySQL-Standardport) verfügbar ist. Der Befehl „docker-compose up“ startet dann alle Services in der gemäss den Abhängigkeiten definierten Reihenfolge und ermöglicht den Container miteinander zu kommunizieren.
Docker Swarm
Ein Docker Swarm („Schwarm“, also Gruppe) besteht aus mehreren zusammengeschalteten Docker Engines (bzw. Docker-Diensten dockerd, auch Nodes genannt), welche gemeinsam unter „einer zentralen Docker API“ für den Benutzer bzw. das Programm „docker“ erreichbar ist. Dabei ist ein Node der „master“ der die Anfragen des Benutzers entgegennimmt, die Container auf den anderen Swarm Nodes startet und sich um die Kommunikation von/zu den Containern auf den verschiedenen Nodes kümmert. Swarm ist eine relativ neue Komponente im Docker-Ökosystem und wurde erst Mitte 2016 veröffentlicht. Entsprechend ist der Funktionsumfang noch beschränkt: ein Swarm ist zum Beispiel noch nicht mandantenfähig, alle Services – egal von welchem Benutzer – müssen also eindeutige Namen haben und sind auch untereinander nicht abgeschottet. Entsprechend wird empfohlen für Testing und Produktion separate Swarms zu betreiben.
Vergleich mit Kubernetes
Kubernetes ist eine Alternative zu Docker Compose und Docker Swarm und unterstützt durch die längere Erfahrung z.B. Mandantenfähigkeit und wird gerade für grössere Umgebungen lieber verwendet, zum Beispiel für die Schweizer Container Plattform APPUiO. Um die Orchestrierung mehrerer Container mittels Docker Compose zu übernehmen gibt es das Programm Kompose, dazu werden wir später noch einen ausführlicheren Blogpost schreiben.
Weitere Informationen
Möchtest du weitere Informationen zu Docker erhalten oder eine Offerte anfordern? Bitte nimm Kontakt mit mir auf:
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
The Let’s Encrypt certificate authority was launched for production use in April 2016 and aims to make encrypted connections on the Internet ubiquitous. Historically certificate authorities have demanded payment for issuing X.509 certificates and the issuing/renewal process was largely manual. Let’s Encrypt issues domain-validated certificates free of charge. Other validation types requiring human interaction, such as Organization Validation or Extended Validation (most browsers show part of the address bar in green for these), are not available. The validation process is fully automated and, once configured, does not need manual intervention for certificate renewal. Let’s Encrypt issues certificates valid for 90 days and most client programs renew certificates a couple of weeks before they expire (usually after 60 days). In this post we describe how to configure load-balanced services such that they can make use of the Let’s Encrypt certificate authority. The assumption is that the reader is familiar with how Let’s Encrypt works. acmetool is used as the Let’s Encrypt client.
Implementation overview
We’re going to implement Let’s Encrypt certificates for a system with three machines acting as a load-balancing frontend for a service backend. The service’s entry point is the domain name svc.example.com and the servers use the IPv6 address range 2001:db8::/32. IPv4 is left as an exercise for the reader. The frontend machines run HAProxy for load-balancing and keepalived to host virtual IP addresses. nginx is used to serve challenge responses for domain validations and to redirect plain-text requests to HTTPS (the service is only available over TLS). The network looks as follows:
IPv6
Description
2001:db8::1
Virtual IP
2001:db8::2
Virtual IP
2001:db8::3
Virtual IP
2001:db8::f001
Frontend LB0
2001:db8::f002
Frontend LB1
2001:db8::f003
Frontend LB2
2001:db8::b001
Backend 1
…
…
2001:db8::b020
Backend 20
There are as many virtual IP addresses as there are load balancers. This way everyday traffic is still spread over across the load balancers even when there is no outage. The DNS record for the service looks as follows:
svc.example.com. 3600 IN AAAA 2001:db8::1
svc.example.com. 3600 IN AAAA 2001:db8::2
svc.example.com. 3600 IN AAAA 2001:db8::3
The main challenge in such a setup is that the service can’t possibly know to which load balancer the Let’s Encrypt validation process connects in order to validate the domain (svc.example.com). Not only is there round-robin DNS, but the other load balancers may suffer an outage or be under maintenance. Hugo Landau’s deployment guide for IRC networks was a significant inspiration during the development of this configuration and proposes a centralized service to which the individual machines submit their challenge responses and where they redirect incoming requests. In a setup where all machines are controlled by one party that can easily be avoided while also avoiding any cross-machine state. In our configuration the load balancers are stateless in regards to the Let’s Encrypt validation. Every load balancer has its own key/certificate combination and is responsible for its renewal.
Example certificate renewal
LB1 determines that it needs to request a new certificate and sends a request to the Let’s Encrypt certificate authority.
As part of the ACME conversation the CA responds with a randomly generated token and a challenge response the server must make available at the URL . acmetool writes the response to /var/run/acme/acme-challenge/TOKEN and conducts a self-test.
Let CA know that the challenge is available.
CA resolves the DNS record svc.example.com and finds the IP addresses 2001:db8::1, 2001:db8::2 and 2001:db8::3 in random order. It connects to the first address. The address, say 2001:db8::2, is currently hosted on LB0. The request GET /.well-known/acme-challenge/TOKEN is sent.
LB0 receives the request and finds that it must act as a reverse proxy with 2001:db8::f001, 2001:db8::f002 and 2001:db8::f003 being the upstream servers. In this example it first connects to itself, to LB0, and issues a request for /.well-known/acme-challenge/TOKEN.
The token is not found in /var/run/acme/acme-challenge/ on LB0 and an HTTP/1.1 404 error is returned. The next upstream server must be tried.
LB1 is now sent the same request and finds the response in /var/run/acme/acme-challenge/TOKEN.
The challenge response is returned from LB1 to LB0 with a status code of HTTP/1.1 200, indicating success.
LB0 forwards the response to the Let’s Encrypt CA. The CA verifies the response and, if successful, proceeds to issue a certificate.
The certificate is made available for download. acmetool retrieves the certificate, stores it permanently in its state directory and invokes the relevant hooks. Services are reloaded to make use of the newly issued certificate.
Keepalived
In case of an outage or maintenance the remaining load balancer or balancers take over the IP addresses of the balancer not in service, ensuring users are not affected. To this effect the priorities per IP address shifted by one per node. The state is set to BACKUP for all IP addresses as there’s no concept of a real primary machine–they’re all equal. Additionally setting the state to BACKUP instead of MASTER prevents an IP address conflict when a machine comes online (another machine with a lower priority is still serving the IP address until synchronization takes place). Keepalived configuration on LB0:
HAProxy is configured to only provide HTTP over TLS (HTTPS) because plain-text HTTP is served by Nginx. Communication with the backend uses TLS too, but depending on the network layout and/or service requirements plain-text HTTP may be acceptable. See the HAProxy documentation for available options.
acmetool is configured to use the webroot mode and to store challenge responses in /var/run/acme/acme-challenge/ (the default path). Define a separate virtual host in Nginx to serve challenge responses on a dedicated port. This port serves only information also available via port 80, hence no further protection is needed.
Configure an upstream group with all load balancers (including the local machine):
upstream acme-backend {
server [2001:db8::f001]:31080 fail_timeout=5s;
server [2001:db8::f002]:31080 fail_timeout=5s;
server [2001:db8::f003]:31080 fail_timeout=5s;
}
The main virtual host on port 80 redirects all requests to HTTP over TLS except those for ACME challenge responses (/.well-known/acme-challenge/…). ACME challenge responses are handled by a reverse proxy configuration attempting to fetch the file from all load balancers until produces an HTTP 200 response or all upstream servers (the balancers) have been tried. Connections to unreachable upstream servers time out after 5 seconds.
Once everything is up and running it is possible to request files in /var/run/acme/acme-challenge/ on any load balancer from all balancers. To test this a text file is written to /var/run/acme/acme-challenge/:
root@lb0 $ echo Hello World | tee /var/run/acme/acme-challenge/lb0
Hello World
lb0 is a unique, per-host name used for the test without special meaning. Retrieve the content via another machine, e.g. LB2. On LB2 the request is internally retried on all load balancers, but the proxy request will only return a successful status code and a response body on LB0.
user@local $ curl 'http://[2001:db8::f003]/.well-known/acme-challenge/lb0'
Hello World
A file not existing on any of the machines will produce an error:
user@local $ curl 'http://[2001:db8::f003]/.well-known/acme-challenge/foobar'
…
<head><title>404 Not Found</title></head>
…
Let’s Encrypt will now be able to verify the service domain, svc.example.com. When one of the load balancers needs a new certificate a request is issued to Let’s Encrypt and the validation takes place via any of the balancers and the internal reverse proxy configuration.
acmetool
Configuring acmetool is outside the scope of this document. However, a couple of hints:
Use the haproxy hook included with acmetool to install newly received certificates. Configure HAProxy to use /var/lib/acme/live/$domain/haproxy for key and certificate.
In scenarios where plain-text HTTP and HTTP over TLS are handled by the same service (e.g. Apache or Nginx) there is a chicken-or-egg problem where the service can’t be started due to the lack of a certificate. We solved this by first inserting a self-signed certificate in order to start the service. Once a signed certificate is received from Let’s Encrypt the service is reloaded.
We have engineered a Puppet module for acmetool and intend to release it at a later point in time.
Die Schweizer Container Plattform “APPUiO” geht mit drei Angeboten an den Start. Neben der Public PaaS wird die Plattform auch als private Cloud betrieben oder in die Infrastruktur der Kunden integriert. APPUiO basiert auf modernen Open Source Konzepten wie Docker und Kubernetes und wird in ISO-zertifizierten und FINMA-auditierten Rechenzentren in der Schweiz betrieben.
Nach einer dreimonatigen Betaphase steht APPUiO ab heute allen Entwicklern und Firmen zur Verfügung. Mit APPUiO lassen sich Applikationen einfach und schnell entwickeln oder Container Workload betreiben. Hinter APPUiO stehen mit Puzzle ITC und VSHN zwei DevOps Experten, welche ihre Kunden bei der erfolgreichen Umsetzung von Konzepten wie Continuous Integration und -Deployment unterstützen.
Auf in Richtung DevOps
Auf der Basis bewährter Open Source Konzepte wie Docker und Kubernetes lassen sich auf APPUiO Applikationen mit standardisierten Komponenten entwickeln und skalierbar betreiben. Mit der Plattform werden IT-Prozesse automatisiert und die Bereitstellung von IT-Services gestrafft. Applikationen können dabei sowohl in der Public Cloud, intern oder auch in einer hybriden Cloud betrieben werden. Die Anwendung der Docker-Konzepte eröffnet neue Aussichten für die Entwicklung und den Betrieb in Richtung DevOps.
Start mit Tech Labs
Interessierte können in kostenlosen Tech Labs erste Erfahrungen mit der Plattform sammeln. Dabei lernen sie Hands-on die wichtigsten Schritte, wie eine Applikation in die Cloud gebracht wird und wie Container auf einer PaaS deployed und betrieben werden können. Wer sich bis Ende November für die Plattform registriert, kommt zudem in den Genuss einer Promo-Aktion.
Puzzle ITC realisiert individuelle Software- und Systemtechnik-Projekte basierend auf offenen Technologien und Standards. Seit der Gründung vor 16 Jahren wächst das Unternehmen – auch Dank der zunehmenden Bedeutung von Open Source Software – kontinuierlich und beschäftigt heute über 90 Mitarbeitende. Puzzle ITC verfügt neben dem Hauptsitz in Bern über eine Niederlassung in Zürich. Mit “We Are Cube3“ besitzt Puzzle ein eigenes User Experience Studio als optimale Schnittstelle zwischen Entwickler, Designer und Benutzer. Zu den Kunden von Puzzle ITC gehören Unternehmen aus dem öffentlichen Verkehr (SBB, BLS, Siemens, PostAuto), der Bundesverwaltung (Bundesamt für Sport, Führungsunterstützungsbasis VBS, Nationale Alarmzentrale, Institut für Geistiges Eigentum, Schweizerisches Bundesarchiv, Schweizerische Bundeskanzlei, swisstopo), der Telekommunikation, Versicherungen (Die Mobiliar, Swiss Re), Banken, Logistik (Swisslog), Unternehmen aus der Industrie sowie zahlreiche KMU. Puzzle ist seit Februar 2013 Red Hat Premier Partner.
VSHN AG – The DevOps Company – betreibt Betriebssysteme und Applikationen cloud-agnostisch nach dem DevOps-Ansatz. Als erfolgsverwöhntes StartUp glauben und erleben wir jeden Tag, dass unsere Kunden durch den hohen Automatisierungsgrad wesentliche Mehrwerte erhalten. VSHN AG, mit Büros direkt am Zürcher Hauptbahnhof, beschäftigt heute 17 Mitarbeitende und ist in privater Hand gehalten. Unsere Kunden – AmazeeLabs, Cinerent, FabWare, Gbanga, GrossStadtJagd, Sherpany, SIX-Group, Starticket und viele mehr – lassen ihre Anwendungen, Daten und damit gleichzeitig Vertrauen deshalb durch uns halten und betreiben, weil wir dank unseren hohen Sicherheits-Anforderungen und den ISO 27001-konformen und FINMA-auditierten Prozessen ihre Integrität garantieren können.
httpoxy: Eine unauffällige HTTP-Kopfzeile führt zur Sicherheitslücke
25. Juli 2016
Am 18. Juli 2016 wurde eine Gruppe von Sicherheitslücken namens httpoxy veröffentlicht. Wir haben Auswirkungen auf unsere eigene Infrastruktur sowie die unserer Kunden bewertet und sind derzeit dabei, Gegenmassnahmen zu ergreifen.
Was ist httpoxy?
httpoxy ist eine Mehrzahl von verwandten Sicherheitslücken, die via Common Gateway Interface (CGI) aufgerufene oder in CGI-ähnlichen Umgebungen laufende Programme betreffen. Jede Kopfzeile einer HTTP-Anfrage (engl. «header») wird vor dem Programmaufruf in eine Umgebungsvariable mit dem Namensschema HTTP_${Name-in-Grossbuchstaben}gespeichert. Aus User-Agent: wird beispielsweise HTTP_USER_AGENT. httpoxy betrifft die Proxy:-Kopfzeile, die dann in HTTP_PROXY abgelegt wird. Die Sicherheitslücke rührt daher, dass die Standardvariable zur Festlegung eines HTTP-Proxies unter Unix-Systemen http_proxy heisst. Proxies für andere Protokolle werden in nach dem gleichen Schema benannten Variablen übergeben. So definiert ftp_proxy den Proxy für das File Transfer Protocol (FTP) und gopher_proxy für Gopher.
Unix, Windows und die Unterscheidung von Gross- und Kleinschreibung
Der grösste Teil der VSHN-Infrastruktur und unserer Kunden laufen mit Unix-kompatiblen Systemen, vorallem Linux. Diese Systeme unterscheiden bei Umgebungsvariablen bzw. deren Namen zwischen Gross- und Kleinschreibung. Andere Systeme, darunter Microsoft Windows®, tun dies nicht.
Leider halten sich nicht alle Programme und Bibliotheken an diese plattform-spezifische Konvention. Die Python-Bibliothek requests beispielsweise liest auch auf Unix-Systemen einen Proxy aus HTTP_PROXY, obwohl die Standardvariable http_proxy heisst:
Demzufolge können interne Abfragen einer Webseite umgeleitet werden, wenn durch externe Faktoren die HTTP_PROXY-Variable kontrolliert werden kann, wie dies durch httpoxy beschrieben wird.
Angenommen, die URL wird durch via CGI, FastCGI oder eine ähnliche Technologie aufgerufenen Code behandelt, so wird dieser eine Umgebungsvariable namens HTTP_PROXY mit dem Wert erhalten. Interne Abfragen werden dann über ebendiesen Proxy geleitet, wenn die verwendeten Bibliotheken verwundbar sind. Die httpoxy-Webseite listet weitere Beispiele und sog. CVEs. Mit grosser Wahrscheinlichkeit werden in den kommenden Stunden, Tagen und Wochen weitere gefunden werden.
Demonstration aus der Praxis
Man nehme ein herkömmliches CGI-Skript:
#!/usr/bin/python3
import os
import requests
print("Status: 200")
print("Content-type: text/plain")
print()
print(dict((k, v) for (k, v) in os.environ.items() if k.lower() == "http_proxy"))
print("---")
url = "http://backend.example.com/?secret_key=lZLx60gP"
try:
print(requests.get(url).text)
except Exception as err:
print("Error: {}".format(err))
Angenommen eine Angreiferin kontrolliert einen HTTP-Proxy mit der IP-Adresse 192.0.2.33 und Port 3128 (der Standardport des Proxy-Servers Squid) macht eine HTTP-Anfrage wie folgend:
curl -H 'Proxy: ' -v
Die resultierende interne Abfrage wird durch den von der Angreiferin kontrollierten Proxy geleitet. Ein Auszug aus den Logdateien des Proxy-Servers:
TCP_MISS/504 1617 GET - DIRECT/backend.example.com text/html
In diesem Fall ist die Beispiel-URL ungültig und der Proxy liefert eine Fehlermeldung zurück:
$ curl -H 'Proxy: ' -v
[…]
> GET /cgi-bin/contact.py HTTP/1.1
> User-Agent: curl/7
> Accept: */*
> Proxy:
>
< HTTP/1.1 200 OK
< Date: Mon, 25 Jul 2016 13:58:50 GMT
< Content-Type: text/plain
<
{'HTTP_PROXY': 'http://192.0.2.33:3128'}
---
[…]
<p>The following error was encountered while trying to retrieve the URL:
<a href="http://backend.example.com/?">http://backend.example.com/?</a></p>
[…]
In der Realität könnte der Proxy den in der URL enthaltenen Schlüssel speichern und hätte die vollständige Kontrolle über die Antwort.
Schadensminderung
Es wird eine Weile dauern, bis alle Applikationen und Bibliotheken aktualisiert und diese verbesserten Versionen in den Produktiveinsatz gebracht wurden. Bis dahin sollten HTTP-Server sämtliche Proxy-Kopfzeilen entfernen. Dies sollte keinen Einfluss auf die Funktion von Webseiten oder Applikationen haben, denn Proxy ist weder von der IETF definiert noch im IANA-Verzeichnis für Nachrichtenkopfzeilen gelistet, also nicht standardisiert. Seit mindestens 1996 bis zur Aufhebung der Empfehlung mit RFC 6648 im Jahr 2012 mussten eigene Kopfzeilen mit einem X--Präfix versehen sein. Manchmal werden Applikationen von Drittanbieter mit alten und somit verwundbaren Bibliotheken oder unsicheren Konfigurationen ausgeliefert. Auch hier ist es wichtig, eine Schadensminderung umzusetzen. Die httpoxy-Webseite hat eine Anzahl von Konfigurationsbeispielen veröffentlicht, mit denen Proxy-Kopfzeilen in diversen HTTP-Servern und verwandten Programmen entfernt werden können. Ebenso bietet die Webseite Beispiele für Applikations- und Bibliotheksentwickler.
Schlussfolgerung
Wir empfehlen, HTTP-Server und sog. Reverse-Proxies so zu konfigurieren, dass sie sämtliche Proxy-Kopfzeilen zu entfernen. Es schadet dabei nicht, dies auch mehrfach im Verlauf einer HTTP-Anfrage zu tun. Die Sicherheitslücke ist jetzt öffentlich und es ist nur eine Frage der Zeit, bis diese für automatisierte und gezielte Angriffe ausgenutzt wird. Auch wenn eine Webseite oder Applikation heute nicht anfällig ist–und schon das ist schwierig abzuklären–so wird sie es vielleicht in der Zukunft. Nicht alle Projekte halten ihre Abhängigkeiten von Drittanbietern aktuell.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Alternative zu Git Submodulen: GWS (Git Workspace)
12. Juni 2016
Ein Git Repository zu pflegen ist keine Hexerei. Ein Git Repository mit Referenzen zu anderen Repositories kann jedoch sehr schnell komplex werden. Git bringt dafür einige Hilfsmittel mit, z.B. Git Submodule oder Git Subtree. Beide Techniken sind relativ komplex und bringen ihre Vor- und vorallem Nachteile mit.
Wir pflegen unsere Puppet Hiera Daten in YAML Dateien, welche in Git Repositories versionisiert werden. Hiera besteht in seiner einfachsten Anwendung aus einem einzelnen Verzeichnisbaum, welcher die Hierarchie abbildet. Unsere Anforderung ist, dass diese Hierarchiestufen in unterschiedlichen Git Repositories liegen. Hierfür verwendeten wir zu Beginn Git Submodule, sind dabei aber auf einige Probleme gestossen. Das grösste Problem ist, dass ein Git Submodule immer auf einen bestimmen Git Commit referenziert. Möchte man immer auf den aktuellsten Commit referenzieren, muss man jedesmal die Referenz im Hauptrepository anpassen. Dies ist nicht praktikabel für unseren Anwendungsfall, da wir immer die aktuellsten Commits verwenden möchten. Wechselt man in ein Unterverzeichnis, welches ein Git Submodule ist, hat man die Möglichkeit, mit den bekannten Git Befehlen zu arbeiten. So wäre es möglich, in diesem Unterverzeichnis mit einem git checkout master den Master Branch auf dem aktuellsten Commit auszuchecken. Dies passt jedoch die Referenz im Hauptrepository nicht an. Klont nun jemand das Hauptrepository vom Git Server, erhält er immer den Verweis auf den Commit im Submodul, welcher referenziert ist. Auf der Suche nach einer Lösung, Referenzen zu mehreren Repositories in einem Hauptrepository pflegen zu können, sind wir auf ein Tool namens GWS – Git Workspace gestossen. Was ist GWS (Git Workspace)? gws is a KISS, bash, colorful helper to manage workspaces composed of git repositories. Wie die Einführung des Autors von GWS bereits erklärt, handelt es sich bei GWS um ein einfaches Bash Skript, welches Referenzen zu Git Repositories in einer einfachen Textdatei speichert und einige Hilfsmittel anbietet, um mit diesen Referenzen zu arbeiten. Das Interessante daran ist, dass das Bash Skript ohne Abhängigkeiten (ausser Git und Bash) auskommt und auch direkt, zusammen mit der Textdatei, mit den Referenzen gespeichert werden kann. Wie arbeite ich mit GWS? Als erstes lädt man sich das Bash Skript vom GitHub Projekt herunter: StreakyCobra/gws. Anschliessend wird eine Textdatei mit dem Namen .projects.gws angelegt, welche die Referenzen zu den gewünschten Repositories beinhaltet:
Hinweis: Zeilen, welche mit # beginnen gelten als Kommentare. Als nächstes initialisiert man die Repositories mit gws update: Nun wurden alle referenzierten Git Repositories in die angegebenen Unterverzeichnisse geklont. Diese Unterverzeichnisse sind unabhängige Git Repositories und man kann mit diesen arbeiten wie mit ganz normalen Git Repositories. Tipp: Das Verzeichnis, welches die Datei .projects.gws (und ggf. das GWS Skript selber) beinhaltet, kann auch in einem Git Repository gepflegt werden. Man sollte jedoch darauf achten, eine saubere .gitignore Datei zu erstellen. Beispiel:
# Ignore everything, so all repositories in our case
*
# But not these files
!.projects.gws
!.gitignore
!gws
!README.md
Weitere Tricks mit GWS Der oben beschriebene Einstieg in GWS ist erst der Anfang. Das Tool bietet noch einige weitere coole Features. Schnelles Initialisieren Hat man bereits viele verschiedene Git Repositories in einem Verzeichnis, hilft gws init, ein Inventar aller Git Repositories in den Unterverzeichnissen zu erstellen und diese in der Datei .projects.gws zu erfassen.
Status Mittels gws status sieht man auf den ersten Blick, ob alle Repositories auf dem neuesten Stand sind, ob Änderungen nicht committed wurden, etc.
Update aller Repositories Möchte man z.B. alle referenzierten Repositories auf den neuesten Stand bringen, kann man dies einfach mit gws ff machen. Dies macht in allen Repositories einen git pull. Oder mit gws fetch wird in allen Repositories ein git fetch durchgeführt.
Tobias Brunner
Tobias Brunner arbeitet seit über 20 Jahren in der Informatik und seit bald 15 Jahren im Internet Umfeld. Neue Technologien wollen ausprobiert und darüber berichtet werden.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Amazee Group lanciert Managed Drupal Hosting – amazee.io
2. Mai 2016
Heute hat Amazee Labs, einer unserer langjährigen Referenzkunden, Managed Drupal-Hosting lanciert.
Wir sind besonders stolz darauf, dass Amazee Group auch für den Betrieb der neuen Plattform – amazee.io – VSHN als Engineering- und Betriebspartner ausgesucht hat. (mehr …)
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Wir sind hocherfreut, dass das Thema DevOps in den letzten Monaten auch in der Schweiz an Bedeutung gewonnen hat. „DevOps ist zentral für die digitale Zukunft von SIX“. Die Kernessenz dieser Headline, nämlich digitale Projekte mit der richtigen Geschwindigkeit und Qualität zu realisieren, lässt sich nur durch das Zusammenbringen und bereichsübergreifender Kommunikation zwischen Business, Dev (Entwicklung) und Ops (Betrieb) erfolgreich umsetzen. Sowohl bei VSHN wie auch bei SIX schliessen sich DevOps und zertifizierte Sicherheit im Finanzumfeld überhaupt nicht aus. Wir sind stolz darauf, SIX Payment Services zu unseren Referenzkunden zählen zu dürfen.
Patrick Stampfli (ELCA) schreibt in seinem Gastbeitrag „In the Code: Alle lieben DevOps – oder?“ über die Herausforderungen bei der Umstellung vom traditionellen „Design-Build-Run-Zyklus“ zur kontinuierlichen „On-Air-Software“. „Eine wirkliche End-to-End-Agilität in der Softwareentwicklung“ ist erst dann möglich, wenn neben der Anpassung der Planungs- und Entscheidungsprozesse hin zur Agilität auch die Automatisierung der technischen Prozesse (die „Voraussetzungen für DevOps“) erfolgt ist. Wie die Einführung in einem grossen Unternehmen geschehen kann, beschreibt netzwoche.ch in „A Virtual DevOps Journey“. Eine etwas kürzere Schritt-für-Schritt-Anleitung bietet computerworld.ch in „Erfolgsrezept DevOps in vier Schritten einführen“. Auch Umfragen belegen, dass das Thema DevOps bei den Entscheidern in Schweizer Unternehmen konkret wird:
77% geben an, DevOps machen zu wollen, weil sie Software für mehrere verschiedenen Plattformen betreiben müssen und sie darum Automation benötigen.
31% geben Applikationen für Mobilgeräte als treibende Kraft an.
30% nennen die steigende Komplexität der Infrastrukturen (physisch, virtuell, Cloud) als Motivation, die Prozesse zu automatisieren um unabhängig(er) von der Infrastruktur zu werden.
Für 27% ist die Steigerung der Qualität und Geschwindigkeit wichtig.
Selbstverständlich sieht auch Google das steigende Interesse nach DevOps aus der Schweiz. So freuen wir uns umso mehr, erfolgreich in diesem aufstrebenden Markt unterwegs zu sein.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Puzzle ITC und VSHN lancieren APPUiO – die Schweizer Enterprise PaaS
1. März 2016
Der Open Source Dienstleister Puzzle ITC und die DevOps Company VSHN AG kombinieren ihre Stärken und lancieren gemeinsam die Schweizer Enterprise PaaS “APPUiO“. APPUiO basiert auf der “next generation PaaS” OpenShift Enterprise V3 von Red Hat. Auf bewährten Open Source Projekten wie Docker und Kubernetes (mehr …)
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
DevOps ist ein weit verbreiteter Begriff, aber leider ähnlich vage wie „Cloud“: zwar weiss jeder, dass er es will oder braucht und dennoch ist es nicht etwas, was man einfach bestellen und geliefert bekommen kann. Wir verstehen unter DevOps die interdisziplinäre Zusammenarbeit zwischen Entwicklern (Developers) und Betreibern (Operators) von Software, um die Applikationen schnell und systematisch einzusetzen.
Ähnlich wie bei Agiler Softwareentwicklung (z.B. Scrum) – bei dem der „Product Owner“ mit den Softwareentwicklern zusammen die jeweils nächstfolgenden Entwicklungsschritte spezifiziert und fertiggestellte Arbeiten abnimmt – fördert dies die Kommunikation zwischen den beteiligten Parteien und vermindert Missverständnisse und dadurch teure Fehler. Die Förderung der Zusammenarbeit zwischen Entwicklern und Betreibern steht im Kontrast zur bisherigen Praxis, diese Teams strikt zu trennen – sei dies aus Gründen der Gewaltentrennung (kein Zugriff der Entwickler auf Produktionsdaten) oder weil Entwickler und Betreiber unterschiedliche Anforderungsprofile erfüllen mussten (Programmierkönnen, Bereitschaftsdienst). Unterdessen sind aber eine Reihe von Erkenntnisse und bewährte Verfahren aus der Softwareentwicklung auch in den Betriebsprozessen angekommen:
Infrastructure as Code: Die Beschreibung und Konfiguration der Infrastruktur-Komponenten mittels Skripts, um wiederkehrende Aufgaben (z.B. Installation eines Servers oder Installation / Upgrade einer Applikation) schnell und zuverlässig zu automatisieren. Je nach Anwendungsfall und Umgebung gibt es dafür unterschiedliche Werkzeuge – Docker, Ansible, Puppet, SaltStack, etc. – die bereits eigene Frameworks und Ökosysteme mit fertigen Bausteinen für Standardkomponenten mitbringen.
Testsysteme: Wenn das Aufsetzen eines Servers komplett automatisiert ist, minimiert dies den Aufwand, einen oder mehrere Testserver zu erstellen. Wenn die Entwickler einen Testserver benutzen können, der gleich aufgesetzt ist wie ein Produktionsserver, können sie Fehler finden, bevor sie auf der Produktion auftreten.
Versionierung: Ist die Infrastruktur oder zumindest Teile davon in Code abgebildet, so kann man diesen mit bekannten Code-Versionierungstools (Git, SVN, etc.) verwalten. Dies ermöglicht die Nachvollziehbarkeit von Änderungen an der Infrastruktur („Wer hat was wann geändert?“, „Warum funktioniert das plötzlich nicht mehr, obwohl an der Software nichts geändert wurde?“) und das lückenlose Zurückrollen von Änderungen, falls doch mal ein Fehler auftreten sollte.
Kontinuierliche Integration des Infrastrukturcodes: So wie auch die eigentliche Applikation automatisch bei jeder Änderung kompiliert und sowohl komponentenweise als auch gesamtheitlich funktional getestet wird, können auch die Anforderungen an die Infrastruktur anhand automatisierter Tests verifiziert werden. Durch das möglichst frühzeitige Erkennen eines Fehlers werden die Auswirkungen minimiert. Zum Beispiel kann das Publizieren von Änderungen gesperrt werden, falls Fehler beim Testen aufgetreten sind.
Umgekehrt fliessen auch Erfahrungen aus dem Betrieb in moderne Softwarearchitekturen ein:
Paketisierung und Versionsverwaltung: Damit über den gesamten Qualitätssicherungsprozess von Test- / Entwicklungsserver, Abnahme durch den Product Owner, evtl. externes Testen / Validieren (Beta-, User-, UX-Tests), Integration mit externen Schnittstellen (Backends, APIs) bis zur Produktion alle beteiligten Personen von der jeweils gleichen Version der Software sprechen, wird diese in einem versionierten Paket abgelegt. Die Art der Paketierung kann dabei von der Entwicklungs- (z.B. JAR bei Java, WAR bei Tomcat) oder Betriebsumgebung (z.B. DEB/RPM bei Linux, MSI bei Windows) vorgegeben oder wie z.B. im Falle von Docker auch unabhängig sein. Dies stellt sicher, dass die Software komplett (mit allen benötigten Bibliotheken) installiert und aktualisiert werden kann und automatisiert diese Schritte soweit möglich.
Service Oriented Architectures (SOA) und Microservices: Sobald eine Applikation in der Entwicklung so umfangreich und / oder komplex wird, dass sich mehr als eine handvoll Teams darum kümmern, ist es einfacher, die Teams in kleinere Sub-Projekte („Microservices“) aufzuteilen und die Schnittstellen dazwischen explizit zu definieren als alle Teams untereinander im gleichen „Projekt“ bezüglich Technologie, Entwicklungsfortschritt und interner Zuständigkeiten zu koordinieren. Damit können die Teams nicht nur entkoppelt voneinander weiterentwickeln, sondern könnten sogar für ihren Zweck geeignetere Technologien wählen – vorausgesetzt, die Schnittstelle zu anderen Teams ändert sich nicht. Optimalerweise wären die meisten Komponenten / Services untereinander fehlertolerant, funktionieren also bei Ausfall einer Sub-Komponente mit eingeschränkter Funktionalität weiter, wodurch das Gesamtprojekt robuster wird.
Configuration Management: Die meisten Applikationen haben Schnittstellen zu anderen Applikationen – zum Beispiel zu einer Datenbank oder anderen APIs / Services – und schreiben Protokolldateien. Während der Entwicklung, dem Testing in der Qualitätssicherung und für die Produktion werden unterschiedliche Endpunkte (Adressen, Zugangsdaten etc.) dafür verwendet. Dies ermöglicht die Isolation von Test- und Produktivdaten; ein Test einer neuen Version kann also nicht aus Versehen die produktiven Kundendaten löschen. Darum werden die Zugangsdaten nicht direkt im Code verwaltet, sondern in Konfigurationsdateien, die wiederum für jede Umgebung automatisch generiert oder aus Umgebungsvariablen gelesen werden können. Eine moderne Definition dafür ist zum Beispiel die Zwölf-Faktoren-Methode (http://12factor.net/de/).
Skalierbarkeit: Applikationen und Services, die klar definierte Schnittstellen haben, können einfach horizontal – also über verschiedene Server verteilt – skaliert werden. Dies ermöglicht dem Betrieb, den Service mehrfach, redundant und damit hochverfügbar anzubieten und auf unterschiedliche Last durch hinzufügen oder entfernen von Servern zu reagieren. Selbst diese Schritte können automatisiert werden: Es ist möglich, automatisch aufgrund der aktuellen Auslastung mehr Serverressourcen zu beziehen respektive wieder frei zu geben und abhängig vom Abrechnungsmodell der einzelnen Ressourcen Kosten nur dann zu produzieren, wenn die Leistung auch effektiv genutzt wird.
Was bringt nun die Verschmelzung von Entwicklungsmethoden und Betriebsprozessen konkret?
Die Automatisierung der Infrastruktur (siehe „Infrastructure as Code“ oben) macht die Infrastruktur schneller, zuverlässiger und verhindert Inkonsistenzen durch (fehlende) manuelle Schritte auf verschiedenen Systemen. Sie ermöglicht, dass Entwickler und Product Owner ihre Ergebnisse effektiv unter gleichen Bedingungen wie die Produktion testen können.
Die Automatisierung des Software-Lebenszyklus von der Entwicklung bis zur Produktion macht den ganzen Prozess schneller, zuverlässiger und kann optimalerweise vom Product Owner selbst nach Freigabe der neuesten Version durchgeführt werden. Dadurch geben nach den Entwicklern auch die Betreiber dem Business die Zügel für die Applikation in die eigenen Hände und stehen für Weiterentwicklungen zur Verfügung. Damit kann der Product Owner sowohl den Umfang als auch die Frequenz der Deployments bestimmen. Je häufiger ausgerollt wird, was zur Folge hat, dass der Umfang der jeweiligen Änderungen kleiner ausfällt, desto kleiner ist das Risiko von unerwünschten Nebenwirkungen und Fehlern. Tauchen dennoch einmal Fehler auf, kann der Product Owner selbst die letzte Änderung rückgängig machen und die Entwickler zur Nachbesserung aufbieten, ohne den Betrieb damit zu belangen.
Beides zusammen verhindert, dass die IT im Selbstzweck den kritischen Pfad des Projektes blockiert und befähigt die Entwickler und das Business zur „Selbstbedienung“. Natürlich bedeutet das auch einen Kulturwandel innerhalb eines Unternehmens: schlägt ein Deployment fehl oder treten Probleme in der Produktion auf, so müssen Entwickler und Betriebsleute das Problem zusammen beheben und sicher stellen, dass es nicht wieder vorkommt (z.B. mittels automatischem Test). Dabei ist unerheblich, warum oder wegen wem das Problem aufgetreten ist: es muss kein „Schuldiger“ gefunden, sondern der Gesamtprozess kontinuierlich verbessert werden.
Wir bei VSHN machen den ganzen Tag nichts anderes, als verschiedene Entwicklungsprozesse, verschiedene Technologien, verschiedene Backends (Datenbanken, Cache-Server, Proxies, WAFs etc.) zu automatisieren und gemäss Anforderungen unserer Kunden und / oder Entwicklungs-Partnern auf beliebiger Infrastruktur – seien das öffentliche Clouds wie Amazon, Azure, Cloudscale.ch, Cloudsigma, Exoscale.ch, Safe Swiss Cloud, Swisscom Cloud oder private, also firmeninterne Infrastrukturen auf VMware- oder Hyper-V-Basis – zu betreiben. Wir beraten unsere Kunden bezüglich Ort der Datenspeicherung (CH, EU, international), sind auch selber bald ISO27001-zertifiziert und können zusammen mit unseren Partnern Hosting gemäss FINMA-Standard anbieten. Unsere Kernwerte sind Vertrauenswürdigkeit und Erreichbarkeit der fachlichen Kompetenz. Vertrauenswürdigkeit und Sicherheit durch Transparenz: transparente Kommunikation der Prozesse, transparente Auftragsdefinitionen und Verrechnungsmodelle. Wir arbeiten agil mit unseren Kunden und kommunizieren regelmässig. Wir sind 24×7 rund um die Uhr erreichbar und kümmern uns proaktiv um „unsere“ Applikationen. Wir sind VSHNeers.
Aarno Aukia
Aarno ist Mitgründer der VSHN AG und als CTO für die technische Begeisterung zuständig.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Wir von VSHN wollen unsere Kunden bei einem sauberen Lifecycle Management ihrer Software unterstützen. Dafür stellen wir ihnen mit Hilfe von Puppet mehrere Umgebungen zur Verfügung. Dies kann mit einer Testmaschine für die Entwickler beginnen, (mehr …)
matthias.indermuehle
Matthias ist Mitgründer der VSHN AG, Mitglied der Geschäftsleitung, und Partner
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet
Unser Weihnachtsgeschenk an die Open Source Community: Wir veröffentlichen unser Tool “crmngr” (Control Repository Manager) auf Github unter der BSD-3-Clause Lizenz: https://github.com/vshn/crmngr.
Dieses Tool hilft uns, die vielen Puppet Environments zu verwalten, welche bei uns durch r10k gesteuert werden. Es bietet zwei Hauptfunktionen: Reporting und Updates. Mit der Report-Funktion bekommen wir einen Überblick darüber, welche Puppetmodule in welcher Version in welchem Puppet-Environment verwendet werden. Ausserdem wird auf den ersten Blick ersichtlich, ob ein Puppetmodul veraltet ist und eine neuere Version zur Verfügung steht – sei das auf Puppet Forge oder zum Beispiel in einem Git Repository. Die Update-Funktion erlaubt es, Module in Puppet-Environments auf einen neueren Stand zu bringen, ein neues Modul hinzuzufügen oder ein Modul zu entfernen. Des Weiteren ist es möglich, über mehrere Environments hinweg Module zu aktualisieren oder andere Veränderungen vorzunehmen. Im Kern arbeitet “crmngr” direkt mit dem r10k Control Git Repository. Es analysiert die Branches und die Puppetfiles innerhalb der Branches des Git Repositorys. Es ist keine manuelle Interaktion mit dem Repository mehr notwendig, “crmngr” kümmert sich um alles (git pull, git commit, git push, etc). Slides vom Puppet Meetup in Zürich, welche „crmngr“ vorstellen, sind auf Speakerdeck zu finden. Die Dokumentation zur Installation und Verwendung des Tools ist im READMEabgelegt. Wir freuen uns über jedes Feedback und jede Contribution zu „crmngr“.
Tobias Brunner
Tobias Brunner arbeitet seit über 20 Jahren in der Informatik und seit bald 15 Jahren im Internet Umfeld. Neue Technologien wollen ausprobiert und darüber berichtet werden.
Latest news
Allgemein
Sovereignty
EUR 180 Millionen für Sovereign Cloud: Was die erste souveränitätsbewertete Ausschreibung der EU für Schweizer Organisationen bedeutet