Blog Open Source OCI-Images als Quelle der Wahrheit für die kontinuierliche Lieferung
Aktualisiert am: May 12, 2025
11 Minuten Lesezeit

OCI-Images als Quelle der Wahrheit für die kontinuierliche Lieferung

Die Vorteile der Verwendung von OCI-Images als Teil von GitOps-Workflows und die vielen Funktionen, die GitLab bietet, um die Bereitstellung in Kubernetes zu vereinfachen.

deployment abstract - cover

Ist GitOps immer noch GitOps, wenn du kein Git-Repository als Artefakt für die Bereitstellung verwendest? Git bleibt zwar weiterhin von zentraler Bedeutung für GitOps-Workflows, doch die Speicherung von Infrastrukturdefinitionen als OCI-Artefakte (Open Container Initiative) in Container-Registries hat als Quelle für GitOps-Bereitstellungen an Beliebtheit gewonnen. In diesem Artikel werden wir uns eingehender mit den Ideen hinter diesem Trend befassen und erläutern, wie GitLab-Funktionen diese Verbesserung der GitOps-Workflows unterstützen.

Was ist GitOps?

Das OpenGitOps-Projekt hat vier Prinzipien für den Einsatz von GitOps definiert (Informationen zu OpenGitOps sind nur in englischer Sprache verfügbar):

Ein Beispiel für GitOps ist das Speichern der Kubernetes-Manifeste für einen Microservice in einem GitLab-Projekt. Diese Kubernetes-Ressourcen werden dann kontinuierlich von einem Controller abgeglichen, der auf dem Kubernetes-Cluster ausgeführt wird, auf dem der Microservice bereitgestellt ist. So können Entwickler(innen) die Infrastruktur mit denselben Workflows verwalten wie bei ihrer Arbeit mit regulärem Code, z. B. durch das Erstellen von Merge Requests, um Änderungen vorzunehmen und zu überprüfen, und durch die Versionsverwaltung von Änderungen. GitOps hat auch betriebliche Vorteile, wie z. B. die Verhinderung von Konfigurationsdrift und es hilft Entwickler(inne)n bei der Prüfung, welche Änderungen bei der Bereitstellung zu bestimmten Ergebnissen geführt haben.

Vorteile und Einschränkungen von Git in GitOps-Workflows

Git ist zwar ein wesentlicher Bestandteil von GitOps-Workflows, aber Git-Repositories wurden nicht für die Bereitstellung durch GitOps-Controller entwickelt. Entwickler(innen) können dank Git bei Infrastrukturänderungen zusammenarbeiten und diese Änderungen später überprüfen. Controller müssen jedoch nicht das gesamte Git-Repository herunterladen, um eine erfolgreiche Bereitstellung zu gewährleisten. GitOps-Controller benötigen lediglich die Infrastruktur, die für eine bestimmte Umgebung definiert ist.

Darüber hinaus ist ein wichtiger Bestandteil des Bereitstellungsprozesses das Signieren und Verifizieren von Bereitstellungen, um sicherzustellen, dass Bereitstellungsänderungen an einer Umgebung aus einer vertrauenswürdigen Quelle stammen. Git-Commits können zwar von GitOps-Controllern signiert und verifiziert werden, aber Commits können auch andere Details erfassen, die nicht mit der Bereitstellung selbst zusammenhängen (z. B. Dokumentationsänderungen, Aktualisierungen anderer Umgebungen und Umstrukturierungen des Git-Repositorys), oder nicht genug vom Bereitstellungsbild, da eine Bereitstellung aus mehreren Commits bestehen kann. Auch hier scheint es sich um einen Fall zu handeln, für den diese Git-Funktion nicht entwickelt wurde.

Ein weiterer herausfordernder Aspekt von Git in GitOps-Workflows ist, dass es manchmal zu mehr Automatisierung als erwartet führen kann. Kurz nach der Zusammenführung wird eine Änderung am beobachteten Branch vorgenommen und dann bereitgestellt. Außerhalb von Git gibt es keine Kontrollen im Prozess. Wie kannst du sicherstellen, dass an einem Freitagnachmittag nichts bereitgestellt wird? Was ist, wenn die für die Bereitstellung verantwortlichen Teams nicht berechtigt sind, in bestimmten GitLab-Projekten Änderungen zusammenzuführen? Durch die Verwendung von OCI-Images wird eine Pipeline in den Prozess eingefügt, die alle Funktionen zur Bereitstellungsteuerung umfasst, wie z. B. Approvals oder Bereitstellungsstopps (nur in englischer Sprache verfügbar).

