Serverlose Lösungen mit Talend dank CI/CD und Containern

Warum sollten wir uns mit CI/CD und Containern beschäftigen?

CI/CD (Continuous Integration/Continuous Development) hat sich zu einem unverzichtbaren Bestandteil jedes erfolgreichen Softwareprojekts entwickelt – und das zu Recht, denn seine Vorteile sind nicht von der Hand zu weisen. Zugleich sind Container allgegenwärtig und vor allem bei Entwicklern sehr beliebt. In der Praxis ermöglicht die Softwareauslieferung nach dem CI/CD-Prinzip, dass die Benutzer schon früh ein positives Verhältnis zu den von den Entwicklern erstellten Anwendungen aufbauen können, weil sie die Software kontinuierlich testen und validieren können. Daneben gibt Containerisierung den Entwicklern viel Flexibilität bei der Verteilung und Ausführung ihrer Programme, weil diese nur einmal geschrieben werden müssen und dann, dank eines von Unternehmen verwendeten Standardformats, “überall” bereitgestellt werden können. Bei dieser mittlerweile gängigen DevOps-Praxis wird besonders der “Aber auf meinem Computer funktioniert es“-Effekt vermieden. Unmittelbare Vorteile sind auch die kürzere Time to Market und häufigere Auslieferungen.

Wie passt dies in die Talend-Umgebung?

Wir bei Talend möchten Sie an dieser umwälzenden Neuerung teilhaben lassen und Ihnen Zugang zum Besten aus beiden Welten geben. Seit der Freigabe von Talend 7.0 können Sie dank eines standardmäßigen Maven-Builds auch Talend-Jobs innerhalb von Docker-Images erstellen. Außerdem unterstützen wir Sie dabei, diesen Vorgang nahtlos in Ihre CI/CD-Pipeline zu integrieren.

Was hat das Ganze mit “serverlos“ zu tun?

Die serverlose Lösung steht am Ende dieser Kette: So stellen wir unsere Talend-Jobs bereit. Denn nun gibt uns die Tatsache, dass diese Jobs in Containern ausgeliefert werden können, die Freiheit, Integrations-Jobs an beliebigen Orten zu implementieren. Zu den neuen Möglichkeiten gehört außerdem, dass sich eine neue Kategorie von Diensten etabliert, die als “serverlos“ bezeichnet werden. Die meisten großen Cloud-Anbieter haben damit begonnen, ihre serverlosen Dienste für Container anzubieten; Beispiele dafür wären etwa AWS Fargate oder Azure Container Instances, um nur diese zu nennen. Mithilfe solcher Dienste lassen sich Container ausführen, ohne dass dazu eine Infrastruktur (Server oder Cluster) verwaltet werden muss. Kosten fallen nur für die Containernutzung an.

Diese neuen Funktionen haber wir auf der Talend Connect US 2018 im Rahmen der Haupt-Keynote mit einer Live-Demo vorgestellt. Zu sehen war die gesamte Entwicklungs-Pipeline vom Build bis zum ausgeführten Job in AWS Fargate und in Azure ACI. In diesem Blogbeitrag greifen wir zur Erstellung einer CI/CD-Pipeline auf das Softwaresystem Jenkins zurück. Die Pipeline umfasst den Build unserer Jobs in Docker-Images, deren Bereitstellung in einer Docker-Registry und sowie schließlich die Ausführung der Images durch Aufruf von AWS Fargate und Azure ACI.

Schema für serverlose Lösungen mit Talend dank CI/CD und Containern

Der Prozess wird im Folgenden schrittweise erläutert. Wenn Sie mitmachen wollen, achten Sie darauf, dass die nachstehenden Voraussetzungen erfüllt sind:

Voraussetzungen

  • Talend Studio ab Version 7.0
  • Talend Cloud Spring 18’ oder höher
  • Verfügbarer Jenkins-Server
  • Der Jenkins-Server benötigt Zugriff auf einen Docker-Daemon, der auf derselben Maschine installiert ist.
  • Talend CommandLine, auf derselben Jenkins-Maschine installiert
  • Nexus Version 2 oder 3
  • Der Talend CI Builder ist installiert und konfiguriert, und ebenso die Talend CommandLine.

