Alles begann damit, dass der Teamleiter eines unserer Entwicklerteams mich bat, ihre neue Anwendung, die gerade containerisiert worden war, zu testen und extern bereitzustellen. Ich habe es gemacht. Ungefähr zwanzig Minuten später kam die Bitte, die Anwendung zu aktualisieren, da eine sehr nützliche Funktion hinzugefügt wurde. Ich habe aktualisiert. Nach ein paar Stunden… naja, Sie können sich denken, was dann passierte…
Ich gebe zu, ich bin ziemlich faul (habe ich das nicht schon mal gesagt? Nein?), und da die Teamleiter Zugriff auf Jenkins haben, wo wir unsere gesamte CI/CD haben, dachte ich: Lass ihn doch selbst deployen, so viel er will! Ich erinnerte mich an einen Witz: Gib einem Menschen einen Fisch, und er wird einen Tag lang satt sein; nenne den Menschen Satt, und er wird sein Leben lang satt sein. Und so ging ich daran, einen Job zu erstellen, der in der Lage wäre, einen Kubernetes-Container mit jeder erfolgreich gebauten Version der Anwendung zu deployen und beliebige Werte an ihn zu übergeben. ENV (Mein Großvater, ein Philologe und ehemals Englischlehrer, würde jetzt mit dem Finger am Kopf drehen und sehr ausdrucksvoll auf mich schauen, wenn er diesen Satz lesen würde).
In meinem Artikel werde ich erläutern, wie ich gelernt habe:
- Aufgaben in Jenkins dynamisch aus der Aufgabe selbst oder von anderen Aufgaben aktualisieren;
- Mit der Cloud-Konsole (Cloud Shell) von einem Knoten mit installiertem Jenkins-Agent verbinden;
- Arbeitslast in Google Kubernetes Engine bereitstellen.
Tatsächlich gebe ich hier ein wenig vor. Es wird vorausgesetzt, dass zumindest ein Teil Ihrer Infrastruktur in der Google Cloud ist, und somit sind Sie ein Nutzer und selbstverständlich haben Sie ein GCP-Konto. Aber darum geht es hier nicht.
Dies ist eine weitere meiner Hilfestellungen. Solche Notizen möchte ich nur aus einem Grund schreiben: Ich hatte eine Aufgabe, wusste anfangs nicht, wie ich sie lösen kann, die Lösung ließ sich nicht sofort googeln, also habe ich sie nach und nach gesucht und letztendlich die Aufgabe gelöst. Damit ich in Zukunft, wenn ich vergesse, wie ich das gemacht habe, nicht alles wieder in Teilen googeln und zusammenführen muss, schreibe ich mir solche Hilfestellungen.
Haftungsausschluss: 1. Die Notiz wurde „für mich“ geschrieben, der Anspruch auf best practice gilt nicht. Ich freue mich über Alternativen „das wäre besser gewesen“ in den Kommentaren.
2. Wenn man den praktischen Teil der Notiz als Salz betrachtet, dann ist auch diese – wie all meine vorherigen Notizen – eine schwach salzige Lösung.
Dynamische Aktualisierung der Job-Einstellungen in Jenkins
Ich antizipiere Ihre Frage: Was hat die dynamische Aktualisierung eines Jobs damit zu tun? Ich habe den Wert des Stringparameters manuell eingegeben und losgelegt!
Hier die Antwort: Ich bin wirklich faul und mag es nicht, wenn sich jemand beschwert: Michi, das Deployment schlägt fehl, alles ist verloren! Dann fängt man an zu schauen, und es gibt einen Schreibfehler im Wert eines Startparameters des Jobs. Deshalb bevorzuge ich es, alles so fehlersicher wie möglich zu gestalten. Wenn es die Möglichkeit gibt, dem Benutzer die direkte Eingabe von Daten zu verwehren und stattdessen eine Liste von Werten zur Auswahl zu geben, organisiere ich die Auswahl.
Der Plan ist folgender: Wir erstellen einen Job in Jenkins, bei dem man vor dem Start aus einer Liste die Version auswählen kann und die Werte für die Parameter angibt, die an den Container übergeben werden sollen. ENV, danach baut er den Container und pusht ihn ins Container-Registry. Von dort aus wird der Container in Kubernetes als workload mit den im Job festgelegten Parametern gestartet.
Den Prozess der Erstellung und Konfiguration eines Jobs in Jenkins betrachten wir hier nicht, das wäre off-topic. Wir gehen davon aus, dass der Job bereit ist. Für die Implementierung einer aktualisierbaren Liste mit Versionen benötigen wir zwei Dinge: eine bereits vorhandene Quellliste mit priori gültigen Versionsnummern und eine Variable vom Typ Choice-Parameter im Job. In unserem Beispiel nennen wir die Variable BUILD_VERSION, auf die wir nicht näher eingehen werden. Bei der Quellliste hingegen sollten wir genauer hinschauen.
Die Optionen sind nicht gerade zahlreich. Mir fallen sofort zwei ein:
- Die Remote Access API nutzen, die Jenkins seinen Nutzern anbietet;
- Den Inhalt eines entfernten Repository-Ordners anfordern (in unserem Fall handelt es sich um JFrog Artifactory, was jedoch nicht entscheidend ist).
Jenkins Remote Access API
Aus der schönen Tradition heraus ziehe ich es vor, lange Erklärungen zu vermeiden.
Ich erlaube mir lediglich eine freie Übersetzung eines Abschnitts des ersten Absatzes :
Jenkins bietet eine API für den remote maschinenlesbaren Zugriff auf seine Funktionen. Der Remote-Zugriff erfolgt im REST-ähnlichen Stil. Das bedeutet, dass es keinen einheitlichen Einstiegspunkt für alle Funktionen gibt, stattdessen wird eine URL wie "/api/", wobei "…" das Objekt bezeichnet, auf das die API-Funktionen angewendet werden.
Mit anderen Worten, wenn der Deployment-Job, über den wir gerade sprechen, unter der Adresse http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build, verfügbar ist, sind die API-Daten für diesen Job unter der Adresse http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/
verfügbar. Wir haben nun die Wahl, in welchem Format wir die Ausgabe erhalten möchten. Lassen Sie uns auf XML konzentrieren, da die API nur in diesem Fall die Filterung ermöglicht.
Versuchen wir einfach so, die Liste aller Ausführungen des Jobs abzurufen. Wir sind nur an dem Namen des Builds (displayName) und seinem Ergebnis (result):
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]Hat es geklappt?
Jetzt filtern wir nur die Ausführungen heraus, die letztendlich mit dem Ergebnis ERFOLG. Wir verwenden das Argument &exclude und übergeben den Pfad zu dem Wert, der ungleich ERFOLGist. Ja, ja. Doppelte Negation bedeutet Bestätigung. Wir schließen alles aus, was uns nicht interessiert:
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!='SUCCESS'] Screenshot der Liste erfolgreicher

