Camel-K – Leichtgewichtige Cloud-Integrations-Plattform

Im Sommer letzten Jahres startete Camel-K[1] als eine Community-getriebene Plattform für das einfache und schnelle Deployment von Apache-Camel[2]-Anwendungen als Cloud-Native-Serverless-Funktionen in Kubernetes oder Openshift. Das Projekt Camel-K verbindet damit die erfolgreiche Enterprise-Integration-Bibliothek Apache-Camel mit dem Serverless-Ansatz. Die in Camel geschriebenen Integrationen können damit direkt auf einer Cloud-Plattform wie Kubernetes ausgeführt werden.

Was ist Apache Camel?

Apache-Camel implementiert als Open-Source-Framework die wichtigsten Enterprise-Integration-Patterns[3]. Diese Patterns wurden bereits 2004 von Gregor Hohpe and Bobby Woolf im gleichnamigen Buch[4] beschrieben und gelten noch heute als zutreffende Lösungsansätze, wenn zwei oder mehr Systeme miteinander integriert werden sollen. Die vorgeschlagenen Lösungsmuster helfen bei der Bewältigung gängiger Herausforderungen die sich ergeben, wenn unterschiedliche Systeme Daten miteinander austauschen. Dabei geht es vor allem um Themen wie Routing, Transformation, Aggregation, Messaging und Event-Streaming.

Diese Integrationsmuster werden in Apache-Camel in einfach zu verstehenden Routen (Abb. 1) umgesetzt, die man in verschiedenen Laufzeitumgebungen (Stand-alone Fat-JAR, Spring-Boot, WildFly, Apache-Karaf) ausführen kann.

 

Route in Apache Camel. (Abb. 1)

 

Seit mehr als zehn Jahren wird Apache-Camel als Framework stetig weiterentwickelt und stellt mittlerweile über 250 Komponenten für die Integration verschiedenster Systeme zur Verfügung. Mithilfe dieser einsatzbereiten Komponenten kann eine Middleware-Integration-Software unterschiedliche Datenformate (JSON, XML, CSV etc.) mit verschiedensten Service-Providern (z.B. Salesforce, Twitter, Amazon, Google-App-Engine) auf unterschiedlichen Transportwegen (HTTP, JMS, FTP, Kafka-Streams etc.) austauschen.

(Listing 1) zeigt eine einfache Apache-Camel-Route, die Nachrichten über einen Eingangskanal (telegram:bots/greeting-bot[5]) zunächst anhand des Nachrichteninhalts filtert, diese gefilterten Nachrichten in einzelne Teile splittet und einzeln an einen Ausgangskanal (kafka:greeting-words[6]) weiterleitet.

 

Listing 1

 

Das Beispiel zeigt wie einfach man eine Middleware-Integration mit Hilfe der Apache-Camel Java-DSL beschreiben und umsetzen kann. Wird zum Beispiel eine Nachricht Hello from Camel K! über den Telegram-Bot abgesetzt, aktiviert die Camel-Route die Verarbeitung und das Resultat sind vier Nachrichten Hello, from,

Camel, K!, die einzeln auf den angegebenen Kafka-Topic-Stream gesendet werden. Diese Apache-Camel-Route lässt sich mit Camel-K nun als Serverless-Function direkt in Kubernetes oder OpenShift ausführen und automatisch skalieren.

Warum Serverless?

Das „K“ in Camel-K ist eine Anspielung auf die Container-Orchestrierungs-Plattform Kubernetes. Die Technologie rund um Docker und Kubernetes hat in den letzten Jahren einen immensen Erfolgsweg aufzuweisen und ist noch immer in aller Munde. Auf Kubernetes basierend entwickeln sich weitere interessante Technologien und Paradigmen, wie zum Beispiel der Serverless-Ansatz.

Serverless beschreibt die Idee sehr klein geschnittene Anwendungsteile (Serverless-Functions) auf Cloud-Plattformen wie zum Beispiel Kubernetes als hoch skalierbare containerbasierte Einheiten zu betreiben. Was mit der Microservices-Idee begann, wird mit Serverless also noch einen Schritt weiter geführt. Ziel ist es, einzelne Logikbausteine schnell und vor allem einfach in einer containerbasierten Laufzeitumgebung zu deployen. Die Bausteine sollen gezielt eine einzige Funktionalität abbilden und werden durch bestimmte Events getriggert. Wenn die Funktionalität zu einem Zeitpunkt nicht gebraucht wird, kann es sogar dazu kommen, dass die Serverless-Function in Kubernetes komplett auf Null skaliert wird. Dadurch werden Infrastruktur-Ressourcen für andere Dienste frei und können effizient genutzt werden. Wird die Serverless-Function hingegen durch ein Event oder einen Request angesprochen, aktiviert Kubernetes die Anwendung automatisch und skaliert diese entsprechend der Anfragen nach oben. Um diese automatische Skalierung effizient durchführen zu können, bedarf es einigen Voraussetzungen, die gerade in der Java-Welt nicht immer vollständig gegeben sind:

Serverless-Functions

  • müssen sich schnell starten und stoppen lassen,
  • sollten möglichst wenig Memory und CPU anfordern,
  • müssen komplett zustandslos sein.

 

Vor allem die Zeiten für den Start bzw. Stopp von Java-Prozessen sowie der Speicherbedarf einer JVM kann ein Hindernis für Serverless-Anwendungen sein. Die ständige Skalierung bedeutet ein häufiges Starten und Stoppen der Anwendung. Bei hoher Nutzung der Serverless-Functions bedeutet dies unter Umständen auch viel Memory- und CPU-Bedarf.

Neben diesen Aspekten für die automatische Skalierung gibt der eigentliche Build-Deploy-Zyklus während der Entwicklung ebenfalls Grund zur Optimierung. Mit Tools wie dem Fabric8-Maven-Plugin[7] gibt es bereits effiziente und einfache Wege eine klassische Java-Anwendung als Container in einem Pod in Kubernetes zu deployen. Wenn wir jedoch den klassischen Aufbau mit einer in Java geschriebenen Apache-Camel-Route verpackt in einer Spring-Boot-Web-Anwendung betrachten, dauert ein Build-Deploy-Zyklus eines Java-Containers in etwa 1 bis 2 Minuten. Dies summiert sich bei häufigem Deployment während der Entwicklung und ist im Vergleich zu anderen Cloud-Native-Technologien relativ langsam. Aus diesem Grund sind im Gegensatz zu Java andere Sprachen wie NodeJS oder Go sehr beliebt in der Serverless-Community.

Camel-K setzt genau hier an, um einige dieser Nachteile eines klassischen Java-Containers mit einer darin laufenden Apache-Camel-Anwendung signifikant zu verbessern. Mit Camel-K können Apache-Camel-Integrationen effizient als Serverless-Anwendungen betrieben werden.

Wie funktioniert Camel-K?

Camel-K nutzt einige Tricks, um sowohl den Memory-Bedarf einer Apache-Camel-Anwendung als auch die Start- und Stopp-Zeiten deutlich zu optimieren. Als Basis definiert Camel-K sogenannte Custom-Resource-Definitions (CRDs) für Apache-Camel und stellt einen Operator bereit, der die CRDs in Kubernetes verwaltet und überwacht. Camel-K definiert 3 unterschiedliche Custom-Resource-Definitions:

 

  • Integration: Enthält die vom User definierte Route.
  • Integration-Context: Repräsentiert das Basis-Image, welches in der Lage ist Integrations auszuführen. Ein Integration-Context kann gleichzeitig von mehreren Integrations genutzt werden.
  • Integration-Platform: Definiert die allgemeine Konfiguration der Plattform, um die Arbeitsweise des Camel-K-Operators zu beeinflussen.

 

Der Camel-K-Operator überwacht diese CRDs und wird automatisch aktiv, wenn eine dieser Custom-Resources neu hinzugefügt wird oder sich eine dieser Custom-Resources ändert. Der Operator erzeugt daraufhin Kubernetes-Built-in-Ressourcen wie Deployments, ConfigMaps oder Images. (Abb. 2) zeigt das Zusammenspiel zwischen Camel-K-Operator, dem Kommandozeilen-Tool kamel und der eigentlichen Routen-Definition in Java, Groovy, Kotlin oder JavaScript.

Zusammenspiel von kamel CLI, Camel-K-Operator und Kubernetes-Ressourcen. (Abb. 2)

 

Durch das extra für Camel-K entwickelte Kommandozeilen-Tool kamel wird die Zusammenarbeit mit dem Operator sehr vereinfacht und der Entwickler konzentriert sich voll und ganz auf die Definition der Apache-Camel-Routen.

Betrachten wir die Arbeit mit Camel-K nun anhand eines Beispiels. Voraussetzung ist eine Kubernetes- oder OpenShift-Laufzeitumgebung. Für den lokalen Test eignen sich die Tools minikube[8]oder minishift[9]. Zunächst muss das Kommandozeilen-Tool kamel[10] heruntergeladen und entpackt werden. Das Kommandozeilen-Tool unterstützt den Nutzer sowohl bei der Installation von Camel-K im Kubernetes-Cluster, als auch beim späteren Deployment der Serverless-Anwendungen. Folgender Befehl installiert Camel-K auf einem Kubernetes-/OpenShift-Cluster:

Listing 2

 

Dieser Befehl installiert den Camel-K-Operator sowie die Custom-Resource-Definitions (CRDs). Da diese Installation für den kompletten Cluster gilt, sind gegebenenfalls Cluster-Administrationsrechte erforderlich. In einem lokalen Minikube- oder Minishift-Cluster sollten Administrationsrechte kein Problem sein. Nun sind alle benötigten Camal-K-Ressourcen im Cluster installiert und der Camel-K-Operator ist gestartet (Abb. 3).

 

Installierte Camel-K-Ressourcen in Kubernetes. (Abb. 3)

 

Jetzt kann sofort eine erste Serverless-Camel-K-Route deployt werden:

 

Listing 3

Der run Befehl benötigt nur die Camel-Routen-Definition selbst und erstellt daraus einen Container im Kubernetes-Cluster. Neben Java werden hier auch andere Sprachen wir Groovy, Kotlin und auch JavaScript unterstützt. Das Kommandozeilen-Tool nimmt das Deployment vor und wir sehen neben dem bereits bei der Installation von Camel-K gestarteten Operator nun auch die neue Camel-K-Integration in der Übersicht der Deployments (Abb. 4). Das Resultat ist eine Apache-Camel-Route, die Ihren Dienst als Kubernetes-Pod aufgenommen hat und je nach eingehenden Anfragen automatisch skaliert wird.

 

Deployment einer Camel-K-Anwendung in Kubernetes. (Abb. 4)

 

(Listing 4) zeigt gleich mehrere in Groovy geschriebene Routen in einer Datei. Diese Groovy-Routen-Definition kann man mit dem run Befehl auf gleiche Weise im Kubernetes-Cluster deployen:

Listing 4

 

Das routes.groovy Beispiel zeigt neben mehreren Routen in einer Datei auch den Einsatz von Context-Objekten, die es erlauben wiederkehrende Konfigurationen zentral auszulagern. Damit lassen sich auch sensitive Daten wie Passwörter und Token-Informationen per ConfigMap und Secrets in Kubernetes laden. Die Camel-K-Anwendung wird wie gewohnt über das Kommandozeilen-Tool im Cluster deployed:

Listing 5

Das komplette Deployment der Camel-K-Serverless-Anwendung in den Clustern kann nun in unter fünf Sekunden durchgeführt werden. Eine Änderung der Routen-Definition und damit ein Redeployment der bereits laufenden Camel-K-Anwendung dauert in der Regel weniger als eine Sekunde! Dies stellt eine deutliche Verbesserung zu den Deployment-Zyklen mit S2i (Source-to-Image) oder normalen Image-Build-Deploy-Ansätzen dar, wenn von einer klassischen Java-Web-Anwendung mit Apache-Camel und zum Beispiel Spring-Boot ausgegangen wird.