* Alle aufgeführten Talend-Komponenten sind in der 30-Tage-Testversion der Talend Cloud enthalten.

Talend-Umgebung

Wenn Sie bisher nicht mit Talend gearbeitet haben, empfehlen wir Ihnen, sich zunächst im folgenden Abschnitt einen allgemeinen Überblick über die verschiedenen Komponenten zu verschaffen. Auf jeden Fall müssen Sie mit Talend Cloud beginnen und ein Projekt in der Talend Management Console (TMC) anlegen. Anschließend müssen Sie dieses Projekt so konfigurieren, dass die von Ihnen erzeugten Job-Artefakte in einem Git-Repository gespeichert werden. Geben Sie außerdem in den Einstellungen der TMC unter “Nexus“ den von Ihnen gehosteten Nexus-Server als Speicherziel für alle Bibliotheken von Fremdanbietern an, die für Ihren Job möglicherweise gebraucht werden. Das allgemeine Projekt- und Artefaktmanagement wird über das Talend Cloud-Konto in der TMC abgewickelt.

Als Nächstes installieren Sie Talend Studio und verknüpfen es mit dem Talend Cloud-Konto. Talend Studio ist die wichtigste Designumgebung von Talend, in der Integrations-Jobs erstellt werden. Wenn Sie sich mit diesen Schritten über Talend Studio im Cloud-Konto anmelden, werden Ihnen die Projekte aus der TMC angezeigt. Unter diesen wählen Sie das für das Git-Repository konfigurierte Projekt aus. Führen Sie die unten beschriebenen Schritte aus, um die erforderlichen Plug-ins zu Talend Studio hinzuzufügen.

Als letzte zwei Komponenten benötigen Sie den CI Builder und Talend CommandLine oder cmdline (wenn Sie die Testversion verwenden, befindet sich das Tool CommandLine bei den Installationsdateien von Talend Studio). Sollten Sie CommandLine zum ersten Mal verwenden, müssen Sie dem Tool ebenfalls eine Lizenz zuordnen, können aber dieselbe Lizenz wie für Studio verwenden. Mithilfe der Tools CommandLine und CI Builder können Sie den Code aus dem Job in Studio (genaugenommen aus Git) verwenden und mithilfe von Skripts vollständig ausführbare Prozesse für unterschiedliche Umgebungen erstellen und implementieren. Dabei hängt es vom CI Builder und dem Profil in Talend Studio ab, ob auf diese Weise eine Laufzeitumgebung für Talend Cloud oder ein Container entsteht. Gehen Sie zunächst wie folgt vor:

1) Legen Sie in Talend Cloud ein Projekt an.

Legen Sie zuerst ein Projekt unter Ihrem Talend Cloud-Konto an und verknüpfen Sie das Projekt mit einem GitHub-Repository. Lesen Sie in der Dokumentation die Anleitung durch, in der dieser Vorgang beschrieben wird.

Denken Sie daran, Ihren Nexus-Server über das Talend Cloud-Konto zu konfigurieren. Orientieren Sie sich dabei an der Dokumentation zur Konfiguration des Nexus-Servers mit Talend Cloud. Berücksichtigen Sie auch, dass der Server die folgenden Repositorys benötigt:

  • releases
  • snapshots
  • talend-custom-libs-release
  • talend-custom-libs-snapshot
  • talend-updates
  • thirdparty

2) Fügen Sie die Maven-Docker-Profile zu Talend Studio hinzu

Dieser Schritt wird bei Talend Studio ab Version 7.1 nicht mehr benötigt. Überspringen Sie diesen Teil, wenn Sie über die genannte Talend-Studio-Version verfügen (die Maven-Docker-Profile werden mittlerweile von Talend Studio generiert). Neu bei Talend Studio ist auch die Unterstützung von OpenJDK 8 durch Version 7.1. Damit können Sie in der Produktionsumgebung Docker-Basis-Images von OpenJDK Docker verwenden.

Wir fügen im Rahmen der Konfiguration von Talend Studio die Maven-Docker-Profile zur Konfiguration unserer Projekt- und Job-Pom-Dateien hinzu. Sie finden die beiden hier benötigten Dateien unter project.xml und standalone-job.xml.

Navigieren Sie dazu in Talend Studio zu “Project Properties“ -> “Build“ -> “Project“ / “Standalone Job“.

Sie müssen hierzu nur die vorhandenen Dateien durch die Dateien ersetzen, die Sie oben schon kopiert hatten. Es sind keine Änderungen erforderlich.

Zur Erläuterung: Der eigentlich wichtige Vorgang besteht hier darin, dass wir mithilfe des Maven-Plug-ins fabric8 ein neues Profil namens “docker” hinzufügen. Beim Erstellen unserer Jobs mit diesem Maven-Profil wird erst openjdk:8-jre-slim als Basis-Image verwendet und anschließend werden die JAR-Dateien unserer Jobs diesem Image hinzugefügt, zusammen mit einem kurzen Skript, das die Ausführung des Jobs beschreibt. Denken Sie auch daran, dass Talend weder OpenJDK noch Alpine Linux unterstützt. Nur zu Testzwecken können Sie das Image openjdk:8-jre-slim behalten; für die Produktion aber müssen Sie Ihr eigenes Java-Oracle-Basis-Image erstellen. Weitere Informationen finden Sie in unserer Dokumentation zu unterstützten Plattformen.

3) Richten Sie Jenkins ein

Auch hier gilt: Wenn Sie mit Talend Studio ab Version 7.1 arbeiten, verwenden Sie statt der unten angegebenen Datei diese Pipeline-Skriptdatei. Sie enthält die Änderungen und Verbesserungen auf dem Stand von Talend 7.1. In der Skriptdatei sind der Docker-Image-Build und die Veröffentlichung in einer Docker-Registry in einem einzigen Maven-Befehl zusammengefasst.

Im dritten Schritt wird der Jenkins-Server eingerichtet. In diesem Blogpost wird die Erstkonfiguration des Jenkins-Servers nicht beschrieben; deshalb empfehlen wir, falls Sie keine Erfahrung mit Jenkins haben, sich den Getting-Started-Leitfaden für die Jenkins-Pipeline (in englischer Sprache) durchzulesen. Nach Abschluss der Erstkonfiguraton bauen wir mit den Plug-ins von Maven, Git, Docker, Pipeline und Blue Ocean unsere CI/CD-Pipeline auf.

Unsere Datei mit den Maven-Einstellungen wird in Jenkins abgelegt. Dazu navigieren wir in den Einstellungen von Jenkins (Befehl “Manage Jenkins“) zu “Managed Files” und erstellen eine Datei mit der ID “maven-file”. Kopieren Sie diese Datei in die neu erstellte Datei wie im Screenshot unten abgebildet. Achten Sie darauf, dass der CommandLine-Pfad an die Einstellungen Ihrer Umgebung angepasst ist und dass Sie Ihre eigenen Nexus-Anmeldeinformationen und die Nexus-URL angeben.

Jetzt müssen Sie noch, bevor Sie die Pipeline im Einzelnen definieren, einige Anmeldeinformationen konfigurieren. Hierzu gehen Sie unter “Manage Jenkins“ zu “Configure credentials“ auf und öffnen dort auf der linken Seite den Eintrag “Credentials“ – siehe folgenden Screenshot:

Erstellen Sie vier Sätze mit Anmeldedaten für GitHub, Docker Hub, AWS und Azure. Wenn Sie nur AWS nutzen wollen, brauchen Sie keine Azure-Anmeldedaten anzugeben, und umgekehrt. Wichtig: Geben Sie bei den AWS-Anmeldeinformationen Ihren ACCESS KEY als Benutzernamen und den SECRET ACCESS KEY als Passwort an.