Und um sicherzustellen, dass der Filter uns nicht getäuscht hat (Filter lügen niemals!), werden wir die Liste der „fehlgeschlagenen“ ausgeben:
http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result='SUCCESS'] Screenshot der Liste der fehlgeschlagenen

Liste der Versionen aus dem Ordner auf dem entfernten Server
Es gibt auch eine zweite Möglichkeit, die Liste der Versionen zu erhalten. Diese gefällt mir sogar besser als der Zugriff auf die Jenkins-API. Schließlich, wenn die Anwendung erfolgreich gebaut wurde, wurde sie verpackt und im entsprechenden Ordner im Repository abgelegt. Das Repository dient standardmäßig als Speicherort für Arbeitsversionen von Anwendungen. Lassen Sie uns also fragen, welche Versionen archiviert sind. Wir werden den entfernten Ordner mit curl abfragen, grep verwenden und awk anwenden. Wer an einem Einzeiler interessiert ist, kann ihn im Spoiler finden.
Einzeilige Command
Beachten Sie zwei Dinge: Ich übergebe im Header die Anmeldeinformationen für den Zugang, und ich benötige nicht alle Versionen aus dem Ordner, sondern filtere nur die, die im letzten Monat erstellt wurden. Passen Sie den Befehl an Ihre Gegebenheiten und Bedürfnisse an:
curl -H "X-JFrog-Art-Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//g' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+')Konfiguration der Aufgaben und Konfigurationsdatei einer Aufgabe in Jenkins
Wir haben die Quelle der Versionsliste bearbeitet. Lassen Sie uns nun die erhaltene Liste in die Aufgabe einfügen. Für mich war es offensichtlich, einen Schritt in der Aufgabenstellung für den Build des Anwendungsprogramms hinzuzufügen. Ein Schritt, der im Falle eines "Erfolgs" ausgeführt wird.
Öffnen Sie die Einstellungen der Build-Aufgabe und scrollen Sie nach unten. Klicken Sie auf die Schaltflächen: Add build step -> Conditional step (single). In den Einstellungen des Schrittes wählen Sie die Bedingung Current build status, setzen Sie den Wert ERFOLG, die durchzuführende Aktion im Erfolgsfall Run shell command.
Und jetzt kommt das Interessante. Jenkins speichert die Aufgabenkonfiguration in Dateien. Im XML-Format. Unter dem Pfad http://pfad-zur-aufgabe/config.xml Daher können Sie die Konfigurationsdatei herunterladen, sie nach Bedarf bearbeiten und an den Ort zurücklegen, von wo Sie sie genommen haben.
Erinnern Sie sich, dass wir oben festgelegt haben, dass wir für die Versionsliste einen Parameter erstellen werden. BUILD_VERSION?
Lassen Sie uns die Konfigurationsdatei herunterladen und einen Blick hineinwerfen. Nur um sicherzustellen, dass der Parameter vorhanden ist und tatsächlich die richtige Form hat.
Screenshot unter dem Spoiler.
Ihr vorgegebener Abschnitt config.xml sollte genauso aussehen. Mit der Ausnahme, dass der Inhalt des Elements choices zurzeit fehlt.

