{"id":92048,"date":"2020-08-22T07:42:57","date_gmt":"2020-08-22T05:42:57","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines"},"modified":"2020-08-22T07:42:57","modified_gmt":"2020-08-22T05:42:57","slug":"sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","title":{"rendered":"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo zusammen in diesem Blog! Hier ist der dritte Beitrag aus der Reihe, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift bereitstellt.<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/9c3337b13a3f045d36343308ce6154cc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn den beiden vorherigen Beitr\u00e4gen haben wir beschrieben, wie man moderne Webanwendungen in nur wenigen Schritten bereitstellt und wie man das neue S2I-Image zusammen mit einem vorgefertigten HTTP-Server-Image, zum Beispiel NGINX, mithilfe von verbundenen Builds f\u00fcr die Organisation der Produktionsbereitstellung nutzt.<\/p>\n<p>Heute zeigen wir, wie man auf der OpenShift-Plattform einen Entwicklungsserver f\u00fcr seine Anwendung startet und ihn mit dem lokalen Dateisystem synchronisiert. Au\u00dferdem werden wir dar\u00fcber sprechen, was OpenShift Pipelines sind und wie sie als Alternative zu verbundenen Builds eingesetzt werden k\u00f6nnen.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>OpenShift als Entwicklungsumgebung<\/h3>\n<p><\/p>\n<h4>Entwicklungsworkflow<\/h4>\n<p>\nWie bereits im <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">ersten Beitrag<\/a><\/noindex>erw\u00e4hnt, ist der typische Entwicklungsprozess f\u00fcr moderne Webanwendungen im Wesentlichen ein \"Entwicklungsserver\", der \u00c4nderungen an lokalen Dateien \u00fcberwacht. Wenn diese eintreten, wird eine Anwendungskompilation gestartet und die Anwendung wird im Browser aktualisiert.<\/p>\n<p>In den meisten modernen Frameworks ist ein solcher \"Entwicklungsserver\" in die entsprechenden Befehlszeilenwerkzeuge integriert.<\/p>\n<h4>Lokales Beispiel<\/h4>\n<p>\nSchauen wir uns zun\u00e4chst an, wie das bei der lokalen Ausf\u00fchrung von Anwendungen funktioniert. Als Beispiel nehmen wir die Anwendung <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">React<\/a><\/noindex> aus den vorherigen Artikeln, obwohl die gleichen Konzepte des Workflows auch in allen anderen modernen Frameworks Anwendung finden.<br \/>\nUm den \"Entwicklungsserver\" in unserem Beispiel mit React zu starten, geben wir den folgenden Befehl ein:<\/p>\n<pre><code class=\"plaintext\">$ npm run start\n<\/code><\/pre>\n<p>\nDann sehen wir im Terminalfenster ungef\u00e4hr Folgendes:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/06f84ffb4c9a6a5868b8b47b8ad1d9ec.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Und unsere Anwendung wird im Standardbrowser ge\u00f6ffnet:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/72341bb0796352e7343bf31ceb8233cd.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Jetzt, wenn wir \u00c4nderungen an der Datei vornehmen, sollte die Anwendung im Browser aktualisiert werden.<\/p>\n<p>Okay, mit der Entwicklung im lokalen Modus ist alles klar, aber wie erreichen wir das Gleiche auf OpenShift?<\/p>\n<h4>Entwicklungsserver auf OpenShift<\/h4>\n<p>\nWenn Sie sich erinnern, haben wir in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/513948\/\">im vorherigen Beitrag<\/a><\/noindex>den sogenannten Startphase (run phase) des S2I-Images behandelt und gesehen, dass standardm\u00e4\u00dfig das Modul serve f\u00fcr unsere Webanwendung zust\u00e4ndig ist.<\/p>\n<p>Wenn wir jedoch genauer hinsehen, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/ubi8-s2i-web-app\/blob\/master\/s2i\/run#L10\">Ausf\u00fchrungsskript<\/a><\/noindex> aus diesem Beispiel, finden wir die Umgebungsvariable $NPM_RUN, die es uns erm\u00f6glicht, auch unseren eigenen Befehl auszuf\u00fchren.<\/p>\n<p>Wir k\u00f6nnen zum Beispiel das Modul nodeshift verwenden, um unsere Anwendung bereitzustellen:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift --deploy.env NPM_RUN=\"yarn start\" --dockerImage=nodeshift\/ubi8-s2i-web-app\n<\/code><\/pre>\n<p>\n<i>Hinweis: Das obige Beispiel wird aus Gr\u00fcnden der K\u00fcrze angef\u00fchrt, um die allgemeine Idee zu veranschaulichen.<\/i><\/p>\n<p>Hier haben wir in unser Deployment die Umgebungsvariable NPM_RUN hinzugef\u00fcgt, die dem Ausf\u00fchrungsprozess mitteilt, dass er den Befehl yarn start ausf\u00fchren soll, um den Entwicklungsserver von React innerhalb unseres OpenShift-Pods zu starten.<\/p>\n<p>Wenn man das Protokoll des laufenden Pods betrachtet, sieht es ungef\u00e4hr so aus:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/5b090223e08e32a3356608881068ce1a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Nat\u00fcrlich ist das alles nichtssagend, solange wir unseren lokalen Code nicht mit dem Code synchronisieren k\u00f6nnen, der ebenfalls auf \u00c4nderungen \u00fcberwacht wird, aber auf einem entfernten Server lebt.<\/p>\n<h4>Synchronisation von entferntem und lokalem Code<\/h4>\n<p>\nGl\u00fccklicherweise kann nodeshift leicht bei der Synchronisation helfen, und zur \u00dcberwachung von \u00c4nderungen kann der Befehl watch verwendet werden.<\/p>\n<p>Nachdem wir also den Befehl zum Deployen des Entwicklungsservers f\u00fcr unsere Anwendung ausgef\u00fchrt haben, k\u00f6nnen wir getrost folgenden Befehl verwenden:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift watch\n<\/code><\/pre>\n<p>\nInfolgedessen wird eine Verbindung zu dem zuvor erstellten laufenden Pod hergestellt, die Synchronisation unserer lokalen Dateien mit dem entfernten Cluster aktiviert, und die Dateien auf unserem lokalen System beginnen, auf \u00c4nderungen \u00fcberwacht zu werden.<\/p>\n<p>Wenn jetzt die Datei src\/App.js aktualisiert wird, reagiert das System auf diese \u00c4nderungen, kopiert sie zum entfernten Cluster und startet den Entwicklungsserver, der dann unsere Anwendung im Browser aktualisiert.<\/p>\n<p>Um das Bild zu vervollst\u00e4ndigen, zeigen wir, wie diese Befehle vollst\u00e4ndig aussehen:<\/p>\n<pre><code class=\"plaintext\">$ 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\n\n$ npx nodeshift watch --strictSSL=false\n<\/code><\/pre>\n<p>\nDer watch-Befehl ist eine Abstraktion \u00fcber dem oc rsync-Befehl, mehr dar\u00fcber, wie es funktioniert, kann man hier erfahren. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/copy_files_to_container.html\">hier<\/a><\/noindex>.<\/p>\n<p>Das war ein Beispiel f\u00fcr React, aberelbe Methode kann auch mit anderen Frameworks verwendet werden, man muss lediglich die Umgebungsvariable NPM_RUN entsprechend festlegen.<br \/>\n\u2003<\/p>\n<h3>OpenShift Pipelines<\/h3>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/33b932d3591b22dd00d82509b352d489.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Als N\u00e4chstes werden wir \u00fcber ein Tool namens OpenShift Pipelines sprechen und wie es als Alternative zu verkn\u00fcpften Builds (chained build) verwendet werden kann.<\/p>\n<h4>Was sind OpenShift Pipelines?<\/h4>\n<p>\nOpenShift Pipelines ist ein cloudorientiertes CI\/CD-System f\u00fcr kontinuierliche Integration und Bereitstellung, das zur Organisation von Pipelines mit Tekton verwendet wird. Tekton ist ein flexibles, Kubernetes-natives CI\/CD-Framework mit offenem Quellcode, das die Automatisierung der Bereitstellung auf verschiedenen Plattformen (Kubernetes, serverless, virtuelle Maschinen usw.) durch Abstraktion von der darunterliegenden Ebene erm\u00f6glicht.<\/p>\n<p>Um diesen Artikel zu verstehen, sind bestimmte Kenntnisse \u00fcber Pipelines erforderlich, daher empfehlen wir dringend, sich zun\u00e4chst mit <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\">dem offiziellen Handbuch<\/a><\/noindex>.<\/p>\n<h4>Einrichten der Arbeitsumgebung<\/h4>\n<p>\nUm mit den Beispielen aus diesem Artikel zu experimentieren, m\u00fcssen Sie zun\u00e4chst die Arbeitsumgebung vorbereiten:<\/p>\n<ol>\n<li>Installieren und Einrichten eines OpenShift 4 Clusters. In unseren Beispielen wird daf\u00fcr CodeReady Containers (CRD) verwendet, die Installationsanleitung finden Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.redhat.com\/openshift\/install\/crc\/installer-provisioned\">hier<\/a><\/noindex>.<\/li>\n<li>Sobald das Cluster bereit ist, muss der Pipeline-Operator installiert werden. Keine Sorge, das ist einfach, die Installationsanleitung finden Sie <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\/blob\/master\/install-operator.md\">hier<\/a><\/noindex>.<\/li>\n<li>Herunterladen <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">Tekton CLI<\/a><\/noindex> (tkn) <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">hier<\/a><\/noindex>.<\/li>\n<li>Starten Sie das Befehlszeilenwerkzeug create-react-app, um eine Anwendung zu erstellen, die anschlie\u00dfend bereitgestellt wird (dies ist eine einfache Anwendung <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\">React<\/a><\/noindex>).<\/li>\n<li>(Optional) Klonen Sie das Repository, um das Anwendungsbeispiel lokal mit dem Befehl npm install auszuf\u00fchren und dann npm start.<\/li>\n<\/ol>\n<p>\nIm Anwendungsrepository gibt es auch einen Ordner k8s, in dem sich die YAML-Dateien von Kubernetes\/OpenShift befinden, die zur Bereitstellung der Anwendung verwendet werden. Dort befinden sich Tasks, ClusterTasks, Ressourcen und Pipelines, die wir in diesem <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">das Repository<\/a><\/noindex>.<\/p>\n<h4>Wir beginnen<\/h4>\n<p>\nZuerst m\u00fcssen wir f\u00fcr unser Beispiel ein neues Projekt im OpenShift-Cluster erstellen. Nennen wir dieses Projekt webapp-pipeline und erstellen wir es mit dem folgenden Befehl:<\/p>\n<pre><code class=\"plaintext\">$ oc new-project webapp-pipeline\n<\/code><\/pre>\n<p>\nDieser Projektname wird dann im Code verwendet, also vergessen Sie nicht, den Code der Beispiele entsprechend zu \u00e4ndern, falls Sie ihm einen anderen Namen geben. Ab diesem Punkt werden wir nicht von oben nach unten, sondern von unten nach oben vorgehen: das hei\u00dft, wir erstellen zuerst alle Bestandteile der Pipeline und erst danach die Pipeline selbst.<\/p>\n<p>Also, als Erstes\u2026<\/p>\n<h4>Aufgaben Tasks<\/h4>\n<p>\nWir erstellen ein paar Aufgaben (tasks), die dann helfen werden, die Anwendung im Rahmen unserer Pipeline zu deployen. Die erste Aufgabe \u2013 apply_manifests_task \u2013 ist verantwortlich f\u00fcr die Anwendung der YAML-Dateien der Kubernetes-Ressourcen (Service, Deployment und Route), die sich im k8s-Ordner unserer Anwendung befinden. Die zweite Aufgabe \u2013 update_deployment_task \u2013 ist verantwortlich f\u00fcr das Aktualisieren des bereits bereitgestellten Images auf das, das von unserer Pipeline erstellt wird.<\/p>\n<p>Keine Sorge, wenn es bisher noch nicht ganz klar ist. Tats\u00e4chlich sind diese Aufgaben eine Art von Dienstprogrammen, und wir werden sie sp\u00e4ter genauer erl\u00e4utern. Lassen Sie uns vorerst einfach die beiden erstellen:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/update_deployment_task.yaml\n$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/apply_manifests_task.yaml\n<\/code><\/pre>\n<p>\nDann \u00fcberpr\u00fcfen wir mit dem tkn CLI-Befehl, ob die Aufgaben erstellt wurden:<\/p>\n<pre><code class=\"plaintext\">$ tkn task ls\n\nNAME                AGE\napply-manifests     vor 1 Minute\nupdate-deployment   vor 1 Minute\n<\/code><\/pre>\n<p>\n<i>Hinweis: Dies sind lokale Aufgaben Ihres aktuellen Projekts.<\/i><\/p>\n<h4>Klastenaufgaben Cluster tasks<\/h4>\n<p>\nKlastenaufgaben sind im Grunde dasselbe wie einfache Aufgaben. Das hei\u00dft, es handelt sich um eine wiederverwendbare Sammlung von Schritten, die auf verschiedene Weise kombiniert werden, wenn eine bestimmte Aufgabe ausgef\u00fchrt wird. Der Unterschied besteht darin, dass eine Klastenaufgabe im gesamten Cluster verf\u00fcgbar ist. Um die Liste der Klastenaufgaben zu sehen, die automatisch erstellt werden, wenn der Pipeline Operator hinzugef\u00fcgt wird, verwenden wir erneut den tkn CLI-Befehl:<\/p>\n<pre><code class=\"plaintext\">$ tkn clustertask ls\n\nNAME                       AGE\nbuildah                    vor 1 Tag\nbuildah-v0-10-0            vor 1 Tag\njib-maven                  vor 1 Tag\nkn                         vor 1 Tag\nmaven                      vor 1 Tag\nopenshift-client           vor 1 Tag\nopenshift-client-v0-10-0   vor 1 Tag\ns2i                        vor 1 Tag\ns2i-go                     vor 1 Tag\ns2i-go-v0-10-0             vor 1 Tag\ns2i-java-11                vor 1 Tag\ns2i-java-11-v0-10-0        vor 1 Tag\ns2i-java-8                 vor 1 Tag\ns2i-java-8-v0-10-0         vor 1 Tag\ns2i-nodejs                 vor 1 Tag\ns2i-nodejs-v0-10-0         vor 1 Tag\ns2i-perl                   vor 1 Tag\ns2i-perl-v0-10-0           vor 1 Tag\ns2i-php                    vor 1 Tag\ns2i-php-v0-10-0            vor 1 Tag\ns2i-python-3               vor 1 Tag\ns2i-python-3-v0-10-0       vor 1 Tag\ns2i-ruby                   vor 1 Tag\ns2i-ruby-v0-10-0           vor 1 Tag\ns2i-v0-10-0                vor 1 Tag\n<\/code><\/pre>\n<p>\nJetzt erstellen wir zwei Klastenaufgaben. Die erste wird ein S2I-Image generieren und es in das interne OpenShift-Registry hochladen; die zweite wird unser Image auf Basis von NGINX erstellen und die bereits entwickelte Anwendung als Inhalt verwenden.<\/p>\n<h4>Wir erstellen und laden das Image hoch<\/h4>\n<p>\nBei der Erstellung der ersten Aufgabe wiederholen wir das, was wir bereits im vorherigen Artikel \u00fcber verkn\u00fcpfte Builds behandelt haben. Wir erinnern daran, dass wir das S2I-Image (ubi8-s2i-web-app) verwendet haben, um unsere Anwendung zu \u201ebauen\u201c, und letztlich ein Image erhalten haben, das im internen OpenShift-Registry gespeichert ist. Jetzt werden wir dieses S2I-Image der Webanwendung verwenden, um ein DockerFile f\u00fcr unsere Anwendung zu erstellen, und dann Buildah einsetzen, um den tats\u00e4chlichen Build durchzuf\u00fchren und das erhaltene Image in die interne OpenShift-Registry zu senden, denn genau das macht OpenShift, wenn Sie Ihre Anwendungen mit NodeShift bereitstellen.<\/p>\n<p>Fragen Sie sich, woher wir das alles wissen? Aus <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-catalog\/blob\/master\/s2i-nodejs\/s2i-nodejs-task.yaml\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 official Node.js<\/a><\/noindex>, haben wir es einfach kopiert und an unsere Bed\u00fcrfnisse angepasst.<\/p>\n<p>So, jetzt erstellen wir die Cluster-Aufgabe s2i-web-app:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/s2i-web-app-task.yaml\n<\/code><\/pre>\n<p>\nWir werden das nicht im Detail durchgehen, sondern nur auf den Parameter OUTPUT_DIR eingehen:<\/p>\n<pre><code class=\"plaintext\">params:\n      - name: OUTPUT_DIR\n        description: Der Speicherort des Build-Ausgabeverzeichnisses\n        default: build\n<\/code><\/pre>\n<p>\nStandardm\u00e4\u00dfig ist dieser Parameter auf build gesetzt, dorthin legt React den gebauten Inhalt ab. In anderen Frameworks werden andere Pfade verwendet, zum Beispiel in Ember ist es dist. Die Ausgabe unserer ersten Cluster-Aufgabe wird ein Image sein, das die von uns gebauten HTML-, JavaScript- und CSS-Dateien enth\u00e4lt.<\/p>\n<h4>Wir erstellen ein Image auf der Basis von NGINX<\/h4>\n<p>\nWas unsere zweite Cluster-Aufgabe betrifft, so soll sie ein Image auf Basis von NGINX erstellen, das den Inhalt unserer bereits gebauten Anwendung verwendet. Im Grunde ist dies der Teil des vorherigen Abschnitts, in dem wir die verkn\u00fcpften Builds behandelt haben.<\/p>\n<p>Dazu \u2013 ganz wie oben \u2013 erstellen wir die Cluster-Aufgabe webapp-build-runtime:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/webapp-build-runtime-task.yaml\n<\/code><\/pre>\n<p>\nWenn man den Code dieser Cluster-Aufgaben betrachtet, sieht man, dass dort nicht das Git-Repository spezifiziert wird, mit dem wir arbeiten, oder die Namen der Images, die wir erstellen. Wir geben nur an, was wir an Git \u00fcbergeben oder ein Image, in das das finale Image ausgegeben werden soll. Deshalb k\u00f6nnen diese Cluster-Aufgaben wiederverwendet werden, auch wenn wir mit anderen Anwendungen arbeiten.<\/p>\n<p>Und hier kommen wir elegant zum n\u00e4chsten Punkt\u2026<\/p>\n<h4>Ressourcen<\/h4>\n<p>\nAlso, da die Cluster-Aufgaben, wie wir gerade gesagt haben, so allgemein wie m\u00f6glich sein m\u00fcssen, m\u00fcssen wir Ressourcen erstellen, die als Eingabe (Git-Repository) und Ausgabe (Endbilder) verwendet werden. Die erste Ressource, die wir ben\u00f6tigen, ist Git, wo sich unsere Anwendung befindet, etwas wie das:<\/p>\n<pre><code class=\"plaintext\"># This resource is the location of the git repo with the web application source\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: web-application-repo\nspec:\n  type: git\n  params:\n    - name: url\n      value: https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\n    - name: revision\n      value: master\n<\/code><\/pre>\n<p>\nHier hat PipelineResource den Typ git. Der Schl\u00fcssel url im Abschnitt params verweist auf das spezifische Repository und legt den Branch master fest (das ist optional, aber wir geben ihn der Vollst\u00e4ndigkeit halber an).<\/p>\n<p>Jetzt m\u00fcssen wir eine Ressource f\u00fcr das Bild erstellen, in dem die Ergebnisse der Ausf\u00fchrung der Aufgabe s2i-web-app gespeichert werden. Das geschieht so:<\/p>\n<pre><code class=\"plaintext\"># This resource is the result of running &quot;npm run build&quot;,  the resulting built files will be located in \/opt\/app-root\/output\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: built-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/built-web-application:latest\n<\/code><\/pre>\n<p>\nHier hat PipelineResource den Typ image, und der Wert des Parameters url verweist auf das interne OpenShift Image Registry, konkret auf das, das sich im Namespace webapp-pipeline befindet. Vergessen Sie nicht, diesen Parameter zu \u00e4ndern, wenn Sie einen anderen Namespace verwenden.<\/p>\n<p>Und schlie\u00dflich wird die letzte Ressource, die wir ben\u00f6tigen, ebenfalls vom Typ image sein und es wird das endg\u00fcltige NGINX-Bild sein, das dann beim Deployment verwendet wird:<\/p>\n<pre><code class=\"plaintext\"># This resource is the image that will be just the static html, css, js files being run with nginx\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: runtime-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/runtime-web-application:latest\n<\/code><\/pre>\n<p>\nUnd wieder sei darauf hingewiesen, dass diese Ressource das Bild im internen OpenShift-Register im Namespace webapp-pipeline speichert.<\/p>\n<p>Um all diese Ressourcen gleichzeitig zu erstellen, verwenden wir den Befehl create:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/resources\/resource.yaml\n<\/code><\/pre>\n<p>\nSie k\u00f6nnen \u00fcberpr\u00fcfen, ob die Ressourcen erstellt wurden, indem Sie Folgendes eingeben:<\/p>\n<pre><code class=\"plaintext\">$ tkn resource ls\n<\/code><\/pre>\n<p><\/p>\n<h4>Pipeline<\/h4>\n<p>\nJetzt, wo wir alle notwendigen Komponenten haben, erstellen wir die Pipeline, indem wir den folgenden Befehl ausf\u00fchren:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/pipelines\/build-and-deploy-react.yaml\n<\/code><\/pre>\n<p>\nAber bevor wir diesen Befehl ausf\u00fchren, lassen Sie uns diese Komponenten analysieren. Die erste ist der Name:<\/p>\n<pre><code class=\"plaintext\">apiVersion: tekton.dev\/v1alpha1\nkind: Pipeline\nmetadata:\n  name: build-and-deploy-react\n<\/code><\/pre>\n<p>\nDann sehen wir im Abschnitt spec die Angabe der Ressourcen, die wir zuvor erstellt haben:<\/p>\n<pre><code class=\"plaintext\">spec:\n  resources:\n    - name: web-application-repo\n      type: git\n    - name: built-web-application-image\n      type: image\n    - name: runtime-web-application-image\n      type: image\n<\/code><\/pre>\n<p>\nDann erstellen wir die Aufgaben, die unser Pipeline ausf\u00fchren soll. Zuerst muss sie die bereits von uns erstellte Aufgabe s2i-web-app ausf\u00fchren:<\/p>\n<pre><code class=\"plaintext\">tasks:\n    - name: build-web-application\n      taskRef:\n        name: s2i-web-app\n        kind: ClusterTask\n<\/code><\/pre>\n<p>\nDiese Aufgabe nimmt die Eingangsparameter (git-Ressource) und die Ausgangsparameter (Ressource built-web-application-image). Wir \u00fcbergeben ihr auch einen speziellen Parameter, damit sie TLS nicht \u00fcberpr\u00fcft, da wir selbstsignierte Zertifikate verwenden:<\/p>\n<pre><code class=\"plaintext\">Ressourcen:\n        Eingaben:\n          - Name: Quelle\n            Ressource: web-application-repo\n        Ausgaben:\n          - Name: Bild\n            Ressource: built-web-application-image\n      Parameter:\n        - Name: TLSVERIFY\n          Wert: \"false\"\n<\/code><\/pre>\n<p>\nDie n\u00e4chste Aufgabe ist fast identisch, nur dass hier die bereits erstellte Clusteraufgabe webapp-build-runtime aufgerufen wird:<\/p>\n<pre><code class=\"plaintext\">Name: build-runtime-image\n    TaskRef:\n      Name: webapp-build-runtime\n      Art: ClusterTask\n<\/code><\/pre>\n<p>\nWie bei der vorherigen Aufgabe \u00fcbergeben wir eine Ressource, aber jetzt ist es das built-web-application-image (Ausgabe unserer vorherigen Aufgabe). Und erneut definieren wir als Ausgabe ein Bild. Da diese Aufgabe nach der vorherigen ausgef\u00fchrt werden muss, f\u00fcgen wir das Feld runAfter hinzu:<\/p>\n<pre><code class=\"plaintext\">Ressourcen:\n        Eingaben:\n          - Name: Bild\n            Ressource: built-web-application-image\n        Ausgaben:\n          - Name: Bild\n            Ressource: runtime-web-application-image\n        Parameter:\n        - Name: TLSVERIFY\n          Wert: \"false\"\n      runAfter:\n        - build-web-application\n<\/code><\/pre>\n<p>\nDie n\u00e4chsten beiden Aufgaben sind f\u00fcr die Anwendung der YAML-Dateien f\u00fcr den Dienst, die Route und das Deployment verantwortlich, die im k8s-Verzeichnis unserer Webanwendung leben, sowie f\u00fcr die Aktualisierung dieses Deployments bei der Erstellung neuer Bilder. Diese beiden Clusteraufgaben haben wir bereits zu Beginn des Artikels definiert.<\/p>\n<h4>Pipeline starten<\/h4>\n<p>\nAlso, alle Teile unseres Pipelines sind erstellt, und wir werden sie mit dem folgenden Befehl starten:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline start build-and-deploy-react\n<\/code><\/pre>\n<p>\nIn diesem Schritt wird die Befehlszeile im interaktiven Modus verwendet und man muss die entsprechenden Ressourcen als Antwort auf jede ihrer Anfragen ausw\u00e4hlen: F\u00fcr die Ressource git w\u00e4hlen wir web-application-repo, dann f\u00fcr die Ressource des ersten Bildes \u2013 built-web-application-image, und schlie\u00dflich f\u00fcr die Ressource des zweiten Bildes \u2013 runtime-web-application-image:<\/p>\n<pre><code class=\"plaintext\">? Choose the git resource to use for web-application-repo: web-application-repo (https:\/\/github.com\/nodeshift-starters\/react-pipeline-example)\n? 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-\napplication:latest)\n? 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\ne-web-application:latest)\nPipelinerun started: build-and-deploy-react-run-4xwsr\n<\/code><\/pre>\n<p>\nJetzt \u00fcberpr\u00fcfen wir den Status der Pipeline mit dem folgenden Befehl:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline logs -f\n<\/code><\/pre>\n<p>\nNachdem die Pipeline gestartet wurde und die Anwendung bereitgestellt ist, fordern wir die ver\u00f6ffentlichte Route mit dem folgenden Befehl an:<\/p>\n<pre><code class=\"plaintext\">$ oc get route react-pipeline-example --template='http:\/\/{{.spec.host}}'\n<\/code><\/pre>\n<p>\nF\u00fcr mehr Anschaulichkeit k\u00f6nnen wir unsere Pipeline im Entwickler-Modus der Web-Konsole im Abschnitt <b>Pipelines<\/b>, wie in Abb. 1 gezeigt.<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/ede9b076414e389c2cd212adeda08956.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Abb. 1. \u00dcbersicht \u00fcber die gestarteten Pipelines.<\/i><\/p>\n<p>Ein Klick auf die gestartete Pipeline zeigt zus\u00e4tzliche Informationen an, wie in Abb. 2 gezeigt.<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/64581b1f6d8ff91aedd963019ef29be5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Abb. 2. Zus\u00e4tzliche Informationen zur Pipeline.<\/i><\/p>\n<p>Nach den zus\u00e4tzlichen Informationen k\u00f6nnen die gestarteten Anwendungen im Sichtfeld <b>Topologie<\/b>, wie in Abb. 3 gezeigt.<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/d23f723e14514ff60ecfddd8eb9bf752.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Abb. 3. gestarteter Pod.<\/i><\/p>\n<p>Ein Klick auf den Kreis in der oberen rechten Ecke des Symbols \u00f6ffnet unsere Anwendung, wie in Abb. 4 gezeigt.<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/aa8e09d9fd9f33d5faffc7f661d84ca4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Abb. 4. gestartete React-Anwendung.<\/i><\/p>\n<h3>Fazit<\/h3>\n<p>\nWir haben gezeigt, wie man auf OpenShift einen Entwicklungsserver f\u00fcr seine Anwendung starten und ihn mit dem lokalen Dateisystem synchronisieren kann. Au\u00dferdem haben wir betrachtet, wie man eine chained-build-Vorlage mit OpenShift Pipelines simuliert. Alle Beispielcodes aus diesem Artikel sind zu finden <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">hier<\/a><\/noindex>.<\/p>\n<h3>Zus\u00e4tzliche Ressourcen (EN)<\/h3>\n<p><\/p>\n<ul>\n<li>Kostenloses E-Book <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\/\">\u201eEntwicklung auf OpenShift: ein Leitfaden f\u00fcr Ungeduldige\u201c<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/06\/11\/container-native-nodejs-istio-rhoar\/\">Erstellung von containerbasierten Node.js-Anwendungen mit Red Hat OpenShift Application Runtimes und Istio<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/05\/15\/debug-your-node-js-application-on-openshift-with-chrome-devtools\/\">Debugging von Node.js-Anwendungen auf OpenShift mit Chrome DevTools<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/04\/16\/zero-express-openshift-3-commands\/\">Drei Befehle, um Express auf OpenShift von Grund auf zu meistern<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/03\/12\/rhoar-nodejs-annoucement\/\">Ank\u00fcndigung der \u00f6ffentlichen Version von Node.js in Red Hat OpenShift Application Runtimes<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/12\/21\/monitoring-node-js-applications-on-openshift-with-prometheus\/\">\u00dcberwachung von Node.js-Anwendungen auf OpenShift mit Prometheus<\/a><\/noindex><\/li>\n<li>Weitere Artikel zu <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift und Kubernetes<\/a><\/noindex> auf der Red Hat-Website<\/li>\n<\/ul>\n<h3>Ank\u00fcndigungen bevorstehender Webinare<\/h3>\n<p>\nWir starten eine Reihe von Freitags-Webinaren \u00fcber die native Nutzung von Red Hat OpenShift Container Platform und Kubernetes:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232599abcd&amp;sc_cid=7013a000002gwqQAAQ\"><b>28. August, Webinar Imperator \u201eOperator\u201c: Operatoren in OpenShift und Kubernetes<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232694abcd&amp;sc_cid=7013a000002gwrdAAA\"><b>11. September, DeploymentConfig vs Deployment \u2013 OpenShift-spezifische magische Dinge zum Erstellen und Bereitstellen von Anwendungen<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232789abcd&amp;sc_cid=7013a000002gws7AAA\"><b>25. September, Red Hat OpenShift und Machine API<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232884abcd&amp;sc_cid=7013a000002gwsqAAA\"><b>9. Oktober, Wie man mit pl\u00f6tzlichem Anstieg der Last umgeht<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232979abcd&amp;sc_cid=7013a000002gwumAAA\"><b>23. Oktober, Integrierter Jenkins, Pipeline-Bauten, Tekton in Red Hat OpenShift Container Platform<\/b><\/a><\/noindex><\/li>\n<\/ul>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/515988\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435! \u0421 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Red Hat OpenShift. \u0412 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0433\u043e\u0432 \u0438 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 S2I \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c HTTP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, NGINX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043e\u043a chained [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92049,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92048","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-22T05:42:57+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-22T05:42:57+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Moderne Anwendungen auf OpenShift, Teil 3: OpenShift als Entwicklungsumgebung und OpenShift Pipelines | ProHoster","description":"Hallo zusammen in diesem Blog!","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-22T05:42:57+00:00","article:modified_time":"2020-08-22T05:42:57+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92048","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:16:43","updated":"2022-10-02 02:53:55","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/92048","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=92048"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/92048\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/92049"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=92048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=92048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=92048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}