Schließlich müssen wir vor der Definition der Pipeline noch zwei CLI-Docker-Images auf der Jenkins-Maschine zur Verfügung stellen. Der Grund ist, dass Jenkins in den Befehlszeilen-Schnittstellen (CLIs) von AWS und Azure Docker-Images verwendet, um dort CLI-Befehle für die verschiedenen Dienste auszuführen. Auf diese Weise lassen sich die beiden CLIs ohne großen Aufwand einbeziehen, d. h. ohne sie auf dem Computer installieren zu müssen. Nachstehend die Images, die dabei verwendet werden:

  • vfarcic/aws-cli (docker pull vfarcic/aws-cli:latest; docker tag vfarcic/aws-cli:latest aws-cli)
  • microsoft/azure-cli:latest (docker pull microsoft/azure-cli:latest; docker tag microsoft/azure-cli:latest azure-cli)

Sie können natürlich auch, ganz nach Bedarf, andere Images verwenden.

Diese Docker-Images müssen mit einem pull-Befehl auf den Jenkins-Computer geladen werden. Dadurch können wir, wie Sie noch sehen werden, im Docker-Plug-in von Jenkins die Funktion “withDockerContainer(‘image’)” einsetzen, um die CLI-Befehle auszuführen. Weitere Informationen über die Ausführung von Build-Schritten in einem Docker-Container finden Sie in der Docker-Dokumentation hier.

Nun sind alle Voraussetzungen erfüllt und wir können auf der Hauptseite einen “New item“ erstellen und dafür die “Pipeline“ auswählen.

Nach der Erstellung wird die Pipeline konfiguriert und dabei auch das Skript der Pipeline definiert (in der Skriptsprache Groovy).

Das Skript finden Sie hier.

Lassen Sie uns einen Blick auf die wichtigsten Schritte in diesem Skript werfen.

Am Anfang der Datei können Sie Ihre eigenen Einstellungen mithilfe von Umgebungsvariablen angeben. Sie können die Schritte hier anhand eines Beispiels nachvollziehen, bei dem ein Projekt namens “TALEND_JOB_PIPELINE” und ein Job “test” bearbeitet werden. Der git-Name des Projekts sollte mit dem Namen in Ihrem GitHub-Repository identisch sein. Deshalb ist er hier in Großbuchstaben angegeben. Beachten Sie auch, dass wir in diesem Skript den Job-Namen als Namen des Docker-Images verwenden und der Job-Name aus diesem Grund keine Unterstriche enthalten darf. Wenn Sie einen Unterstrich verwenden wollen, müssen Sie für das Docker-Image einen alternativen Namen ohne Unterstrich definieren. Sie können den Docker-Image-Namen überschreiben; hierzu dient die Option -Dtalend.docker.name=NAME im Maven-Befehl. Folgende Umgebungsvariablen müssen gesetzt werden:

env.PROJECT_GIT_NAME = 'TALEND_JOB_PIPELINE'
env.PROJECT_NAME = env.PROJECT_GIT_NAME.toLowerCase()
env.JOB = 'test'
env.VERSION = '0.1'
env.GIT_URL = 'https://github.com/tgourdel/talend-pipeline-job.git'
env.TYPE = "" // if big data = _mr
env.DOCKERHUB_USER = "talendinc"

Jeder Schritt in dieser Datei ist als eine “stage“ definiert (siehe jeweils die erste, ausgerückte Zeile eines Abschnitts). In den ersten beiden “stages“ wird mithilfe des Git-Plug-ins die aktuelle Version des Jobs per pull-Befehl eingefügt.

Hieran schließt sich der Build des Jobs selbst an. Wie Sie sehen, verwenden wir das Maven-Plug-in. Die Einstellungen befinden sich in einer Jenkins-Konfigurationsdatei – der Datei, die wir in einem früheren Schritt der Jenkins-Konfiguration mit der ID der maven-file hinzugefügt haben.

In den Abschnitten (“stages“) “Build, Test and Publish to Nexus” sowie “Package Jobs as Container” ist jeweils die folgende Zeile zu ändern:

-Dproduct.path=/cmdline -DgenerationType=local -DaltDeploymentRepository=snapshots::default::http://nexus:8081/repository/snapshots/ -Xms1024m -Xmx3096m

Sie geben hier Ihren eigenen Pfad (relativ zum Jenkins-Server) zum CommandLine-Verzeichnis sowie Ihre Nexus-URL an:

