Beliebte Suchanfragen

Cloud Native

DevOps

IT-Security

Agile Methoden

Java

//

Canary-Release mit der Very Awesome Microservices Platform (Vamp)

11.10.2015 | 7 Minuten Lesezeit

Im letzten Artikel der Serie “Microservice-Deployment ganz einfach ” erkläre ich, dass Docker nicht zwingend notwendig ist, um Microservice-Anwendungen auszuliefern. Wie der Artikel zeigt, kann man die Linux-Paketverwaltung benutzen, um Microservice-Anwendungen schnell und komfortabel auszuliefern. Leider muss man sich bei diesem Ansatz um die Auslastung seiner Rechner und die Verteilung der einzelnen Microservices auf die unterschiedlichen Rechner selbst kümmern. Es ist aus meiner Sicht aber wünschenswert, dass man einem Rechner-Cluster einfach Arbeit in Form eines Microservice gibt und sich das Cluster eigenständig darum kümmert, die Microservices entsprechend zu verteilen und auszuführen. In der Praxis interessiert mich eigentlich nicht wo ein Microservice läuft, sondern nur das ein bestimmter Microservice läuft. Mit Kubernetes stelle ich im Artikel “Microservice-Deployment ganz einfach mit Kubernetes” ein Werkzeug vor, dass mich bei der Verteilung der Container in einem Rechner-Cluster unterstützt und mir zusätzlich auch noch dabei hilft, dass sich die Container auf unterschiedlichen Rechnern gegenseitig finden. Mein Kollege Christian Zunker beschreibt die Service-Discovery-Thematik, die durch die Verteilung von Docker-Containern auf unterschiedlichen Rechnern entsteht, ausführlich in seinem Artikel “Variation des Ambassador Pattern von CoreOS ”.

Microservice-Deployments mit Kubernetes

Kubernetes benutzt Pods, Replication Controller und Services, um Docker-Container in einem Rechner-Cluster zu verteilen und auszuführen. Weiterhin verfügt Kubernetes über ein sehr nützliches Feature, das so genannte Rolling-Update. Mit ihm kann man beliebige Docker-Container über mehre Knoten hinweg zeitverzögert ausliefern. Damit hat man die Möglichkeit einen Microservice auszurollen und mit realem Traffic entsprechende Daten über den Erfolg eines Deployments zu sammeln, bevor ein Microservice im kompletten Cluster ausgeliefert ist. Geht etwas schief, hat man immer noch die Möglichkeit das Deployment abzubrechen. Damit minimiert man die Gefahr, dass grobe Softwarefehler im kompletten Cluster in Produktion landen. Allerdings gilt das nur für Softwarefehler, wenn unsere Fachabteilungen bei der Produktentwicklung Änderungen machen, die die Benutzer nicht gut finden, dann stellt man das erst am geringeren Umsatz nach dem Deployment fest. Es ist aber aus meiner Sicht wünschenswert, dass man im Produkt-Entwicklungsprozess Kundenfeedback nach Fertigstellung einer neuen Funktionalität einholen kann, um eine Produktidee zu verbessern.

Dazu wäre es gut, wenn man einen Router hätte, der die Verteilung der Benutzer entsprechend bestimmter Regeln auf unterschiedliche Docker-Container organisiert, um das Benutzerverhalten mit einem Teil seiner Kunden messen und analysieren zu können. Einen solchen Router besitzt Kubernetes allerdings nicht. Die Verteilung der Benutzer ist abhängig von der Anzahl der Knoten im Kubernetes-Cluster, auf die die neue Version der Software ausgeliefert ist. Daher bietet Kubernetes out-of-the-box keine Möglichkeit, ein so genanntes Canary-Release abzubilden.

Canary-Release

Ein Canary-Release verwendet man, um das Risiko bei der Einführung einer neuen Software-Version zu vermindern. Man stellt Änderungen erst mal nur einem Teil seiner Benutzer zu Verfügung und misst wie dieser Teil auf die Änderungen reagiert, bevor man die neue Software auf der kompletten Infrastruktur ausrollt. Durch dieses Vorgehen hat man die Möglichkeit die Software schrittweise zu verbessern.

Ein Canary-Release ähnelt in der Ausführung einem Blue-Green-Deployment , das aber das Ziel verfolgt, die Downtime einer Applikation zu minimieren. Dazu hält man zwei Infrastruktur-Stränge für zwei unterschiedliche Softwareversionen vor und leitet die Benutzer über einen Router auf die entsprechende Version um. Bei einem Blue-Green-Deployment macht man einen harten Wechsel auf die neue Version der Software. Beim Canary-Release leitet man dagegen z.B. nur 5 Prozent des Traffic auf die neue Version um. Mit einem Canary-Release möchte man also vielmehr herrausfinden, ob eine neue Funktionalität wirklich eine signifikante Veränderungen im Verhalten der Benutzer auslöst. Diese Releases können auch benutzt werden, um A/B-Testing zu implementieren.

