Moderne OpenShift-Anwendungen, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift-Pipelines

Hallo an alle auf diesem Blog! Dies ist der dritte Beitrag in einer Reihe, in der wir Ihnen zeigen, wie Sie moderne Webanwendungen auf Red Hat OpenShift bereitstellen.







In den beiden vorherigen Beiträgen wurde erläutert, wie moderne Webanwendungen in nur wenigen Schritten bereitgestellt werden und wie ein neues S2I-Image zusammen mit einem vorgefertigten HTTP-Server-Image wie NGINX mithilfe verketteter Builds für die Produktionsbereitstellung verwendet wird.



Heute zeigen wir Ihnen, wie Sie einen Entwicklungsserver für Ihre Anwendung auf der OpenShift-Plattform ausführen und mit dem lokalen Dateisystem synchronisieren sowie was OpenShift Pipelines sind und wie Sie ihn als Alternative zu verknüpften Assemblys verwenden können.



OpenShift als Entwicklungsumgebung



Entwicklungsworkflow



Wie im ersten Beitrag erläutert , ist ein typischer Entwicklungsworkflow für moderne Webanwendungen einfach ein "Entwicklungsserver", der Änderungen in lokalen Dateien überwacht. In diesem Fall wird der Build der Anwendung gestartet und anschließend im Browser aktualisiert.



In den meisten modernen Frameworks ist dieser "Entwicklungsserver" in die entsprechenden Befehlszeilentools integriert.



Lokales Beispiel



Lassen Sie uns zunächst sehen, wie dies funktioniert, wenn Anwendungen lokal ausgeführt werden. Nehmen wir als Beispiel die React- App aus den vorherigen Artikeln, obwohl viele der gleichen Workflow-Konzepte für alle anderen modernen Frameworks gelten.

Um den "Entwicklungsserver" in unserem React-Beispiel zu starten, geben wir den folgenden Befehl aus:



$ npm run start


Dann sehen wir im Terminalfenster ungefähr Folgendes:







Und unsere Anwendung wird im Standardbrowser geöffnet:







Wenn wir nun Änderungen an der Datei vornehmen, sollte die Anwendung im Browser aktualisiert werden.



OK, mit der lokalen Entwicklung ist alles klar, aber wie kann man das unter OpenShift erreichen?



Entwicklungsserver unter OpenShift



Wenn Sie sich erinnern, haben wir im vorherigen Beitrag die sogenannte Ausführungsphase des S2I-Images analysiert und festgestellt, dass das Serve-Modul standardmäßig für die Bereitstellung unserer Webanwendung verantwortlich ist.



Wenn Sie sich jedoch das Ausführungsskript aus diesem Beispiel genauer ansehen , werden Sie feststellen, dass es die Umgebungsvariable $ NPM_RUN enthält, mit der Sie Ihren eigenen Befehl ausführen können.



Zum Beispiel können wir das Nodeshift-Modul verwenden, um unsere Anwendung bereitzustellen:



$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app


Hinweis: Das obige Beispiel wird zur Veranschaulichung der allgemeinen Idee abgekürzt.



Hier haben wir unserer Bereitstellung die Umgebungsvariable NPM_RUN hinzugefügt, die der Laufzeit mitteilt, dass der Garnstartbefehl ausgeführt werden soll, mit dem der React-Entwicklungsserver in unserem OpenShift-Pod gestartet wird.



Wenn Sie sich das Protokoll eines laufenden Pods ansehen, wird Folgendes angezeigt:







Natürlich wird dies alles nichts sein, bis wir den lokalen Code mit dem Code synchronisieren können, der ebenfalls auf Änderungen überwacht wird, aber auf einem Remote-Server lebt.



Remote- und lokalen Code synchronisieren



Glücklicherweise kann Nodeshift bei der Synchronisierung leicht helfen, und Sie können den Befehl watch verwenden, um Änderungen zu verfolgen.



Nachdem wir den Befehl zum Bereitstellen des Entwicklungsservers für unsere Anwendung ausgeführt haben, können wir den folgenden Befehl sicher verwenden:



$ npx nodeshift watch


Infolgedessen wird eine Verbindung zum laufenden Pod hergestellt, den wir etwas früher erstellt haben. Die Synchronisierung unserer lokalen Dateien mit dem Remote-Cluster wird aktiviert und die Dateien auf unserem lokalen System werden auf Änderungen überwacht.



Wenn wir jetzt die Datei src / App.js aktualisieren, reagiert das System auf diese Änderungen, kopiert sie in den Remote-Cluster und startet den Entwicklungsserver, der dann unsere Anwendung im Browser aktualisiert.