Nach dem Build des Jobs in einem Docker-Image werden wir das Image über einen push-Befehl in die Docker-Hub-Registry laden. Für diesen und den darauffolgenden Schritt werden wir CLIs als Schnittstellen zu unterschiedlichen Fremdanbietern verwenden. Weil der Docker-Daemon in der Regel auf dem Jenkins-Computer schon ausgeführt wird, können wir direkt auf die Docker-CLI zugreifen. Wir rufen den Docker-Hub-Benutzernamen und das zugehörige Passwort mit der Funktion withCredentials() ab:

stage ('Push to a Registry') {
            withCredentials([usernamePassword(credentialsId: 'dockerhub', passwordVariable: 'dockerhubPassword', usernameVariable: 'dockerhubUser')]) {
               sh 'docker tag $PROJECT_NAME/$JOB:$VERSION $DOCKERHUB_USER/$JOB:$VERSION'
               sh "docker login -u ${env.dockerhubUser} -p ${env.dockerhubPassword}"
               sh "docker push $DOCKERHUB_USER/$JOB:$VERSION"
           }
}

Der Abschnitt (“stage“) “Deployment environment” zeigt dann lediglich die Interaktion mit dem Benutzer bei Ausführung der Pipeline. Der Benutzer wird gefragt, ob der Container in AWS Fargate oder Azure ACI implementiert werden soll. Sie können diesen Schritt löschen, wenn Sie bis zur Bereitstellung einen kontinuierlichen Build durchführen möchten. Der Schritt dient hier nur zu Demonstrationszwecken.

Die nächsten beiden Abschnitte zeigen die Bereitstellung selbst, in AWS Fargate bzw. Azure ACI. In jedem dieser Abschnitte müssen Sie jeweils Ihre eigenen Einstellungen vornehmen. Beispielsweise modifizieren Sie im Abschnitt über die Bereitstellung in AWS Fargate folgende Zeile:

aws ecs run-task --cluster TalendDeployedPipeline --task-definition TalendContainerizedJob --network-configuration awsvpcConfiguration={subnets=[subnet-6b30d745],securityGroups=[],assignPublicIp=ENABLED} --launch-type FARGATE

Sie ändern dabei den Namen des Fargate-Clusters und Ihre Aufgaben-Definition jeweils in die eigenen Einstellungen. Zu Ihrer Information: Beide müssen Sie in Ihrer AWS-Konsole erstellen. Lesen Sie als Anleitung dazu diese Dokumentation. Zum Entstehungszeitpunkt dieses Blogbeitrags war AWS Fargate ausschließlich in der Region North Virginia verfügbar (weitere Regionen geplant). Der hier bei der Aufgabendefinition definierte Container ist derselbe, der in Ihrem Docker-Hub-Konto erzeugt werden wird und der als Image-Namen den Namen Ihres Jobs erhält. Dieser Name lautet beispielsweise in der Standardkonfiguration unseres Pipeline-Skripts talendinc/test:0.1.

Entsprechendes gilt für Azure ACI: Geben Sie hierfür Ihre eigene Ressourcengruppe und Container-Instanz an.

4) Konfigurieren Sie die Befehlszeile

Um es genau zu sagen: Ihr Job wird von Maven mit CommandLine erstellt. CommandLine kann in zwei Modi verwendet werden: im Skript- und im Servermodus. Geben Sie zuerst den Arbeitsbereich für CommandLine an (in Ihrem Fall der Jenkins-Arbeitsbereich). Ändern Sie die Datei command-line.sh wie unten gezeigt mit dem folgenden Pfad, der auf den Jenkins-Arbeitsbereich verweist (wobei der genaue Pfad von dem im vorherigen Schritt gewählten Pipeline-Namen abhängt).

./Talend-Studio-linux-gtk-x86_64 -nosplash -application org.talend.commandline.CommandLine -consoleLog -data $WORKSPACE startServer -p 8002

