Tekton Cloud-Native CI/CD: Ein pragmatisches Intro

Keine Kommentare

In diesem Artikel möchte ich einen Überblick über Tekton geben mit dem Ziel, die Grundlagen zu erklären und einen schnellen Einstieg zu ermöglichen.

Tekton möchte laut eigener Homepage der Standard für CI / CD werden. Zum einen bietet es ein Framework, um Cloud-native CI/CD-Systeme in Kubernetes zu bauen und darüber hinaus ein standardisiertes Tooling für diese Systeme. So hat es schon Einzug in Jenkins X gehalten und ist die Basis für RedHat OpenShift Pipelines.

Entwickler, die ein CI-System nutzen wollen, profitieren von der breiten Unterstützung, da vorhandene Pipelines und Pipelineschritte ohne Aufwand zwischen den Tekton CI-Implementierungen ausgetauscht werden können.

Das Tekton-Projekt nutzt Kubernetes als Plattform und stellt im Kern die Building Blocks einer CI Pipeline in Form von CRDs dar. Eine Custom Resource Definition, kurz CRD, ist ein selbst erstelltes Kubernetes-Objekt, das genutzt werden kann, um eigene Objekte innerhalb der Kubernetes API sichtbar und nutzbar zu machen. So finden sich in Tekton Objekte wie z. B. eine Pipeline, die ebendiese abbildet, und durch Tasks, welche die einzelnen Prozessschritte ausführen, ausgestaltet werden können.

Die gesamte Konfiguration findet dann wie von Kubernetes gewohnt über Manifeste statt. Das vorhandene Kubernetes Know-how kommt hier voll zum Zuge, denn neben der Konfiguration kann auch eine Introspektion der Prozesse über diesen Weg stattfinden.

Als zentrale Anlaufstelle für durch die Community gepflegte Tasks und Pipelines wird der Tekton Hub angeboten. Dort zu finden sind schon viele Bausteine, um die üblichsten Schritte abzudecken. Zusätzlich zu dem öffentlichen Hub ist es sehr einfach möglich, innerhalb der eigenen Organisation einmal spezifische Lösungen zu implementieren und zuverlässig zu verteilen.

Neben den Manifesten liefert Tekton natürlich auch die Kubernetes-Operatoren im Tekton Pipelines Repository, welche die konfigurierten Arbeitsschritte ausführen. Wie bei modernen CI-Systemen üblich werden die Build-Schritte innerhalb von Containern ausgeführt.

Installation

Die Installation erfolgt entweder durch Apply der Kubernetes-Manifeste der Release-Seite oder durch den Tekton Operator.

Der Tekton Operator ist aktuell noch in einer frühen Entwicklungsphase und bietet aktuell die reine Installation. Hinweise zur Konfiguration der Installation sind auf den Hilfeseiten zu finden.

Die Installation über die Kubernetes-Manifeste ist im Getting Started Guide verständlich beschrieben.

Um schnell eine nutzbare Installation zu haben, empfehle ich die Installation der Pipeline- und der Dashboard-Komponente, die einen visuellen Einblick in die laufende Tekton-Installation bietet. Das Dashboard ist über einen Browser von außen zu erreichen.

Ready-to-run-Projekt

Im Github-Projekt Tekton-Demo ist eine komplette Installation zu finden, die mit K3d direkt auf dem lokal System läuft. Die Installation ist sowohl im README zu finden als auch immer aktuell in der GitHub Action.

Nachdem die Installation erfolgreich durchgelaufen ist, ist das Cluster eine laufende Tekton-Installation mit Tasks und Pipelines, welche im Namespace tekton-pipelines installiert sind. Da man sehr leicht im falschen Namespace schaut, möchte ich nur kurz kubectx und kubens empfehlen, denn kubens tekton-pipelines setzt den default Namespace korrekt.

Das Dashboard ist über einen Port-Forward erreichbar und ein Eventlistener ist über einen Ingress nutzbar. Es kann auch schon auf Events reagieren, doch dazu kommen wir in einem weiteren Blogartikel.

Eine beispielhafte CI Pipeline

Nach der Installation können wir auch schon die Hauptkomponenten kennenlernen und mit diesen ein „Hello, World!“-Beispiel aufbauen.

Ein Task besteht aus einer Serie von Steps, die der Reihenfolge nach ausgeführt werden. Ein Step ist ein in sich abgeschlossenes Kommando, das im folgenden Beispiel Names hello, der Aufruf von echo "Hello World!" ist. Dies wird in einem Bash Container gestartet und ausgeführt, was natürlich auch nach Gusto geändert werden kann.

Im realen Einssatz finden sich an dieser Stelle Kommandos, die einen Checkout vornehmen, Images bauen und vieles mehr.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: hello
      image: bash:latest
      command:
        - echo
      args:
        - "Hello, world!"

Ebenfalls ist ein goodbye Task angelegt, der sich durch ein echo Kommando auf der Systemconsole verabschiedet.

In diesem kleinen Beispiel werden wir eine Pipeline erzeugen, welche die beiden Tasks nacheinander aufruft, damit bei Betrachtung der Pipeline-Logs sowohl die Begrüßung als auch die Verabschiedung anzeigt.