Microservice-Deployments mit Vamp

Vamp oder Very Awesome Microservices Platform vereinfacht das Durchführen von Canary-Releases. Vamp unterstützt im Moment Mesos und Marathon , später soll aber auch Kubernetes als Container-Manager hinzukommen. Die Plattform wird von der niederländischen Firma magnetic.io entwickelt. Ähnlich wie Kubernetes ist Mesos ein Dienst zum Starten von Docker-Containern in einem verteilten Rechner-Cluster. Mesos ist zuständig für Ressourcenverwaltung im Cluster und kann mit Marathon das Deployment von Microservice-Anwendungen durchführen. Marathon übernimmt dabei die Aufgabe eines Schedulers, der die Verteilung und Ausführung von Docker-Containern steuert. Viele große Firmen setzen ähnliche Technologie-Stacks schon erfolgreich in Produktion ein, darunter sind z.B, Apple , Holidaycheck und Otto.

Vamp ist ein Dienst, der sich überhalb eines Container-Manager ansiedelt und aus mehren Bestandteilen besteht. Vamp-Core bietet eine Plattform-agnostische DSL und ein REST-API. Die DSL kann ähnlich wie Giant Swarm und Docker-Compose benutzt werden, um eine Microservice-Anwendung mit ihren Abhängigkeiten zu beschreiben. Diese Beschreibung benutzt die REST-Schnittstelle von Vamp-Core, um mit Marathon die Microservices im Mesos-Cluster zu deployen. Darüberhin beinhaltet die DSL auch Elemente zum Beschreiben von A/B Tests und Canary-Releases sowie zum Beschreiben von SLAs. Diese SLAs sorgen dafür, dass wenn bestimmte Antwortzeiten unterschritten werden und noch Ressourcen im Cluster verfügbar sind, automatische neue Docker-Container im Cluster gestartet werden. Zum Sammeln der Metriken, die für die SLAs und A/B Tests benötigt werden, gibt es den Metriken- und Event-Store Vamp-Pulse, in dem Daten von Core und Router in Elasticsearch gespeichert werden. Der Vamp Router ist eine Komponente die einen HAProxy steuert, der die Verbindung zwischen den laufenden Docker-Containern und den eigentlichen Benutzern realisiert.

Wie in den vorgangegangen Artikeln der Serie “Microservice-Deployment ganz einfach ” benutze ich einen Online-Shop als Beispiel, um die Funktionionsweise vom Vamp zu zeigen. Diesen Online-Shop findet man in meinem Github-Repository . Die genaue Fachlichkeitsbeschreibung, die hinter diesem Beispiel steckt, erkläre in meinem Artikel “Microservices und die Jagd nach mehr Konversion” . Um Vamp für das Deployment unserer Microservice-Anwendung zu benutzen, müssen wir erst einmal einen so genannten Blueprint anlegen. Ein Blueprint ist eine Art Ausführungsplan für unsere Microservice-Anwendung, der in einer Datei gespeichert wird. Ein Blueprint beschreibt die abstrakte Topologie der Anwendung im Cluster. In einem Blueprint wird unter anderem beschrieben

  • welche Ports von außen erreichbar sind,
  • welche Abhängigkeiten zwischen den unterschiedlichen Microservices bestehen,
  • welche Microservices im Cluster für A/B Tests benutzt werden,
  • welche Routing-Regeln für A/B Tests bestehen,
  • wie viele Ressourcen (CPU, Speicher, Skalierung) reserviert werden müssen und
  • welche SLAs es geben soll.

Das folgende Listing zeigt einen Ausschnitt eines Blueprints des obengenanntem Online-Shops. Der vollständige Blueprint befindet sich auf Github.

