5.1. Intro

5.1.1. Was ist DevOps?

DevOps ist ein Ansatz in der Softwareentwicklung, der darauf abzielt, die Zusammenarbeit zwischen Entwicklungs- (Development) und Betriebsteams (Operations) zu verbessern Ziel ist es, den Softwareentwicklungszyklus zu beschleunigen, die Qualität der Software zu erhöhen und die Effizienz der Prozesse zu steigern Dies wird erreicht durch Automatisierung, kontinuierliche Integration und kontinuierliche Bereitstellung (CI/CD), sowie durch die Nutzung gemeinsamer Tools und Prozesse, um eine reibungslose und effiziente Zusammenarbeit zu fördern DevOps fördert eine Kultur der gemeinsamen Verantwortung, Transparenz und kontinuierlichen Verbesserung.

Man könnte DevOps auch als Optimierung des Softwareentwicklungsprozesses bezeichnen. Für diese Optimierung werden einige Tools und Konzepte eingesetzt. Beispielsweise Issuetracking mit Jira oder Ähnlichem oder DevSecOps, ein Prinzip im Bezug auf gemeine Verantwortung zur Softwaresicherheit sind DevOps Prinzipien. Wir wollen uns hauptsächlich auf die Implementierung einer Pipeline in Gitlab CI fokussieren, die das Deployment des Berichts automatisiert. Um weitere DevOps Prinzipien soll es in diesem Projekt im Detail allerdings nicht gehen, da dies den Rahmen sprengen würde.

5.1.2. Was ist CI/CD?

Früher wurden Anwendungen nur in sehr großen Abständen released. Dies führte dazu, dass eine große Menge an Änderungen auf einmal ins Projekt-Repository des Produkts integriert werden mussten. Sehr häufig kam es dabei zu Problemen. Im schlimmsten Fall musste der Rollout komplett abgebrochen werden und ein funktionierender Zustand wiederhergestellt werden.

Dies versachte hohen Aufwand und damit Kosten. Daher ging man dazu über Code Änderungen möglichst schnell, kontinuierlich, zu integrieren. Idealerweise wird bei Continuous Integration jede Änderung automatisch getestet, um sicherzustellen, dass keine neuen Fehler eingeführt wurden. Dies ermöglicht es Entwicklern, Integrationsprobleme frühzeitig zu erkennen und zu beheben.

Continuous Deployment (CD) bedeutet, dass nach erfolgreichem Abschluss aller Tests die Änderungen automatisch in die Produktionsumgebung überführt werden, sodass neue Features, Fehlerbehebungen und Verbesserungen schnell und zuverlässig für die Endnutzer bereitgestellt werden können Dies erfordert ein hohes Maß an Automatisierung und Vertrauen in die Test- und Deployment-Prozesse. Im Gegensatz dazu geht Continuous Delivery einen Schritt weiter, indem die Änderungen nach den Tests in eine staging-Umgebung überführt werden und der letzte Schritt zur Produktionsfreigabe eine manuelle Freigabe durch das Entwicklungsteam erfordert Dadurch wird sichergestellt, dass der Code jederzeit releasefähig ist und auf Knopfdruck in die Produktion gehen kann Zusammen verbessern CI und CD die Softwarequalität, reduzieren das Risiko von Fehlern im Produktionscode und ermöglichen eine schnellere Bereitstellung neuer Funktionen und Updates.

Dieser Zyklus wird in folgender Grafik nochmals bildlich dargestellt:

../_images/DevOps.png

5.1.3. GitLab CI Piplines

Die Integration ins Produkt geschieht über sogenannte Pipelines. Sie sind das zentrale Feature um CI/CD (in Gitlab) umzusetzen. Mit GitLab CI Pipelines kannst man automatisierte Workflows erstellen, die Code-Builds, Tests und Deployments umfassen.

Eine Pipeline besteht aus einer bis mehreren Stufen (Stages). Die Reihefolge der Ausführung wird hierzu ebenfalls definiert. Jede Stufe kann einen oder mehrere Jobs enthalten. Auch eine parallele Ausführung von Jobs ist möglich.

Stages unterteilt man standmäßig in build, test und deploy. Jobs sind einzelne Aufgaben, die in einer Stage ausgeführt werden. Dies kann zum Beispiel ein Skript sein, dass ausgeführt wird oder ein direkt ein Kommando aufrufen. Außerdem ist es möglich Stages nur bei bestimmten Branches auszuführen oder Ausführung erst nach einem definierten Timer zu starten.

Ein einfaches Beispiel einer .gitlab-ci.yml sieht folgendermaßen aus:

stages:
  - build
  - test
  - deploy

build_job:
  stage: build
  script:
    - echo "Building the project"
    - ./build_script.sh
    - echo another command

test_job:
  stage: test
  script:
    - echo "Running tests"
    - ./test_script.sh
    - ls -la

deploy_job:
  stage: deploy
  script:
    - echo "Deploying the project"
    - ./deploy_script.sh
  only:
    - master

5.1.4. Gitlab Runner

Ein GitLab Runner ist ein spezieller Agent, der von GitLab verwendet wird, um CI/CD-Pipelines auszuführen. Er ist ein essenzieller Bestandteil des GitLab-Systems, das Entwicklern ermöglicht, ihre Software-Entwicklungsprojekte effizient und automatisiert zu bauen, zu testen und zu deployen. Der GitLab Runner ist verantwortlich für die Ausführung der Jobs, die in den CI/CD-Pipelines definiert sind. Der Runner kommuniziert mit dem GitLab-Server, um Aufträge abzuholen und deren Status zurückzumelden, und arbeitet eng mit dem GitLab CI/CD-System zusammen, das in den Projekt-Repositories konfiguriert ist.

GitLab Runner kann auf verschiedenen Plattformen und Umgebungen betrieben werden, einschließlich Linux, Windows, macOS und auch in Container-Umgebungen wie Docker. Dadurch ist er sehr flexibel und kann an unterschiedliche Anforderungen angepasst werden. Man kann mehrere GitLab Runner installieren, um die Last zu verteilen und die Verfügbarkeit zu erhöhen, was besonders in großen Projekten mit vielen gleichzeitigen Builds und Tests nützlich ist.

Runner können in zwei Hauptmodi konfiguriert werden: Shared Runners und Specific Runners. Shared Runners werden von allen Projekten innerhalb einer GitLab-Instanz gemeinsam genutzt und sind nützlich, um Ressourcen effizient zu nutzen und die Administration zu vereinfachen. Specific Runners sind nur für bestimmte Projekte oder Gruppen von Projekten vorgesehen und ermöglichen eine detailliertere Kontrolle über die Ausführungsumgebung und Ressourcen.

GitLab Runner unterstützt verschiedene Executor-Typen, die bestimmen, wie und wo die Jobs ausgeführt werden. Einige der häufig verwendeten Executor sind der Shell Executor, der Jobs direkt in der Shell des Host-Betriebssystems ausführt, der Docker Executor, der Jobs in Docker-Containern ausführt und somit eine isolierte und konsistente Umgebung sicherstellt, und der Kubernetes Executor, der Jobs in einem Kubernetes-Cluster ausführt, was für hoch skalierbare und containerisierte Anwendungen nützlich ist.