Im ersten Artikel haben wir die Tekton-Installation gemeistert, erste API-Objekte kennengelernt und dabei eine erste kleine Pipeline erstellt. Hier eine kurze grafische Zusammenfassung als Erinnerung.
Jetzt werden wir eine praktisch nutzbare Pipeline erstellen, die, wie für ein CI-System üblich, bei neuen Commits neue Images erstellt. Die Wiederverwendbarkeit von Tekton-Komponenten, sowohl Tasks als auch ganze Pipelines, ist eine Stärke, die ich gerne in diesem Artikel praktisch darstellen möchte.
Wie bauen wir?
Container Images können wir auf verschiedene Arten erstellen. Docker, die Firma, die Container in die Breite getragen hat, sah es vor, ein Dockerfile
zu schreiben, das durch einen docker build
schrittweise ein Container Image gebaut hat. Ein Dockerfile
zu schreiben ist sehr simpel, jedoch wird es schnell sehr aufwendig, wenn man einen sicheren, stabilen Build und Betrieb gewährleisten möchte.
Ich möchte nur zwei Impulse setzen, die man klären sollte:
- Sollte das CI-System wirklich einen Docker Socket an die Build-Container weitergeben?
- Sollte innerhalb des Docker Images wirklich der Root User genutzt werden?
Für diese Themen gibt es viele Lösungsmöglichkeiten. Im Folgenden werde ich den Buildpack-Ansatz beleuchten.
Cloud-Native Buildpacks sind eine einfache Lösung, um Container Images zu erstellen. Was ist also zu tun? Es reicht ein pack build my-image
, um die Anwendung im aktuellen Verzeichnis als my-image
zu bauen und in einem Image Repository abzulegen. Zugegebenermaßen ist die Lösung sehr einfach zu nutzen, gleichzeitig passiert viel im Hintergrund, um einen optimalen Image Build zu gewährleisten. Themen wie z. B. Caching und Security werden transparent gelöst.
Integration in Tekton
Wir werden eine Pipeline benötigen, die Schritt für Schritt die benötigten Tasks ablaufen lässt. Die Pipeline wird zuerst den Sourcecode aus einem Git-Repository klonen und in einem Verzeichnis ablegen. Der zweite Schritt wird den Sourcecode in diesem Verzeichnis lesen und mit Buildpack Tooling das Image erstellen und in ein Container Registry pushen.
Im ersten Artikel haben wir uns angeschaut, wie wir eine Pipeline erstellen können und Tasks verknüpfen, aber mit Dateien haben wir noch nicht gearbeitet.
Workspaces
Verzeichnisse können in Tekton mithilfe von Workspaces zwischen Tasks geteilt werden. Workspaces können auf diverse Kubernetes-Storage-Typen zurückgreifen; so kann z. B. ein PersistentVolumeClaim, eine Config-Map oder ein emptyDir verwendet werden.
Bei der Definition einer Pipeline legen wir die benötigten Workspaces fest. In unserem Fall definieren wir einen Workspace, um den Sourcecode aus dem Git-Repository für die Laufzeit der Pipeline zu speichern. An dieser Stelle sind nur der Name und die Verknüpfung zu den Tasks bekannt. Tasks können Workspaces erwarten, die dann unter einem bestimmten Namen durch die Pipeline bereitgestellt werden können.
Hier sehen wir eine kurze Pipeline, die den Sourcecode aus einem Git-Repository in einen Workspace mit dem Namen source-workspace klont.
1apiVersion: tekton.dev/v1beta1 2kind: Pipeline 3metadata: 4 name: git-clone-sample-pipeline 5spec: 6 params: 7 - name: git-clone-url 8 type: string 9 description: HTTP URL of the git repository to clone 10 - name: git-revision 11 type: string 12 default: "main" 13 description: Git revision (branch, tag, commit-id) to clone 14 workspaces: 15 - name: source-workspace # Directory where application source is located. (REQUIRED) 16 tasks: 17 - name: fetch-repository # This task fetches a repository using the `git-clone` task you installed 18 taskRef: 19 name: git-clone 20 workspaces: 21 - name: output 22 workspace: source-workspace 23 params: 24 - name: url 25 value: $(params.git-clone-url) 26 - name: revision 27 value: $(params.git-revision) 28 - name: subdirectory 29 value: "" 30 - name: deleteExisting 31 value: "true"
PipelineRun
Wie schon im ersten Artikel beschrieben, erzeugen wir einen PipelineRun
zum Start der Pipeline und zur Übergabe von Parametern und Workspaces.
Im folgenden Beispiel starten wir die oben definierte Pipeline mit den gewünschten Werten. Das Git-Repository wird auf einen festen Wert gesetzt und der source-workspace
wird mit einem vorhandenen PersistentVolumeClaim
verknüpft.
1apiVersion: tekton.dev/v1beta1 2kind: PipelineRun 3metadata: 4 generateName: git-clone-sample-pipeline- 5spec: 6 serviceAccountName: tekton-service-account 7 pipelineRef: 8 name: git-clone-sample-pipeline 9 workspaces: 10 - name: source-workspace 11 subPath: source 12 persistentVolumeClaim: 13 claimName: source-workspace-pvc 14 params: 15 - name: git-clone-url 16 value: https://github.com/marcopaga/feeding-the-ci-process-single-project.git
Jetzt startet die Pipeline, klont das Repository und terminiert erfolgreich.
Credentials für Clone und Push bereitstellen
Für Open-Source-Projekte mit einem öffentlich verfügbaren Repository sind wir damit am Ziel. Bei dem internen Einsatz mit Credentials auf einem Repository müssen wir diese noch dem Git-Prozess zur Verfügung stellen.
Bei der Recherche zu diesem Aspekt habe ich verschiedene Informationen gefunden. Für mich hat diese Variante, die dort beschrieben wird, funktioniert. Im Kern wird ein Secret mit den Anmeldeinformationen erstellt und mit Annotations erweitert, die beschreiben, für welchen Einsatz und welchen Server dies zu verwenden ist. Der Key tekton.dev/git-0
gibt an, dass dies für github.com-Repositorys zu verwenden ist.
1apiVersion: v1 2kind: Secret 3metadata: 4 name: github-clone-secret 5 annotations: 6 tekton.dev/git-0: https://github.com 7type: kubernetes.io/basic-auth 8stringData: 9 username: git-clone-user-name 10 password: git-clone-password
Das alleine reicht noch nicht, denn die zu benutzenden Secrets müssen dem ServiceAccount des PipelineRuns hinzugefügt werden. Wie im folgenden Beispiel zu sehen, wird das Secret einfach mit aufgeführt.
Für den Container Image Push ist ebenfalls ein Secret notwenig. Hierbei reicht es, ein normales Docker Registry Secret anzulegen, wie hier in den Tekton Docs beschrieben. Wichtig auch hierbei ist, dies dem ServiceAccount hinzuzufügen.
Im Folgenden ist ein ServiceAccount mit den beiden definierten Secrets zu sehen.
1apiVersion: v1 2kind: ServiceAccount 3metadata: 4 name: buildpacks-service-account 5secrets: 6 - name: docker-registry-secret 7 - name: gitlab-clone-secret
Vorhandene Pipeline und Tasks nutzen
Jetzt haben schon einmal eine Pipeline angelegt, mit der wir den Code klonen können. Wir können jetzt mit unserem Wissen weitermachen und schrittweise die nächsten Schritte hinzufügen.
Auf dem Tekton Hub finden wir Tasks für den Build . So weit, so gut! Die Tasks sind gut dokumentiert und eigentlich können wir diese direkt einbauen.
Man kann auch nach Pipelines suchen . Wenn wir das machen, finden wir eine komplette Pipeline, die schon fertig und getestet ist.
Die Buildpacks-Pipeline ist wunderbar dokumentiert. Wir finden Informationen zum Hintergrund, den benötigten Abhängigkeiten und der Installation.
Wie im ersten Artikel beschrieben, werden diese installiert und direkt benutzt. Der vorhandene PipelineRun
wird der Dokumentation folgend angepasst und schon ist alles fertig.
Fazit
Diese Wiederverwendbarkeit erlaubt eine Zusammenarbeit und einen Austausch von CI-Komponenten innerhalb der eigenen Organisation und sogar im Open-Source-Umfeld.
Wir konnten durch Verwendung und Konfiguration von Community-Komponenten mit sehr wenig Aufwand eine funktionierende Pipeline erstellen. Damit haben wir jetzt einen Startpunkt, um die eigenen Erweiterungen vorzunehmen und auch dabei von der Community des Tekton Hubs zu profitieren und hoffentlich sogar eigene Contributions zurückzugeben.
Im nächsten Artikel werden wir mit Tekton Triggers auf dieser Basis weitermachen und beim Push in ein Repository einen Build dieser Pipeline starten.
Weitere Beiträge
von Marco Paga
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
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.
Blog-Autor*in
Marco Paga
Senior Solution Architect
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.