1---
2name: shop:1.0
3
4endpoints:
5 catalog.port: 9050
6
7clusters:
8
9 catalog:
10   services:
11     -
12       breed:
13         name: catalog
14         deployable: zutherb/catalog-frontend:latest
15         ports:
16           port: 80/http
17         environment_variables:
18           CHECKOUT_DESIGN: standard
19           SHOP_PORT_8080_TCP_ADDR: $checkout.host
20           SHOP_PORT_8080_TCP_PORT: $checkout.ports.port
21           PRODUCT_PORT_18080_TCP_ADDR: $product.host
22           PRODUCT_PORT_18080_TCP_PORT: $product.ports.port
23           NAVIGATION_PORT_18090_TCP_ADDR: $navigation.host
24           NAVIGATION_PORT_18090_TCP_PORT: $navigation.ports.port
25           CART_PORT_18100_TCP_ADDR: $cart.host
26           CART_PORT_18100_TCP_PORT: $cart.ports.port
27         dependencies:
28           product: product
29           navigation: navigation
30           cart: cart
31           checkout: checkout
32       scale:
33         instances: 1
34         cpu: 0.1
35         memory: 128
36       routing:
37         weight: 100
38     -
39       breed:
40         name: catalogWithAlternativeCheckoutDesign
41         deployable: zutherb/catalog-frontend:latest-b
42         ports:
43           port: 80/http
44         environment_variables:
45           SHOP_PORT_8080_TCP_ADDR: $checkout.host
46           SHOP_PORT_8080_TCP_PORT: $checkout.ports.port
47           PRODUCT_PORT_18080_TCP_ADDR: $product.host
48           PRODUCT_PORT_18080_TCP_PORT: $product.ports.port
49           NAVIGATION_PORT_18090_TCP_ADDR: $navigation.host
50           NAVIGATION_PORT_18090_TCP_PORT: $navigation.ports.port
51           CART_PORT_18100_TCP_ADDR: $cart.host
52           CART_PORT_18100_TCP_PORT: $cart.ports.port
53         dependencies:
54           product: product
55           navigation: navigation
56           cart: cart
57           checkout: checkout
58       scale:
59         instances: 1
60         cpu: 0.1
61         memory: 128
62       routing:
63         weight: 0
64         filters:
65         - condition: User-Agent = Chrome
66
67 checkout:
68   services:
69     breed:
70       name: checkout
71       deployable: zutherb/monolithic-shop:latest
72       ports:
73         port: 8080/http
74       environment_variables:
75         CART_PORT_18100_TCP_ADDR: $cart.host
76         CART_PORT_18100_TCP_PORT: $cart.ports.port
77         MONGODB_PORT_27017_TCP_ADDR: $mongodb.host
78         MONGODB_PORT_27017_TCP_PORT: $mongodb.ports.port
79       dependencies:
80         mongodb: mongodb
81         cart: cart
82     scale:
83       instances: 2
84       cpu: 0.5
85       memory: 512

Diesen Blueprint schickt man einfach an das REST-API von Vamp-Core und dann wird die Anwendung im Cluster deployt. Wie die Orchestierung in einem 5 Node Cluster aufsieht, kann man in folgenden Video sehen. Außerdem ist zu sehen, wie A/B Tests ins laufende Cluster ohne Downtime deployt werden.

Mit dem Laden des Videos akzeptieren Sie die Datenschutzerklärung von YouTube.
Mehr erfahren

Video laden

YouTube immer entsperren

Fazit

Zusammenfassend kann man sagen, dass Vamp über eine Plattform-agnostische DSL die Möglichkeit bietet Microservice-Anwendung zu beschreiben und in einem Mesos-Cluster auszuführen. Vamp nimmt die Arbeit ab, dass man sich darum kümmern muss, wo ein Microservice läuft. Mesos findet freie Ressourcen im Cluster und startet dort Docker-Container. Vamp sorgt dafür, dass die entsprechenden Endpunkte der Services den entsprechenden Docker-Container mitgeteilt werden, die andere Microservices darstellen. Dies passiert über Umgebungsvariablen und einem HAProxy als Ambassador.

Mit dieser Plattform bekommt man völlig neue Möglichkeiten Microservice-Anwendungen auszuliefern. Man kann sehr einfach A/B Tests formulieren, mit denen man komplette Prozesse verändern und testen kann. Zur Auswertung der A/B Test muss man im Moment aber leider noch auf ein Web-Tracking wie Google Analytics zurückgreifen.  Außerdem wird die Ausführung von Zero-Downtime-Deployments und Skalierungsszenarien stark vereinfacht. Wenn mehr Hardware gebraucht wird, fügt man einfach neue Maschinen in das Cluster und Vamp sorgt dafür, dass bei einer Verlangsamung von Antwort-Zeiten automatisch neue Docker-Container gestartet werden.

Für alle, die das Thema mehr interessiert und die auch auf der kommenden W-JAX in München sein werden. Ich halte dort am 3. November den Vortrag “Von Null auf Hundert mit Microservices” , wo ich dieses Thema ausführlicher beleuchte.

Beitrag teilen

Gefällt mir

0

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.