Wie ist diese Optimierung möglich?

Der Camel-K-Operator interpretiert die zu startende Camel-Route und wählt die leichtgewichtigste Laufzeitumgebung dafür aus. Zusätzlich erstellt der Operator das minimale Paket für den Code mit ausschließlich benötigten Camel-Komponenten und deren Abhängigkeiten. Zuletzt optimiert der Operator die Camel- und JVM-Parameter für die Ausführung. Das bedeutet, dass der Camel-K-Operator den Quellcode einer Route versteht und ein ideales Deployment erstellt.

Beim Redeployment kann der Camel-K-Operator bereits erstellte Images einfach wiederverwenden, da die Routen-Definition an sich nicht Teil des Images ist, sondern als ConfigMap beim Deployment hinzugefügt wird. Somit sind Änderung der Routen-Definition lediglich eine Änderung der ConfigMap. Ein Rebuild des Images entfällt komplett.

Fazit

Mit Hilfe des optimierten Build-Deploy-Zyklus kann Camel-K die Apache-Camel-Routen sehr schnell auf einer Cloud-Plattform wie Kubernetes-nativ zur Ausführung bringen. Im Sinne von automatisierter Skalierung wird die Serverless-Anwendung dynamisch gestartet und gestoppt.

Der Memory-Bedarf einer Camel-K-Serverless-Anwendung ist ebenfalls optimiert. Es sind weitere signifikante Optimierungen für dieses Jahr geplant, die sich enorm positiv auf die Leichtgewichtigkeit und Schnelligkeit der Camel-K-Prozesse auswirken. Ahead-of-time Kompilierung und Native-Images sind hier Wege zu noch viel schnelleren Startzeiten und enorm minimiertem RAM-Bedarf. Es bleibt also spannend noch weitere Verbesserungen in diesem Bereich zu sehen.

Eine weitere spannende Entwicklung rund um Camel-K ist die Integration mit Knative[11]. Knative stellt eine weitere Zielplattform von Camel-K dar, wobei vor allem die Zusammenarbeit mit den in Knative definierten Bereichen Serving und Eventing von großem Interesse sind.

Der Java-basierte Ansatz für Serverless-Enterprise-Integration-Anwendungen mit Apache-Camel als zentrale Enterprise-Integration-Bibliothek ist schon jetzt mit den bereits bestehenden Mitteln rund um Camel-K wieder sehr interessant geworden. Die Effizienz von Kubernetes in der Zuweisung von Ressourcen und die automatische Skalierung funktionieren in Camel-K sehr gut und machen Apache-Camel bereit für den Einsatz im Serverless-Umfeld.

Christoph Deppisch arbeitet als Senior-Software-Engineer bei RedHat. Dort beschäftigt er sich im RedHat-Fuse-Team vor allem mit Middleware-Integration, Apache-Camel und der Entwicklung der Integrationsplatform Fuse-Online. Als leidenschaftlicher Verfechter von Testautomatisierung gründete und entwickelte er das Open-Source-Integration-Testframework Citrus und teilt seine Erfahrungen gerne in regelmäßigen Blogs, Fachartikeln und als Speaker auf internationalen Konferenzen.

 

Links:

[1] https://bit.ly/2UShWO9  

[2] http://camel.apache.org/

[3] https://bit.ly/2WnYauq 

[4] https://bit.ly/2HU4uWI   

[5] https://bit.ly/1SC2vkI

[6] https://kafka.apache.org/

[7] https://bit.ly/2WjGBvm

[8] Mehr zu CRDs und Operatren in Kubernetes:

https://bit.ly/2C9dILC https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/

[9] Mehr zu CRDs und Operatren in Kubernetes: https://coreos.com/operators

[10] https://bit.ly/2E40UaE

[11] https://bit.ly/2FB6zVK  

[12] https://bit.ly/2U0NPIf

[13] https://github.com/knative/

 

Victoria Krautter


Leave a Reply