OCI-Images

Die Open Container Initiative hat dazu beigetragen, Standards für Containerformate zu definieren. Während die meisten Entwickler(innen) mit dem Einbinden von Dockerfiles in Container-Images vertraut sind, sind viele möglicherweise nicht so erfahren im Speichern von Kubernetes-Manifesten in einer Container-Registry. Da die Container-Registry von GitLab (nur in englischer Sprache verfügbar) OCI-konform ist, können Benutzer(innen) Kubernetes-Manifeste für eine bestimmte Umgebung in eine Container-Registry übertragen. GitOps-Controller, wie z. B. Flux CD (nur in englischer Sprache verfügbar), können die in diesem OCI-Artefakt gespeicherten Manifeste verwenden, anstatt ein ganzes Git-Repository klonen zu müssen.

In GitOps-Workflows kann ein Git-Repository oft die Infrastrukturdefinitionen für alle Umgebungen enthalten, in denen ein Microservice bereitgestellt wird. Indem die Kubernetes-Manifeste nur für eine bestimmte Umgebung paketiert werden, muss Flux CD nur genau die Dateien herunterladen, die für die Bereitstellung in einer bestimmten Umgebung erforderlich sind.

Sicherheitsvorteile der Verwendung von OCI-Artefakten

Wie bereits erwähnt, bietet das Signieren und Verifizieren der Artefakte, die in einer Umgebung bereitgestellt werden sollen, eine zusätzliche Sicherheitsebene für Softwareprojekte. Nachdem Kubernetes-Manifeste an eine Container-Registry gepusht wurden, kann ein Tool wie Sigstore Cosign verwendet werden, um das OCI-Image mit einem privaten Schlüssel zu signieren, der sicher in einem GitLab-Projekt als CI/CD-Variable (nur in englischer Sprache verfügbar) gespeichert werden kann. Flux CD kann dann einen öffentlichen Schlüssel verwenden, der auf einem Kubernetes-Cluster gespeichert ist, um zu überprüfen, ob eine Bereitstellung von einer vertrauenswürdigen Quelle stammt.

Verwenden von GitLab zum Pushen und Signieren von OCI-Images

GitLab bietet viele Funktionen, die den Prozess des Paketierens, Signierens und der Bereitstellung von OCI-Images vereinfachen. Eine gängige Methode zur Strukturierung von GitLab-Projekten mit GitOps-Workflows besteht darin, separate GitLab-Projekte für den Code der Microservices und ein einziges Infrastruktur-Repository für alle Microservices zu verwenden. Wenn eine Anwendung aus n-Microservices besteht, wären für eine Anwendung n+1-GitLab-Projekte erforderlich.

Das Artefakt, das aus einem Programmierprojekt hervorgeht, ist in der Regel ein Container-Image, das zum Paketieren der Anwendung verwendet wird. Das Infrastruktur- oder Bereitstellungsprojekt enthält die Kubernetes-Manifeste, in denen alle Ressourcen definiert sind, die für die Skalierung und die Bereitstellung des Datenverkehrs für jeden Microservice erforderlich sind. Das Artefakt, das aus diesem Projekt hervorgeht, ist in der Regel ein OCI-Image, das zur Bereitstellung der Anwendung und anderer Manifeste für Kubernetes verwendet wird.