Die Variable $WORKSPACE wird von Ihrer Jenkins-Instanz angegeben und durch den Jenkins-Arbeitsbereich Ihrer Pipeline ersetzt. Dank dieser von Jenkins zur Verfügung gestellten Umgebungsvariablen können Sie unterschiedliche Pipelines in unterschiedlichen Jenkins-Arbeitsbereichen ausführen, wobei CommandLine seinen eigenen Arbeitsbereich jeweils entsprechend anpasst.

Wie an den Maven-Optionen im Groovy-Skript zu erkennen, wird der Parameter -Dgeneration.type=local angegeben. Er besagt, dass CommandLine gestartet wird, um den Build zu erstellen, und anschließend beendet wird. Diese Option ermöglicht es uns, CommandLine beliebig oft auszuführen, und dabei über die Variable $WORKSPACE je nach ausgeführter Pipeline den Arbeitsbereich zu ändern.

Zuletzt wird die Datei /configuration/maven_user_settings.xml geändert. Hierzu kopieren Sie diese Datei und fügen sie ein, allerdings mit Ihrer eigenen Nexus-URL und Ihren eigenen Anmeldeinformationen.

5) Führen Sie die Pipeline aus

Nachdem alle notwendigen Konfigurationsschritte durchgeführt sind, führen Sie die Pipeline aus. Hierzu rufen Sie die Ansicht “Open Blue Ocean“ auf und klicken auf die Schaltfläche “run.” Jetzt wird die Erstellung der Pipeline angestoßen und Sie können die Abarbeitung der Einzelschritte verfolgen:

Screenshot der Jenkins-Pipeline zur Erstellung von Talend-Jobs innerhalb von Docker-Containern

Jenkins-Pipeline zur Erstellung von Talend-Jobs in Docker-Containern

In der Beispiel-Pipeline dieses Blogposts werden Sie gefragt, ob Sie den Container bereitstellen möchten. Sie können hier entweder AWS Fargate oder Azure ACI auswählen. Wir gehen von Fargate als Beispiel aus.

Nachdem Ihr Fargate-Cluster zum Bereitstellungs-Schritt gewechselt hat, sollte im Cluster nur noch eine Aufgabe ausstehen:

Führen Sie diese Aufgabe aus und rufen Sie anschließend das Protokoll der Job-Ausführung auf:

Den Integrations-Job von Talend können Sie nun, da er sich in einem Docker-Container befindet, an einer beliebigen Stelle ausführen, z. B. in:

  • AWS Fargate
  • Azure ACI
  • Google Container Engine
  • Kubernetes oder OpenShift
  • und so weiter …

Dank der CI/CD-Funktionen von Talend können Sie den gesamten Prozess vom Build bis zur Ausführung des Jobs automatisieren.

Wenn Sie von keiner bestimmten Cloud abhängig sein wollen und sich die Portabilität der Container zunutze machen möchten, zeigt Ihnen dieses Beispiel, wie Sie mit dem CI/CD-Tool (in diesem Fall Jenkins) den Build automatisieren und ihn anschließend unter verschiedenen Cloud-Containerdiensten ausführen können. Es handelt sich hier nur um ein Beispiel von vielen. Bedenken Sie aber, dass die Fähigkeit, Jobs als Container zu erstellen, Ihnen eine völlig neue Welt für Ihre Integrations-Jobs eröffnet. Je nach Einsatzbereich Ihrer Lösung kann es Ihnen nun passieren, dass Sie dank der neuen serverlosen Dienste (wie Fargate oder Azure ACI) deutlich weniger Geld ausgeben. Genauso könnte es sein, dass Sie jetzt weniger Zeit für die Konfiguration der Infrastruktur aufwenden müssen und sich stärker auf die Entwicklung von Jobs konzentrieren können.

Wenn Sie mehr darüber erfahren möchten, wie Sie von Containern und serverloser Technologie profitieren würden, kommen Sie zu uns auf die Talend Connect 2018 in London und Paris. Es wird dort spezielle Break-out-Sessions zu serverlosen Lösungen geben, mit denen Sie, ausgehend von diesen Demos, gleich loslegen können. Wir freuen uns auf Ihren Besuch!

An der Diskussion teilnehmen

0 Comments

Leave a Reply