Lassen Sie uns der Vollständigkeit halber zeigen, wie diese Befehle in ihrer Gesamtheit aussehen:



$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false


Der Befehl watch ist eine Abstraktion über dem Befehl oc rsync. Weitere Informationen zur Funktionsweise finden Sie hier .



Dies war ein Beispiel für React, aber genau dieselbe Methode kann mit anderen Frameworks verwendet werden. Legen Sie einfach die Umgebungsvariable NPM_RUN nach Bedarf fest.



Open-Shift-Pipelines









Als nächstes werden wir über ein Tool wie OpenShift Pipelines sprechen und wie es als Alternative zu verketteten Builds verwendet werden kann.



Was ist OpenShift Pipelines?



OpenShift Pipelines ist ein Cloud-basiertes CI / CD-System zur kontinuierlichen Integration und Bereitstellung von Pipelines mit Tekton. Tekton ist ein flexibles Open-Source-CI / CD-Framework von Kubernetes, das die Bereitstellung plattformübergreifend (Kubernetes, serverlose, virtuelle Maschinen usw.) automatisiert, indem es von der zugrunde liegenden Schicht abstrahiert.



Um diesen Artikel zu verstehen, sind einige Kenntnisse über Pipelines erforderlich. Wir empfehlen Ihnen daher dringend, zuerst das offizielle Tutorial zu lesen .



Arbeitsumgebung einrichten



Um mit den Beispielen in diesem Artikel herumzuspielen, müssen Sie zunächst Ihre Produktionsumgebung vorbereiten:



  1. OpenShift 4. CodeReady Containers (CRD), .
  2. , , Pipeline Operator. , , .
  3. Tekton CLI (tkn) .
  4. create-react-app, , ( React).
  5. () , npm install npm start.


Das Anwendungsrepository verfügt außerdem über einen k8s-Ordner, in dem sich die zum Bereitstellen der Anwendung verwendeten Kubernetes / OpenShift-YAMLs befinden. In diesem Repository werden Aufgaben, Clusteraufgaben, Ressourcen und Pipelines erstellt .



Lass uns anfangen



Der erste Schritt für unser Beispiel besteht darin, ein neues Projekt im OpenShift-Cluster zu erstellen. Nennen wir dieses Projekt Webapp-Pipeline und erstellen es mit dem folgenden Befehl:



$ oc new-project webapp-pipeline


Außerdem wird dieser Name des Projekts im Code angezeigt. Wenn Sie sich also entscheiden, ihm einen anderen Namen zu geben, vergessen Sie nicht, den Code aus den Beispielen entsprechend zu bearbeiten. Ab diesem Punkt gehen wir nicht von oben nach unten, sondern von unten nach oben: Das heißt, wir erstellen zuerst alle Komponenten des Förderers und erst dann selbst.



Also zuallererst ...



Aufgaben



Lassen Sie uns einige Aufgaben erstellen, die uns dann bei der Bereitstellung der Anwendung in unserer Pipeline helfen. Die erste Aufgabe, apply_manifests_task, ist für die Anwendung von YAML auf die Kubernetes-Ressourcen (Dienst, Bereitstellung und Route) verantwortlich, die sich im Ordner k8s unserer Anwendung befinden. Die zweite Aufgabe - update_deployment_task - ist für die Aktualisierung eines bereits bereitgestellten Images auf das von unserer Pipeline erstellte Image verantwortlich.



Mach dir keine Sorgen, wenn es noch nicht klar ist. Tatsächlich handelt es sich bei diesen Aufgaben um Dienstprogramme, auf die wir später noch näher eingehen werden. Lassen Sie uns sie zunächst einfach erstellen:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml


Überprüfen Sie dann mit dem Befehl tkn CLI, ob die Aufgaben erstellt wurden:



$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago


Hinweis: Dies sind lokale Aufgaben Ihres aktuellen Projekts.



Cluster-Aufgaben



Clustered Tasks sind im Grunde dasselbe wie einfache Tasks. Das heißt, es handelt sich um eine wiederverwendbare Sammlung von Schritten, die beim Starten einer bestimmten Aufgabe auf die eine oder andere Weise kombiniert werden. Der Unterschied besteht darin, dass die Clusteraufgabe überall im Cluster verfügbar ist. Verwenden Sie erneut den Befehl tkn CLI, um eine Liste der Clusteraufgaben anzuzeigen, die beim Hinzufügen des Pipeline-Operators automatisch erstellt werden:



$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago


Erstellen wir nun zwei Cluster-Aufgaben. Der erste generiert ein S2I-Image und sendet es an die interne OpenShift-Registrierung. Die zweite besteht darin, unser NGINX-basiertes Image mit der Anwendung zu erstellen, die wir bereits als Inhalt zusammengestellt haben.



Erstellen und senden Sie das Bild



Beim Erstellen der ersten Aufgabe wiederholen wir das, was wir bereits im vorherigen Artikel über verknüpfte Assemblys getan haben. Denken Sie daran, dass wir das S2I-Image (ubi8-s2i-web-app) zum "Erstellen" unserer Anwendung verwendet haben und das Image in der internen OpenShift-Registrierung gespeichert wurde. Wir werden nun dieses S2I-Image der Webanwendung verwenden, um eine Docker-Datei für unsere Anwendung zu erstellen, und dann Buildah verwenden, um den eigentlichen Build durchzuführen und das resultierende Image in die interne OpenShift-Registrierung zu übertragen, da dies genau das ist, was OpenShift tut, wenn Sie Ihre bereitstellen. Anwendungen mit NodeShift.



Woher haben wir das alles gewusst, fragst du? Von der offiziellen Version von offiziell Node.js haben wir es einfach kopiert und für uns selbst fertiggestellt.



Nun erstellen wir die s2i-Web-App-Cluster-Aufgabe:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml


Wir werden darauf nicht näher eingehen, sondern nur auf den Parameter OUTPUT_DIR eingehen:



params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build


Standardmäßig ist dieser Parameter so eingestellt, dass er erstellt wird. Hier legt React den gesammelten Inhalt ab. Andere Frameworks verwenden andere Pfade, z. B. verwendet Ember dist. Die Ausgabe unserer ersten Clusteraufgabe ist ein Bild, das das von uns gesammelte HTML, JavaScript und CSS enthält.



Erstellen eines auf NGINX basierenden Images



Bei unserer zweiten Clusteraufgabe sollte ein auf NGINX basierendes Bild unter Verwendung des Inhalts der bereits gesammelten Anwendung erfasst werden. Grundsätzlich ist dies der Teil des vorherigen Abschnitts, in dem wir uns verkettete Builds angesehen haben.



Zu diesem Zweck erstellen wir - wie oben beschrieben - eine Cluster-Task-Webapp-Build-Laufzeit:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml


Wenn Sie sich den Code für diese Cluster-Aufgaben ansehen, sehen Sie, dass das Git-Repository, mit dem wir arbeiten, oder die Namen der von uns erstellten Bilder dort nicht angegeben sind. Wir geben nur an, was genau wir auf Git oder ein bestimmtes Bild übertragen, auf dem das endgültige Bild angezeigt werden soll. Aus diesem Grund können diese Clusteraufgaben bei der Arbeit mit anderen Anwendungen wiederverwendet werden.



Und hier gehen wir anmutig zum nächsten Punkt über ...



Ressourcen



Da Cluster-Aufgaben, wie bereits erwähnt, so allgemein wie möglich sein sollten, müssen wir Ressourcen erstellen, die für die Eingabe (Git-Repository) und Ausgabe (endgültige Images) verwendet werden. Die erste Ressource, die wir benötigen, ist Git, wo sich unsere Anwendung befindet.



# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: web-application-repo
spec:
  type: git
  params:
    - name: url
      value: https://github.com/nodeshift-starters/react-pipeline-example
    - name: revision
      value: master


Hier ist PipelineResource vom Typ git. Der URL-Schlüssel im Abschnitt params verweist auf ein bestimmtes Repository und legt den Hauptzweig fest (dies ist optional, wird jedoch der Vollständigkeit halber geschrieben).



Jetzt müssen wir eine Ressource für das Bild erstellen, in der die Ergebnisse der s2i-Web-App-Aufgabe gespeichert werden. Dies geschieht folgendermaßen:



# This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: built-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest


Hier ist die PipelineResource vom Typ image, und der Wert des URL-Parameters verweist auf die interne OpenShift Image-Registrierung, insbesondere auf die im Webapp-Pipeline-Namespace. Denken Sie daran, diesen Parameter zu ändern, wenn Sie einen anderen Namespace verwenden.



Und schließlich wird die letzte Ressource, die wir benötigen, auch vom Image-Typ sein, und dies wird das endgültige NGINX-Image sein, das dann während der Bereitstellung verwendet wird:



# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: runtime-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest


Beachten Sie erneut, dass diese Ressource das Image in der internen OpenShift-Registrierung im Namespace der Webanwendungspipeline speichert.



Verwenden Sie den Befehl create, um alle diese Ressourcen gleichzeitig zu erstellen:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml


Sie können sicherstellen, dass die Ressourcen folgendermaßen erstellt wurden:



$ tkn resource ls


Pipeline Pipeline



Nachdem wir alle erforderlichen Komponenten haben, werden wir daraus eine Pipeline zusammenstellen und diese mit dem folgenden Befehl erstellen:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml


Bevor Sie diesen Befehl ausführen, werfen wir einen Blick auf diese Komponenten. Der erste ist der Name:



apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react


Dann sehen wir im Spezifikationsabschnitt einen Hinweis auf die Ressourcen, die wir zuvor erstellt haben:



spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image


Anschließend erstellen wir Aufgaben für unsere Pipeline. Zunächst muss er die bereits erstellte s2i-Web-App-Aufgabe ausführen:



tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask


Diese Aufgabe verwendet Eingabe- (Gir-Resource) und Ausgabeparameter (Built-Web-Application-Image-Ressource). Wir übergeben ihm auch einen speziellen Parameter, damit TLS nicht überprüft wird, da wir selbstsignierte Zertifikate verwenden:



resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"


Die nächste Aufgabe ist fast dieselbe, nur hier heißt die bereits erstellte Webapp-Build-Runtime-Cluster-Aufgabe:



name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask


Wie bei der vorherigen Aufgabe übergeben wir die Ressource, aber dies ist jetzt ein erstelltes Webanwendungs-Image (die Ausgabe unserer vorherigen Aufgabe). Und als Ausgabe setzen wir wieder das Bild. Da diese Aufgabe nach der vorherigen ausgeführt werden soll, fügen wir das Feld runAfter hinzu:



resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application


Die nächsten beiden Aufgaben sind für das Anwenden der Service-, Routen- und Bereitstellungs-YAML-Dateien verantwortlich, die sich im k8s-Verzeichnis unserer Webanwendung befinden, und für das Aktualisieren dieser Bereitstellung beim Erstellen neuer Images. Wir setzen diese beiden Cluster-Aufgaben am Anfang des Artikels.



Förderband laufen lassen



Also werden alle Teile unserer Pipeline erstellt und wir werden sie mit dem folgenden Befehl starten:



$ tkn pipeline start build-and-deploy-react


In dieser Phase wird die Befehlszeile interaktiv verwendet, und Sie müssen die entsprechenden Ressourcen als Antwort auf jede ihrer Anforderungen auswählen: Wählen Sie für die Git-Ressource Webanwendungs-Repo aus, dann für die erste Image-Ressource - Built-Web-Application-Image und schließlich für die zweite Bildressource - Laufzeit-Webanwendungsbild:



? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr


Überprüfen wir nun den Pipeline-Status mit dem folgenden Befehl:



$ tkn pipeline logs -f


Nachdem die Pipeline gestartet und die Anwendung bereitgestellt wurde, fordern wir die veröffentlichte Route mit dem folgenden Befehl an:



$ oc get route react-pipeline-example --template='http://{{.spec.host}}'


Für mehr Sichtbarkeit können Sie unsere Pipeline im Entwicklermodus der Webkonsole im Abschnitt Pipelines anzeigen ( siehe Abb. 1). 1.







Abb. 1. Übersicht über laufende Pipelines.



Wenn Sie auf eine laufende Pipeline klicken, werden zusätzliche Informationen angezeigt (siehe Abbildung 2).







Zahl: 2. Weitere Informationen zur Pipeline.



Nach weiteren Details können Sie die ausgeführten Anwendungen in der Topologieansicht anzeigen (siehe Abbildung 3).







Abb. 3. Pod laufen lassen.



Durch Klicken auf den Kreis in der oberen rechten Ecke des Symbols wird unsere Anwendung geöffnet (siehe Abbildung 4).







Zahl: 4. React-Anwendung ausführen.



Fazit



Daher haben wir gezeigt, wie Sie einen Entwicklungsserver für Ihre Anwendung unter OpenShift ausführen und mit dem lokalen Dateisystem synchronisieren. Wir haben uns auch angesehen, wie die verkettete Build-Vorlage mithilfe von OpenShift-Pipelines nachgeahmt werden kann. Alle Beispielcodes aus diesem Artikel finden Sie hier .



Zusätzliche Ressourcen (EN)







Kommende Ankündigungen von Webinaren



Wir starten eine Reihe von Webinaren am Freitag über die native Erfahrung mit der Verwendung der Red Hat OpenShift Container Platform und von Kubernetes:






All Articles