In diesem Setup wird die Trennung von Umgebungen durch die Definition von Kubernetes-Manifesten in separaten Ordnern gehandhabt. Diese Ordner stellen Umgebungen (z. B. Entwicklung, Staging und Produktion) dar, in denen die Anwendung gehostet wird. Wenn Änderungen am Codeprojekt vorgenommen und ein neues Container-Image gepusht wird, müssen zur Bereitstellung dieser Änderungen über die Integration von GitLab mit Flux CD lediglich die Manifeste im Ordner „Environment“ bearbeitet werden, um die neue Image-Referenz aufzunehmen, und ein „Merge Request“ geöffnet werden. Sobald dieser Merge Request überprüft, genehmigt und zusammengeführt wurde, wird der CI/CD-Job des Bereitstellungsprojekts ein neues OCI-Image pushen, das Flux CD aufnimmt und in der neuen Umgebung bereitstellt.

OCI-Images – Flowchart

Das Signieren eines OCI-Image ist so einfach wie das Einfügen von Cosign in den CI/CD-Job deines Projekts. Du kannst einfach einen neuen öffentlichen und privaten Schlüssel mit Cosign generieren, indem du die folgenden Befehle lokal ausführst. Stelle einfach sicher, dass du dich mit der glab-CLI bei deiner GitLab-Instanz anmeldest und die [PROJECT_ID] für den Befehl „cosign“ durch die ID deines Bereitstellungsprojekts ersetzt.

glab auth login
cosign generate-key-pair gitlab://[PROJECT_ID]

Sobald der Befehl „cosign“ erfolgreich ausgeführt wurde, findest du die zu deinem Projekt hinzugefügten Cosign-Schlüssel im Abschnitt „CI/CD-Variablen“ unter den Schlüsselnamen COSIGN_PUBLIC_KEY und COSIGN_PRIVATE_KEY.

Beispiel für einen CI/CD-Job

Ein GitLab-CI/CD-Job zum Pushen eines OCI-Images sieht in etwa so aus:

frontend-deploy:
  rules:
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    changes:
      paths: 
      - manifests/dev/frontend-dev.yaml
  trigger:
    include:
      - component: gitlab.com/components/fluxcd/[email protected]
        inputs:
          version: 0.3.1
          kubernetes_agent_reference: gitlab-da/projects/tanuki-bank/flux-config:dev
          registry_image_url: "oci://$CI_REGISTRY_IMAGE/frontend"
          image_tag: dev
          manifest_path: ./manifests/dev/frontend-dev.yaml
          flux_oci_repo_name: frontend
          flux_oci_namespace_name: frontend-dev
          signing_private_key: "$COSIGN_PRIVATE_KEY" 

Der GitLab-CI/CD-Katalog (nur in englischer Sprache verfügbar) bietet eine von GitLab gepflegte CI/CD-Komponente für die Arbeit mit OCI-Artefakten und Flux CD. Mit dieser Komponente können Entwicklungsteams Kubernetes-Manifeste als OCI-Images an die Container-Registry von GitLab oder eine externe Container-Registry senden, das OCI-Image mit Cosign signieren und das neu gepushte Image sofort über Flux CD abgleichen.

Im obigen Beispiel ist die Flux CD component in einer .gitlab-ci.yml-Datei eines GitLab-Projekts enthalten. Mithilfe der inputs der Komponente können Benutzer(innen) definieren, in welche Registry das Image gepusht werden soll (d. h. registry_image_url und image tag), den Dateipfad zu den Kubernetes-Manifesten, die gepusht werden sollen (d. h. manifest_path), den privaten Cosign-Schlüssel, der zum Signieren von Images verwendet wird (d. h. signing_private_key), sowie den Kubernetes-Namensraum und den Namen des Flux-CD-OCIRepository, der für die Synchronisierung von Aktualisierungen in einer Umgebung benötigt wird (d. h. flux_oci_namespace_name und flux_oci_repo_name).

Mit der kubernetes_agent_reference können GitLab-CI/CD-Jobs das für den Zugriff auf einen Kubernetes-Cluster erforderliche kubeconfig erben, ohne dass in jedem GitLab-Projekt eine kubeconfig-CI/CD-Variable gespeichert werden muss. Durch die Einrichtung des GitLab Agent for Kubernetes (nur in englischer Sprache verfügbar) können die CI/CD-Jobs aller GitLab-Projekte in einer GitLab-Gruppe (nur in englischer Sprache verfügbar) konfiguriert werden, um Berechtigungen für die Bereitstellung im Kubernetes-Cluster zu erben.