Sehr intuitiv – wie ich jedenfalls finde – erstellen wir ein CRD vom Typ Pipeline und definieren dort eine Liste von Tasks, die mit Abhängigkeiten untereinander versehen werden können. In diesem einfachen Beispiel geben wir über runAfteran, dass die Verabschiedung nach der Begrüßung stattfinden soll.

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-goodbye-pipeline
spec:
  tasks:
    - name: hello
      taskRef:
        name: hello
    - name: goodbye
      runAfter:
        - hello
      taskRef:
        name: goodbye

Der oben definierte Task wird über eine taskRefverlinkt, sodass die definierten Tasks darüber verknüpft werden und die Pipeline die zwei Schritte durchläuft.

Interaktion mit Tekton

Wie zu Beginn dargestellt arbeitet Tekton über die Konfiguration und Installation von CRDs. Diese API-Objekte können direkt über kubectl abgerufen und manipuliert werden, worüber eine nachvollziehbare API abgebildet wird. Installierte Pipelines können problemlos abgerufen werden:

# kubectl get pipelines.tekton.dev --all-namespaces -o wide
NAMESPACE          NAME                     AGE
8
tekton-pipelines   hello-goodbye-pipeline   1s
9

Weiterhin ist es natürlich auch möglich, eine Pipeline zu starten. In dem Repository ist ein PipelineRun zu finden, den ich im Folgenden einmal darstelle:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName:  hello-goodbye-pipeline-
spec:
  pipelineRef:
    name:  hello-goodbye-pipeline

Die Konfiguration stellt ein Präfix für die erstellten Runs über das generateName-Attribut zur Verfügung. Ebenfalls wird eine Referenz zu der zu verwendeten Pipeline vergeben, welche wir während der Installation erzeugt und uns im Verlauf dieses Artikels angeschaut haben.

Wie kann eine Pipeline gestartet werden? Jetzt brauchen wir doch noch ein weiteres API-Objekt und zwar den PipelineRun. Dieses Objekt bringt die notwendigen Parameter – in unserem Fall noch keine – in Verbindung mit der auszuführenden Pipeline. Als Nutzer können wir durch Referenz auf den erzeugten Run den Status und auch die Log-Ausgabe abrufen.

Los geht’s:

kubectl create -n tekton-pipelines -f ./hello-goodbye-pipeline-run.yaml

Und wie schon angedeutet rufen wir alle Ausführungen ab:

kubectl get pipelineruns.tekton.dev --all-namespaces -o wide
NAMESPACE          NAME                             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
8
tekton-pipelines   hello-goodbye-pipeline-v5h5l   True        Succeeded   13s         1s

Hier erkennbar sind die vorhandenen Statusfelder dieses Objekts. Für das Blackbox-Testing können wir daher auf den Statuswechsel des PipelineRuns auf Succeeded warten, um den Durchlauf einer Pipeline zu erkennen.

Neben der direkten Interaktion mit kubectl bietet Tekton ein spezialisiertes Command Line Interface (CLI), das direkt über den aktuell genutzten Kubernetes Context mit dem Cluster interagiert. Viele Kubernetes-basierten Tools bringen ein passendes CLI mit, um effizient mit der Plattform zu arbeiten. tkn ist das entsprechende go Binary, was problemlos auf verschiedenen Plattformen lauffähig ist. Eine Installationsanleitung ist über das GitHub Repository zu finden.

Mit diesem CLI ist es dann einfacher möglich z. B. die Tasks und Pipelines abzurufen. Hier ein kurzes Beispiel:


tkn task list --all-namespaces
tkn pipeline list --all-namespaces

Diese beiden Aufrufe zeigen alle vorhandenen Tasks und Pipelines in allen Namespaces an.

Die Inspektion der Logs erfolgt über dieses Kommando:

tkn pr logs $PIPELINE_RUN_NAME

Die Ausgabe aller Tasks wird hier gesammelt, nachvollziehbar ausgegeben und sieht wie folgt aus:

[hello : hello] Hello World!

[goodbye : goodbye] Goodbye World!

Fazit

Wir haben jetzt mit wenig Aufwand die Installation vorgenommen und auch schon die erste Pipeline erstellt. Damit haben wir schon viel erreicht und konnten den ersten Blick hinter die Kulissen wagen.

In den folgenden Artikeln werden wir eine Buildpack-Pipeline erstellen und die Build-Pipeline um einen WebHook-Trigger von außen erweitern. Damit kann Tekton automatisch ein Container Image bauen, wenn ein Push in einem Git-Repository getätigt wurde.

Marco entwickelt Software aus Leidenschaft. Gerne arbeitet er im Team an der Lösung komplexer Probleme.
In der Vergangenheit hat er dabei erfolgreich Legacy-Applikationen modernisiert, um diese auf geänderte Herausforderungen vorzubereiten. Alle Beteiligten auf diesem Weg mitzunehmen und für neue Technologien zu begeistern – das ist für ihn selbstverständlich.

Über 1.000 Abonnenten sind up to date!

Die neuesten Tipps, Tricks, Tools und Technologien.
Jede Woche direkt in deine Inbox.

Kostenfrei anmelden und immer auf dem neuesten Stand bleiben!
(Keine Sorge, du kannst dich jederzeit abmelden.)

Artikel von Marco Paga

Continuous Integration

GitHub Actions test a full Tekton CI installation

Continuous Integration

Tekton Triggers in practice

Weitere Inhalte zu Continuous Integration

Continuous Integration

Tekton Triggers in der Praxis

Continuous Integration

Tekton Buildpack Pipeline: Alles schon da?

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht.