Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins‘ Jacke

Alles begann, als der Teamleiter eines unserer Entwicklungsteams uns bat, seine neue Anwendung zu testen, die am Tag zuvor in Containern verpackt worden war. Ich habe es gepostet. Nach etwa 20 Minuten kam eine Anfrage, die Anwendung zu aktualisieren, da dort etwas sehr Notwendiges hinzugefügt wurde. Ich habe erneuert. Nach ein paar weiteren Stunden ... nun, Sie können sich vorstellen, was als nächstes geschah ...

Ich muss zugeben, ich bin ziemlich faul (habe ich das nicht früher zugegeben? Nein?), und angesichts der Tatsache, dass Teamleiter Zugriff auf Jenkins haben, in dem wir alle CI/CD haben, dachte ich: Lassen Sie ihn als bereitstellen so viel er will! Ich erinnerte mich an einen Witz: Gib einem Mann einen Fisch und er wird einen Tag lang essen; Nennen Sie einen Menschen FED und er wird sein ganzes Leben lang FED sein. Und ging bei der Arbeit Streiche spielen, der in der Lage wäre, einen Container mit der Anwendung jeder erfolgreich erstellten Version in Kuber bereitzustellen und beliebige Werte dorthin zu übertragen ENV (Mein Großvater, ein Philologe und früher Englischlehrer, drehte jetzt seinen Finger an seiner Schläfe und sah mich sehr ausdrucksvoll an, nachdem er diesen Satz gelesen hatte.)

In dieser Notiz werde ich Ihnen erzählen, wie ich gelernt habe:

  1. Aktualisieren Sie Jobs in Jenkins dynamisch vom Job selbst oder von anderen Jobs aus;
  2. Stellen Sie von einem Knoten aus, auf dem der Jenkins-Agent installiert ist, eine Verbindung zur Cloud-Konsole (Cloud-Shell) her.
  3. Stellen Sie die Arbeitslast in Google Kubernetes Engine bereit.


Tatsächlich bin ich natürlich etwas unaufrichtig. Es wird davon ausgegangen, dass Sie zumindest einen Teil der Infrastruktur in der Google Cloud haben, also deren Nutzer sind und natürlich über ein GCP-Konto verfügen. Aber darum geht es in dieser Notiz nicht.

Das ist mein nächster Spickzettel. Ich möchte solche Notizen nur in einem Fall schreiben: Ich stand vor einem Problem, ich wusste zunächst nicht, wie ich es lösen sollte, die Lösung war nicht fertig gegoogelt, also habe ich sie in Teilen gegoogelt und schließlich das Problem gelöst. Und damit ich in Zukunft, wenn ich vergesse, wie ich es gemacht habe, nicht noch einmal alles Stück für Stück googeln und zusammentragen muss, schreibe ich mir solche Spickzettel.

Haftungsausschluss: 1. Die Notiz wurde „für mich selbst“ geschrieben, für die Rolle best Practices gilt nicht. Ich freue mich, die „Es wäre besser, es so zu machen“-Optionen in den Kommentaren zu lesen.
2. Wenn der aufgetragene Teil der Notiz als Salz gilt, dann ist diese, wie alle meine vorherigen Notizen, eine schwache Salzlösung.

Dynamische Aktualisierung der Auftragseinstellungen in Jenkins

Ich sehe Ihre Frage voraus: Was hat die dynamische Jobaktualisierung damit zu tun? Geben Sie den Wert des String-Parameters manuell ein und los geht’s!

Ich antworte: Ich bin wirklich faul, ich mag es nicht, wenn sie sich beschweren: Mischa, die Bereitstellung stürzt ab, alles ist weg! Sie beginnen mit der Suche und stellen fest, dass der Wert eines Task-Startparameters einen Tippfehler enthält. Deshalb bevorzuge ich es, alles so effizient wie möglich zu erledigen. Wenn es möglich ist, die direkte Eingabe von Daten durch den Benutzer zu verhindern, indem man stattdessen eine Liste mit Werten zur Auswahl bereitstellt, dann organisiere ich die Auswahl.

Der Plan ist folgender: Wir erstellen einen Job in Jenkins, in dem wir vor dem Start eine Version aus der Liste auswählen und Werte für Parameter angeben können, die über an den Container übergeben werden ENV, dann sammelt es den Container und schiebt ihn in die Container Registry. Von dort aus wird der Container dann in Würfelform gestartet Pensum mit den im Job angegebenen Parametern.

Wir werden den Prozess der Erstellung und Einrichtung eines Jobs in Jenkins nicht berücksichtigen, da dies kein Thema ist. Wir gehen davon aus, dass die Aufgabe fertig ist. Um eine aktualisierte Liste mit Versionen zu implementieren, benötigen wir zwei Dinge: eine vorhandene Quellliste mit a priori gültigen Versionsnummern und eine Variable wie Auswahlparameter in der Aufgabe. In unserem Beispiel sei die Variable benannt BUILD_VERSION, wir werden nicht näher darauf eingehen. Doch werfen wir einen genaueren Blick auf die Quellenliste.

Es gibt nicht so viele Möglichkeiten. Zwei Dinge fielen mir sofort ein:

  • Nutzen Sie die Fernzugriffs-API, die Jenkins seinen Benutzern bietet;
  • Fordern Sie den Inhalt des Remote-Repository-Ordners an (in unserem Fall ist dies JFrog Artifactory, was nicht wichtig ist).

Jenkins-API für den Fernzugriff

Nach bewährter hervorragender Tradition möchte ich lange Erklärungen lieber vermeiden.
Ich erlaube mir nur eine freie Übersetzung eines Teils des ersten Absatzes erste Seite der API-Dokumentation:

Jenkins bietet eine API für den maschinenlesbaren Fernzugriff auf seine Funktionalität. <…> Der Fernzugriff wird im REST-ähnlichen Stil angeboten. Das bedeutet, dass es keinen einzigen Einstiegspunkt zu allen Funktionen gibt, sondern stattdessen eine URL wie „.../api/", Wo "...„bezeichnet das Objekt, auf das die API-Funktionen angewendet werden.

Mit anderen Worten, wenn die Bereitstellungsaufgabe, über die wir gerade sprechen, unter verfügbar ist http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build, dann sind die API-Pfeifen für diese Aufgabe unter verfügbar http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/

Als nächstes haben wir die Wahl, in welcher Form wir die Ausgabe erhalten möchten. Konzentrieren wir uns auf XML, da die API in diesem Fall nur das Filtern zulässt.

Versuchen wir einfach, eine Liste aller Jobausführungen zu erhalten. Uns interessiert nur der Assemblyname (Anzeigename) und sein Ergebnis (Folge):

http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]

Hat es funktioniert?

Lassen Sie uns nun nur die Läufe filtern, die am Ende das Ergebnis liefern ERFOLG. Lassen Sie uns das Argument verwenden &ausschließen und als Parameter übergeben wir ihm den Pfad zu einem Wert ungleich ERFOLG. Ja Ja. Eine doppelte Verneinung ist eine Aussage. 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 Erfolgsliste
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Nun, nur zum Spaß stellen wir sicher, dass der Filter uns nicht täuscht (Filter lügen nie!) und zeigen eine Liste der „erfolglosen“ an:

http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result='SUCCESS']

Screenshot der Liste der nicht erfolgreichen
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Liste der Versionen aus einem Ordner auf einem Remote-Server

Es gibt eine zweite Möglichkeit, eine Versionsliste abzurufen. Es gefällt mir noch besser als der Zugriff auf die Jenkins-API. Denn wenn die Anwendung erfolgreich erstellt wurde, bedeutet das, dass sie gepackt und im Repository im entsprechenden Ordner abgelegt wurde. Ein Repository ist beispielsweise der Standardspeicher für Arbeitsversionen von Anwendungen. Wie. Nun, fragen wir ihn, welche Versionen sich im Speicher befinden. Wir werden den Remote-Ordner einrollen, grepen und awk ausführen. Wenn sich jemand für den Oneliner interessiert, dann ist er unter dem Spoiler.

Einzeiliger Befehl
Bitte beachten Sie zwei Dinge: Ich übergebe die Verbindungsdetails im Header und benötige nicht alle Versionen aus dem Ordner, und ich wähle nur diejenigen aus, die innerhalb eines Monats erstellt wurden. Bearbeiten Sie den Befehl entsprechend Ihren Realitäten und Bedürfnissen:

curl -H "X-JFrog-Art-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[^/]+' )

Einrichten von Jobs und Jobkonfigurationsdatei in Jenkins

Wir haben die Quelle der Versionsliste herausgefunden. Lassen Sie uns nun die resultierende Liste in die Aufgabe integrieren. Für mich bestand die offensichtliche Lösung darin, der Anwendungserstellungsaufgabe einen Schritt hinzuzufügen. Der Schritt, der ausgeführt würde, wenn das Ergebnis „Erfolg“ wäre.

Öffnen Sie die Einstellungen für die Montageaufgabe und scrollen Sie ganz nach unten. Klicken Sie auf die Schaltflächen: Build-Schritt hinzufügen -> Bedingter Schritt (einzeln). Wählen Sie in den Schritteinstellungen die Bedingung aus Aktueller Build-Status, legen Sie den Wert fest ERFOLG, die Aktion, die bei Erfolg ausgeführt werden soll Führen Sie den Shell-Befehl aus.

Und jetzt der lustige Teil. Jenkins speichert Jobkonfigurationen in Dateien. Im XML-Format. Auf dem Weg http://путь-до-задания/config.xml Dementsprechend können Sie die Konfigurationsdatei herunterladen, bei Bedarf bearbeiten und wieder dort ablegen, wo Sie sie haben.

Denken Sie daran, dass wir oben vereinbart haben, einen Parameter für die Versionsliste zu erstellen BUILD_VERSION?

Laden wir die Konfigurationsdatei herunter und werfen einen Blick hinein. Nur um sicherzustellen, dass der Parameter vorhanden ist und vom gewünschten Typ ist.

Screenshot unter Spoiler.

Ihr config.xml-Fragment sollte gleich aussehen. Außer, dass der Inhalt des Elements „choices“ noch fehlt
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Bist du sicher? Das war's, schreiben wir ein Skript, das ausgeführt wird, wenn der Build erfolgreich ist.
Das Skript empfängt eine Versionsliste, lädt die Konfigurationsdatei herunter, schreibt die Versionsliste an die benötigte Stelle hinein und legt sie dann zurück. Ja. Alles ist richtig. Schreiben Sie eine Versionsliste in XML an der Stelle, an der sich bereits eine Versionsliste befindet (in der Zukunft, nach dem ersten Start des Skripts). Ich weiß, dass es auf der Welt immer noch leidenschaftliche Fans regulärer Ausdrücke gibt. Ich gehöre nicht zu ihnen. Bitte installiere xmlstarler an den Computer, auf dem die Konfiguration bearbeitet wird. Mir scheint, dass dies kein so hoher Preis ist, um die Bearbeitung von XML mit sed zu vermeiden.

Unter dem Spoiler präsentiere ich den Code, der die obige Sequenz vollständig ausführt.

Schreiben Sie eine Liste der Versionen aus einem 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.xml

Wenn Sie die Möglichkeit bevorzugen, Versionen von Jenkins zu bekommen, und genauso faul sind wie ich, dann finden Sie unter dem Spoiler den gleichen Code, aber eine Liste von Jenkins:

Schreiben Sie eine Liste der Versionen von Jenkins in die Konfiguration
Denken Sie daran: Mein Assemblyname besteht aus einer Sequenznummer und einer Versionsnummer, getrennt durch einen Doppelpunkt. Dementsprechend schneidet awk den unnötigen Teil ab. Ändern Sie diese Zeile für sich selbst entsprechend Ihren Bedürfnissen.

#!/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.xml

Wenn Sie den auf der Grundlage der obigen Beispiele geschriebenen Code getestet haben, sollte theoretisch in der Bereitstellungsaufgabe bereits eine Dropdown-Liste mit Versionen vorhanden sein. Es ist wie im Screenshot unter dem Spoiler.

Korrekt ausgefüllte Versionsliste
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Wenn alles funktioniert hat, kopieren Sie das Skript und fügen Sie es ein Führen Sie den Shell-Befehl aus und Änderungen speichern.

Verbindung zur Cloud-Shell herstellen

Wir haben Sammler in Containern. Wir verwenden Ansible als unser Anwendungsbereitstellungstool und Konfigurationsmanager. Dementsprechend fallen mir beim Erstellen von Containern drei Optionen ein: Docker in Docker installieren, Docker auf einer Maschine installieren, auf der Ansible läuft, oder Container in einer Cloud-Konsole erstellen. Über Plugins für Jenkins haben wir uns in diesem Artikel darauf geeinigt, Stillschweigen zu bewahren. Erinnern?

Ich entschied: Nun, da Container „out of the box“ in der Cloud-Konsole gesammelt werden können, warum sollte man sich dann die Mühe machen? Halten Sie es sauber, oder? Ich möchte Jenkins-Container in der Cloud-Konsole sammeln und sie dann von dort aus in den Cuber starten. Darüber hinaus verfügt Google innerhalb seiner Infrastruktur über sehr umfangreiche Kanäle, was sich positiv auf die Geschwindigkeit der Bereitstellung auswirken wird.

Um eine Verbindung zur Cloud-Konsole herzustellen, benötigen Sie zwei Dinge: gcloud und Zugriffsrechte auf Google Cloud API für die VM-Instanz, mit der dieselbe Verbindung hergestellt wird.

Für diejenigen, die eine Verbindung überhaupt nicht über die Google Cloud herstellen möchten
Google bietet in seinen Diensten die Möglichkeit, die interaktive Autorisierung zu deaktivieren. Auf diese Weise können Sie auch von einer Kaffeemaschine aus eine Verbindung zur Konsole herstellen, wenn diese unter *nix läuft und selbst über eine Konsole verfügt.

Wenn es notwendig ist, dass ich dieses Thema im Rahmen dieser Notiz ausführlicher behandele, schreiben Sie es in die Kommentare. Wenn wir genügend Stimmen bekommen, werde ich ein Update zu diesem Thema schreiben.

Die Rechtevergabe erfolgt am einfachsten über die Weboberfläche.

  1. Stoppen Sie die VM-Instanz, von der aus Sie anschließend eine Verbindung zur Cloud-Konsole herstellen.
  2. Öffnen Sie die Instanzdetails und klicken Sie auf Ändern.
  3. Wählen Sie ganz unten auf der Seite den Instanzzugriffsbereich aus Voller Zugriff auf alle Cloud-APIs.

    Screenshot
    Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

  4. Speichern Sie Ihre Änderungen und starten Sie die Instanz.

Sobald die VM vollständig geladen ist, stellen Sie über SSH eine Verbindung zu ihr her und stellen Sie sicher, dass die Verbindung fehlerfrei erfolgt. Verwenden Sie den Befehl:

gcloud alpha cloud-shell ssh

Eine erfolgreiche Verbindung sieht in etwa so aus
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

In GKE bereitstellen

Da wir mit allen Mitteln eine vollständige Umstellung auf IaC (Infrastruktur als Code) anstreben, werden unsere Docker-Dateien in Git gespeichert. Das ist einerseits. Und die Bereitstellung in Kubernetes wird durch eine Yaml-Datei beschrieben, die nur von dieser Aufgabe verwendet wird, die selbst auch wie Code ist. Das ist von der anderen Seite. Im Allgemeinen ist der Plan folgender:

  1. Wir nehmen die Werte der Variablen BUILD_VERSION und optional die Werte der Variablen, die weitergeleitet werden ENV.
  2. Laden Sie die Docker-Datei von Git herunter.
  3. Generieren Sie Yaml für die Bereitstellung.
  4. Wir laden diese beiden Dateien über scp in die Cloud-Konsole hoch.
  5. Wir bauen dort einen Container und pushen ihn in die Container-Registrierung
  6. Wir wenden die Load-Deployment-Datei auf den Cuber an.

Lassen Sie uns genauer sein. Sobald wir angefangen haben, darüber zu reden ENV, dann nehmen wir an, wir müssen die Werte von zwei Parametern übergeben: PARAM1 и PARAM2. Wir fügen ihre Aufgabe für die Bereitstellung hinzu, geben Sie ein: String-Parameter.

Screenshot
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Wir werden Yaml mit einer einfachen Umleitung generieren Echo einordnen. Es wird natürlich davon ausgegangen, dass Sie dies in Ihrer Docker-Datei haben PARAM1 и PARAM2dass der Ladename lauten wird tolle App, und der zusammengebaute Behälter mit der Anwendung der angegebenen Version liegt darin Containerregistrierung auf dem Weg gcr.io/awesomeapp/awesomeapp-$BUILD_VERSIONWo $BUILD_VERSION wurde gerade aus der Dropdown-Liste ausgewählt.

Teamliste

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.yaml

Jenkins-Agent nach der Verbindung mit gcloud alpha cloud-shell ssh Der interaktive Modus ist nicht verfügbar, daher senden wir mithilfe des Parameters Befehle an die Cloud-Konsole --Befehl.

Wir bereinigen den Home-Ordner in der Cloud-Konsole von der alten Docker-Datei:

gcloud alpha cloud-shell ssh --command="rm -f Dockerfile"

Platzieren Sie die frisch heruntergeladene Docker-Datei mit scp im Home-Ordner der Cloud-Konsole:

gcloud alpha cloud-shell scp localhost:./Dockerfile cloudshell:~

Wir sammeln, kennzeichnen und übertragen den Container in die Container-Registrierung:

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"

Dasselbe machen wir mit der Bereitstellungsdatei. Bitte beachten Sie, dass die folgenden Befehle fiktive Namen des Clusters verwenden, in dem die Bereitstellung erfolgt (awsm-cluster) und Projektname (tolles Projekt), 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 führen die Aufgabe aus, öffnen die Konsolenausgabe und hoffen, den erfolgreichen Zusammenbau des Containers zu sehen.

Screenshot
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Und dann der erfolgreiche Einsatz des zusammengebauten Containers

Screenshot
Wir erstellen eine Bereitstellungsaufgabe in GKE ohne Plugins, SMS oder Registrierung. Werfen wir einen Blick unter Jenkins' Jacke

Ich habe die Einstellung bewusst ignoriert Eintritt. Aus einem einfachen Grund: sobald Sie es eingerichtet haben Pensum Mit einem bestimmten Namen bleibt es betriebsbereit, unabhängig davon, wie viele Bereitstellungen Sie mit diesem Namen durchführen. Nun, im Allgemeinen sprengt dies ein wenig den Rahmen der Geschichte.

Anstelle von Schlussfolgerungen

Alle oben genannten Schritte hätten wahrscheinlich nicht durchgeführt werden können, sondern einfach ein Plugin für Jenkins, ihr Muuulion, installiert. Aber aus irgendeinem Grund mag ich keine Plugins. Genauer gesagt, ich greife nur aus Verzweiflung auf sie zurück.

Und ich möchte einfach ein neues Thema für mich aufgreifen. Der obige Text ist auch eine Möglichkeit, die Erkenntnisse weiterzugeben, die ich bei der Lösung des eingangs beschriebenen Problems gemacht habe. Teilen Sie es mit denen, die wie er überhaupt kein böser Wolf in der Entwicklung sind. Wenn meine Erkenntnisse zumindest jemandem helfen, freue ich mich.

Source: habr.com

Kommentar hinzufügen