Der Agent für den Kubernetes-Kontext wird normalerweise überall dort konfiguriert, wo du den GitLab Agent for Kubernetes in deiner GitLab-Gruppe konfigurierst. Das solltest du in der Regel in dem Projekt zu tun, in dem Flux CD verwaltet wird. Weitere Informationen zur Konfiguration des Agents für den CI/CD-Zugriff findest du in unserer CI/CD-Workflow-Dokumentation (nur in englischer Sprache verfügbar).

Die Variablen $COSIGN_PRIVATE_KEY, $FLUX_OCI_REPO_NAME und $FRONTEND_DEV_NAMESPACE sind Werte, die als CI/CD-Variablen gespeichert werden, um den Zugriff auf diese vertraulichen Daten in CI/CD-Protokollen zu erleichtern und sie zu maskieren. $CI_REGISTRY_IMAGE ist eine Variable, die standardmäßig in GitLab-Jobs verfügbar ist und die Container-Registry des GitLab-Projekts angibt.

Bereitstellen von OCI-Images

Wenn du Flux CD mit deinen GitLab-Projekten (nur in englischer Sprache verfügbar) verwendest, kannst du die Bereitstellung und Signaturprüfung für die Umgebungen deiner Microservices automatisieren. Sobald Flux CD für die Synchronisierung von einem GitLab-Projekt konfiguriert ist, kannst du die folgenden benutzerdefinierten Ressourcendefinitionen von Kubernetes zu deinem Projekt hinzufügen, um dein gepushtes OCI-Image zu synchronisieren.

apiVersion: v1
kind: Namespace
metadata:
  name: frontend-dev
  labels:
    name: frontend-dev
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: cosign-public-key
  namespace: frontend-dev
spec:
  encryptedData:
    cosign.pub: AgAKgLf4VbVzJOmr6++k81LlFayx88AELaUQFNOaXmBF4G+fBfBYeABl0skNvMAa1UrPVNSfMIHgFoYHoO96g576a+epk6V6glOI+++XvYbfsygof3GGxe0nL5Qh2b3ge0fNpyd0kTPSjTj0YUhRhKtMGMRSRw1jrwhNcGxCHK+Byibs52v8Np49KsIkeZKbzLdgYABkrv+k0j7hQM+jR180NpG+2UiRvaXpPuogxkbj61FEqWGrJHk8IVyfl3eh+YhoXxOHGDqko6SUC+bUZPDBlU6yKegO0/8Zq3hwulrSEsEjzRZNK+RFVMOLWWuC6h+WGpYhAMcsZPwjjJ/y29KLNa/YeqkN/cdk488QyEFc6ehCxzhH67HxIn2PDa+KkEOTv2TuycGF+Q00jKIizXF+IwLx/oRb3pTCF0AoAY8D8N3Ey+KfkOjsBON7gGID8GbQiJqX2IgIZxFMk0JRzxbRKOEqn+guLd5Shj7CD1a1Mkk0DxBdbqrGv2XNYUaFPI7xd3rZXUJZlnv+fsmwswsiGWRuXwim45HScWzQnfgLAe7tv3spVEGeaO5apl6d89uN21PBQnfE/zyugB//7ZW9tSp6+CSMyc5HynxI8diafqiwKPgvzLmVWRnkvxJijoXicRr3sCo5RudZPSlnjfd7CKdhwEVvLl7dRR4e/XBMdxCzk1p52Pl+3/kJR+LJii5+iwOpYrpVltSZdzc/3qRd19yMpc9PWpXYi7HxTb24EOQ25i21eDJY1ceplDN6bRtop2quzkjlwVeE2i4cEsX/YG8QBtQbop/3fjiAjKaED3QH3Ul0PECS9ARTScSkcOL3I00Xpp8DyD+xH0/i9wCBRDmH3yKX18C8VrMq02ALSnlP7WCVVjCPzubqKx2LPZRxK9EG0fylwv/vWQzTUUwfbPQZsd4c75bSTsTvxqp/UcFaXA==
  template:
    metadata:
      name: cosign-public-key
      namespace: frontend-dev
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
    name: frontend
    namespace: frontend-dev
spec:
    interval: 1m
    url: oci://registry.gitlab.com/gitlab-da/projects/tanuki-bank/tanuki-bank-delivery/frontend
    ref:
        tag: dev
    verify:
      provider: cosign
      secretRef:
        name: cosign-public-key
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
    name: frontend
    namespace: frontend-dev
spec:
    interval: 1m
    targetNamespace: frontend-dev
    path: "."
    sourceRef:
        kind: OCIRepository
        name: frontend
    prune: true

Mit der Ressource Kustomization können Kubernetes-Manifeste weiter angepasst werden und sie gibt auch an, in welchem Namensraum Ressourcen bereitgestellt werden sollen. Die Ressource OCIRepository für Flux CD ermöglicht es Benutzer(inne)n, die OCI-Image-Repositoryreferenz und das Tag anzugeben, von dem regelmäßig synchronisiert werden soll. Außerdem wirst du die Eigenschaften verify.provider und verify.secretRef bemerken. Anhand dieser Felder kannst du überprüfen, ob das für den Cluster bereitgestellte OCI-Image mit dem entsprechenden privaten Cosign-Schlüssel signiert wurde, der im früheren CI/CD-Job verwendet wurde.

Der öffentliche Schlüssel muss in einem Kubernetes-Geheimnis gespeichert werden, das sich im selben Namensraum wie die Ressource OCIRepository befinden muss. Damit Flux CD dieses Geheimnis verwaltet und es nicht im Klartext gespeichert wird, kannst du SealedSecrets verwenden, um den Wert zu verschlüsseln und ihn cluster-seitig von einem Controller entschlüsseln zu lassen.

Eine einfachere Methode, für die SealedSecrets nicht erforderlich ist, ist die Bereitstellung des Geheimnisses über einen GitLab-CI/CD-Job (nur in englischer Sprache verfügbar) mit der kubectl CLI. Bei der Variante ohne SealedSecret entfernst du einfach das oben enthaltene SealedSecret und führst den Job zur Bereitstellung des öffentlichen Geheimnis-Schlüssels aus, bevor du den Job zum Pushen des neuen OCI-Images ausführst. Dadurch wird sichergestellt, dass das Geheimnis sicher in GitLab gespeichert ist und dass es im Cluster vom OCIRepository abgerufen werden kann. Dieser Ansatz ist etwas einfacher, aber nicht für die Verwaltung von Geheimnissen in der Produktion geeignet.

Die Vorteile von OCI, GitLab und GitOps

Mit OCI-Artefakten (Oracle Cloud Infrastructure) können GitOps-Teams Bereitstellungen noch weiter optimieren. Sie bieten zusätzliche Sicherheitsvorteile und ermöglichen minimale Bereitstellungen. Benutzer(innen) profitieren weiterhin von allen Vorteilen, die Git bietet, insbesondere von einer zuverlässigen Datenquelle für die Infrastruktur und der Zusammenarbeit an Projekten. OCI-Images erweitern den Bereitstellungsansatz von GitOps um einen Paketierungsansatz.

Bei GitLab lernen wir kontinuierlich von unseren Kund(inn)en und der Cloud-nativen Community, um Erfahrungen zu sammeln, die zur Vereinfachung von GitOps-Workflows beitragen. Einige der in diesem Blogbeitrag erwähnten Funktionen kannst du nutzen, indem du dich für eine kostenlose 60-Tage-Testversion von GitLab Ultimate anmeldest. Wir freuen uns auch über Erfahrungsberichte von Benutzer(inne)n dieser Tools. Feedback kannst du im Community-Forum abgeben.

Wir möchten gern von dir hören

Hat dir dieser Blogbeitrag gefallen oder hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab Community-Forum und tausche deine Eindrücke aus. Teile dein Feedback

Bist du bereit?

Sieh dir an, was dein Team mit einer einheitlichen DevSecOps-Plattform erreichen könnte.

Kostenlose Testversion anfordern

Finde heraus, welcher Tarif für dein Team am besten geeignet ist

Erfahre mehr über die Preise

Erfahre mehr darüber, was GitLab für dein Team tun kann

Sprich mit einem Experten/einer Expertin