Sind Sie sich sicher? Gut, dann schreiben wir das Skript, das im Fall eines erfolgreichen Builds ausgeführt wird.
Das Skript wird die Liste der Versionen abrufen, die Konfigurationsdatei herunterladen, die Liste der Versionen an die benötigte Stelle schreiben und sie dann wieder zurücklegen. Ja, das ist richtig. Die Liste der Versionen wird in die XML-Datei an die Stelle geschrieben, wo bereits eine Liste der Versionen existiert (wird in Zukunft nach dem ersten Ausführen des Skripts geschehen). Ich weiß, dass es auf der Welt noch leidenschaftliche Liebhaber von regulären Ausdrücken gibt. Ich gehöre nicht dazu. Bitte installieren Sie auf die Maschine, auf der die Konfiguration bearbeitet wird. Es scheint mir, dass dies kein allzu großer Preis ist, um die Bearbeitung von XML mit sed zu vermeiden.
Unter dem Spoiler finden Sie den vollständigen Code, der die oben beschriebene Sequenz ausführt.
Wir schreiben die Liste der Versionen aus dem Ordner auf dem Remote-Server in die Konfiguration.
#!/bin/bash
############## Скачиваем конфиг
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml
############## Удаляем и заново создаем xml-элемент для списка версий
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml
xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml
############## Читаем в массив список версий из репозитория
readarray -t vers < <( curl -H "X-JFrog-Art-Api:Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+' )
############## Пишем массив элемент за элементом в конфиг
printf '%sn' "${vers[@]}" | sort -r |
while IFS= read -r line
do
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
done
############## Кладем конфиг взад
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml
############## Приводим рабочее место в порядок
rm -f appConfig.xmlFalls Ihnen die Variante mit dem Abrufen von Versionen aus Jenkins besser gefällt und Sie ebenso faul sind wie ich, finden Sie unter dem Spoiler denselben Code, aber die Liste stammt aus Jenkins:
Wir schreiben die Liste der Versionen aus Jenkins in die Konfiguration.
Bitte beachten Sie, dass der Name des Builds aus einer fortlaufenden Nummer und einer Versionsnummer besteht, die durch einen Doppelpunkt getrennt sind. Daher schneidet awk den unnötigen Teil ab. Passen Sie diese Zeile nach Ihren Bedürfnissen an.
#!/bin/bash
############## Скачиваем конфиг
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml
############## Удаляем и заново создаем xml-элемент для списка версий
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml
xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml
############## Пишем в файл список версий из Jenkins
curl -g -X GET -u username:apiKey 'http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!=%22SUCCESS%22]&pretty=true' -o builds.xml
############## Читаем в массив список версий из XML
readarray vers < <(xmlstarlet sel -t -v "freeStyleProject/allBuild/displayName" builds.xml | awk -F":" '{print $2}')
############## Пишем массив элемент за элементом в конфиг
printf '%sn' "${vers[@]}" | sort -r |
while IFS= read -r line
do
xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
done
############## Кладем конфиг взад
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml
############## Приводим рабочее место в порядок
rm -f appConfig.xmlIdealerweise sollten Sie, wenn Sie den Code getestet haben, der auf den obigen Beispielen basiert, im Deployment-Auftrag bereits ein Dropdown-Menü mit Versionen sehen. So ähnlich wie auf dem Screenshot im Spoiler.
Korrekt ausgefüllte Versionenliste

Wenn alles funktioniert hat, kopieren Sie das Skript in Run shell command und speichern Sie die Änderungen.
Verbindung zur Cloud Shell
Die Builder befinden sich in Containern. Als Mittel zur Bereitstellung von Anwendungen und zur Konfigurationsverwaltung verwenden wir Ansible. Wenn es um den Bau von Containern geht, kommen mir drei Optionen in den Sinn: Docker innerhalb von Docker installieren, Docker auf die Maschine mit Ansible installieren oder Container in der Cloud-Konsole bauen. Über die Plugins für Jenkins haben wir in dieser Notiz Stillschweigen vereinbart. Erinnern Sie sich?
Ich habe beschlossen: Wenn ich Container „out of the box“ in der Cloud-Konsole erstellen kann, warum dann nicht einfach? Halten wir es sauber, oder? Ich möchte Jenkins-Container in der Cloud-Konsole erstellen und sie dann gleich in Kubernetes werfen. Zumal die Verbindungen innerhalb der Google-Infrastruktur extrem leistungsstark sind, was sich positiv auf die Bereitstellungsgeschwindigkeit auswirkt.
Um sich mit der Cloud-Konsole zu verbinden, benötigst du zwei Dinge: gcloud und Zugriffsrechte auf Google Cloud API für das VM-Exemplar, von dem aus die Verbindung hergestellt werden soll.
Für diejenigen, die sich überhaupt nicht aus der Google Cloud verbinden möchten:
Google ermöglicht, die interaktive Authentifizierung in seinen Diensten zu deaktivieren. Das bedeutet, dass du dich sogar von der Kaffeemaschine aus mit Unix/Linux darauf zugreifen kannst, solange sie eine Konsole hat.
Wenn du möchtest, dass ich dieses Thema in diesem Artikel genauer behandle, lass es mich in den Kommentaren wissen. Wenn genügend Stimmen zusammenkommen, schreibe ich ein Update zu diesem Thema.
Der einfachste Weg, Zugriffsrechte zu vergeben, ist über die Web-Oberfläche.
- Stoppe das VM-Exemplar, von dem aus du später die Verbindung zur Cloud-Konsole herstellen möchtest.
- Öffnen Sie die Instanzdetails und klicken Sie Ändern.
- Wählen Sie ganz unten auf der Seite den Zugriffbereich der Instanz aus Vollzugriff auf alle Cloud-APIs.
Screenshot

- Speichern Sie die Änderungen und starten Sie die Instanz.
Nachdem die VM hochgefahren ist, verbinden Sie sich über SSH und stellen Sie sicher, dass die Verbindung fehlerfrei ist. Verwenden Sie den Befehl:
gcloud alpha cloud-shell ssh Eine erfolgreiche Verbindung sieht ungefähr so aus

Deployment in GKE
Da wir bestrebt sind, vollständig auf IaC (Infrastructure as Code) umzusteigen, speichern wir unsere Dockerfiles in Git. Das ist die eine Seite. Das Deployment in Kubernetes wird durch eine YAML-Datei beschrieben, die ausschließlich für diese Aufgabe verwendet wird und die selbst auch als Code betrachtet werden kann. Das ist die andere Seite. Insgesamt lautet der Plan:
- Wir nehmen die Werte der Variablen BUILD_VERSION und optional die Werte der Variablen, die über ENV.
- Laden Sie das Dockerfile aus Git herunter.
- Generieren Sie die YAML für das Deployment.
- Laden Sie beide Dateien über SCP in die Cloud-Konsole hoch.
- Bauen Sie dort den Container und pushen Sie ihn in das Container-Registry
- Wenden Sie die Deployment-Datei in Kubernetes an.
Lassen Sie uns konkreter werden. Angenommen, wir müssen die Werte von zwei Parametern übergeben: ENVPARAM1 PARAM2 und PARAM2. Wir fügen ihren Bereitstellungsauftrag hinzu, Typ — String-Parameter.
Screenshot

Die YAML-Datei generieren wir durch einfaches Umleiten echo in die Datei. Es wird selbstverständlich vorausgesetzt, dass in Ihrer Docker-Datei PARAM2 und PARAM2, dass der Name der Last awesomeapp, und das erstellte Container mit der angegebenen Versionsnummer sich in Container-Registry unter dem Pfad gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION, wobei $BUILD_VERSION genau aus der Dropdown-Liste ausgewählt wurde.
Befehlslisting
touch deploy.yaml
echo "apiVersion: apps/v1" >> deploy.yaml
echo "kind: Deployment" >> deploy.yaml
echo "metadata:" >> deploy.yaml
echo " name: awesomeapp" >> deploy.yaml
echo "spec:" >> deploy.yaml
echo " replicas: 1" >> deploy.yaml
echo " selector:" >> deploy.yaml
echo " matchLabels:" >> deploy.yaml
echo " run: awesomeapp" >> deploy.yaml
echo " template:" >> deploy.yaml
echo " metadata:" >> deploy.yaml
echo " labels:" >> deploy.yaml
echo " run: awesomeapp" >> deploy.yaml
echo " spec:" >> deploy.yaml
echo " containers:" >> deploy.yaml
echo " - name: awesomeapp" >> deploy.yaml
echo " image: gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION:latest" >> deploy.yaml
echo " env:" >> deploy.yaml
echo " - name: PARAM1" >> deploy.yaml
echo " value: $PARAM1" >> deploy.yaml
echo " - name: PARAM2" >> deploy.yaml
echo " value: $PARAM2" >> deploy.yamlDer Jenkins-Agent hat nach der Verbindung über gcloud alpha cloud-shell ssh der interaktive Modus ist nicht verfügbar, daher übergeben wir die Befehle an die Cloud-Konsole mit Hilfe des Parameters —Befehl.
Wir bereinigen das Heimatverzeichnis in der Cloud-Konsole von alten Dockerfiles:
gcloud alpha cloud-shell ssh --command="rm -f Dockerfile"Wir legen die neu heruntergeladene Docker-Datei in das Heimatverzeichnis der Cloud-Konsole mit scp:
gcloud alpha cloud-shell scp localhost:./Dockerfile cloudshell:~Wir erstellen, taggen und pushen den Container in das Container-Registry:
gcloud alpha cloud-shell ssh --command="docker build -t awesomeapp-$BUILD_VERSION ./ --build-arg BUILD_VERSION=$BUILD_VERSION --no-cache"
gcloud alpha cloud-shell ssh --command="docker tag awesomeapp-$BUILD_VERSION gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"
gcloud alpha cloud-shell ssh --command="docker push gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"
Das Gleiche gilt für die Deploy-Datei. Beachten Sie, dass in den folgenden Befehlen fiktive Cluster-Namen verwendet werden, auf die das Deployment erfolgt (awsm-cluster) und der Projektname (awesome-project), wo sich der Cluster befindet.
gcloud alpha cloud-shell ssh --command="rm -f deploy.yaml"
gcloud alpha cloud-shell scp localhost:./deploy.yaml cloudshell:~
gcloud alpha cloud-shell ssh --command="gcloud container clusters get-credentials awsm-cluster --zone us-central1-c --project awesome-project &&
kubectl apply -f deploy.yaml"Wir starten den Job, öffnen die Konsolenausgabe und hoffen, eine erfolgreiche Container-Bereitstellung zu sehen.
Screenshot

Und darüber hinaus eine erfolgreiche Bereitstellung des erstellten Containers.
Screenshot

Ich habe absichtlich die Konfiguration ausgeblendet Ingress. Aus einem einfachen Grund: Einmal konfiguriert, bleibt es bei workload Mit dem angegebenen Namen bleibt es funktionsfähig, egal wie viele Deployments mit diesem Namen durchgeführt werden. Außerdem ist das Thema etwas außerhalb des Rahmens der Geschichte.
Statt Fazits
Die oben genannten Schritte könnte man wahrscheinlich auch einfach umgehen und ein Plugin für Jenkins installieren, es gibt dafür millionen. Aber irgendwie mag ich Plugins nicht. Oder besser gesagt, ich greife nur im Notfall darauf zurück.
Außerdem macht es mir einfach Spaß, ein neues Thema zu erkunden. Der oben stehende Text ist unter anderem ein Weg, meine Erkenntnisse zu teilen, die ich beim Lösen der zu Beginn beschriebenen Aufgabe gewonnen habe. Ich möchte das mit denen teilen, die wie ich kein erfahrener Wolf im DevOps sind. Wenn meine Erkenntnisse auch nur jemandem helfen, wäre ich zufrieden.
Quelle: habr.com

