{"id":90874,"date":"2020-08-07T01:42:20","date_gmt":"2020-08-06T23:42:20","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds"},"modified":"2020-08-07T01:42:20","modified_gmt":"2020-08-06T23:42:20","slug":"sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","title":{"rendered":"Moderne Anwendungen auf OpenShift, Teil 2: verbundene Builds chained builds","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo zusammen! Hier ist der zweite Beitrag aus unserer Reihe, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift implementiert. <\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: verbundene Builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/b1f6ae855a69597c6e86c5198e4a628c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIm vorherigen Beitrag haben wir die M\u00f6glichkeiten des neuen Builder-Images S2I (Source-to-Image) etwas angerissen, das f\u00fcr den Bau und die Bereitstellung moderner Webanwendungen auf der OpenShift-Plattform gedacht ist. Damals interessierte uns das Thema der schnellen Bereitstellung von Anwendungen, und heute werden wir untersuchen, wie man das S2I-Image als \"reines\" Builder-Image verwendet und es mit den zugeh\u00f6rigen Builds von OpenShift kombiniert.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Reines Builder-Image<\/h3>\n<p>\nWie wir im ersten Teil erw\u00e4hnt haben, haben die meisten modernen Webanwendungen eine sogenannte Build-Phase, in der normalerweise Operationen wie Code-Transpilierung, Zusammenf\u00fchren mehrerer Dateien und Minimierung durchgef\u00fchrt werden. Die Resultate dieser Operationen - also statisches HTML, JavaScript und CSS - werden in einen Output-Ordner abgelegt. Der Standort dieses Ordners h\u00e4ngt normalerweise von den verwendeten Build-Tools ab, und f\u00fcr React wird dies der Ordner .\\\/build sein (darauf werden wir sp\u00e4ter noch ausf\u00fchrlicher eingehen).<\/p>\n<h4>Source-to-Image (S2I)<\/h4>\n<p>\nIn diesem Beitrag werden wir das Thema \"Was ist S2I und wie verwendet man es\" nicht behandeln (dar\u00fcber kann man mehr lesen <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/architecture\/core_concepts\/builds_and_image_streams.html#source-build\">hier<\/a><\/noindex>), aber es ist wichtig, sich die beiden Phasen dieses Prozesses klar vor Augen zu f\u00fchren, um zu verstehen, was das Web App Builder-Image tats\u00e4chlich macht.<\/p>\n<h4>Assemble-Phase<\/h4>\n<p>\nDie Assemble-Phase \u00e4hnelt im Wesentlichen dem, was passiert, wenn Sie docker build ausf\u00fchren und im Ergebnis ein neues Docker-Image erhalten. Infolgedessen tritt diese Phase auf, wenn der Build auf der OpenShift-Plattform gestartet wird.<\/p>\n<p>Im Fall des Web App Builder-Images ist das Skript zum Installieren der Abh\u00e4ngigkeiten f\u00fcr Ihre Anwendung und zum Starten des Builds verantwortlich <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/assemble#L47\">assemble script<\/a><\/noindex>. Standardm\u00e4\u00dfig verwendet das Builder-Image den Befehl npm run build, aber dieser kann \u00fcber die Umgebungsvariable NPM_BUILD \u00fcberschrieben werden.<\/p>\n<p>Wie bereits erw\u00e4hnt, h\u00e4ngt der Speicherort der fertigen, bereits erstellten Anwendung davon ab, welche Werkzeuge verwendet werden. Bei React w\u00e4re dies zum Beispiel der Ordner \/build, w\u00e4hrend es bei Angular-Anwendungen der Ordner project_name\/dist ist. Und wie bereits im letzten Beitrag gezeigt, kann der Speicherort des Output-Verzeichnisses, das standardm\u00e4\u00dfig als build festgelegt ist, \u00fcber die Umgebungsvariable OUTPUT_DIR \u00fcberschrieben werden. Da der Speicherort des Output-Ordners von Framework zu Framework variiert, kopieren Sie einfach das generierte Output in den Standardordner im Image, n\u00e4mlich \/opt\/apt-root\/output. Das ist wichtig f\u00fcr das Verst\u00e4ndnis des n\u00e4chsten Teils dieses Artikels; lassen Sie uns nun schnell den n\u00e4chsten Schritt \u2013 die Ausf\u00fchrungsphase (run phase) \u2013 betrachten.<\/p>\n<h4>Ausf\u00fchrungsphase (run phase)<\/h4>\n<p>\nDiese Phase tritt auf, wenn das neu erstellte Image aus der Assembly-Phase mit docker run aufgerufen wird. Sie tritt auch bei der Durchf\u00fchrung von Deployments auf der OpenShift-Plattform auf. Standardm\u00e4\u00dfig <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/run\">Ausf\u00fchrungsskript<\/a><\/noindex> verwendet <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/package\/serve\">Modul bereitstellen<\/a><\/noindex> um statische Inhalte bereitzustellen, die im oben genannten Standardausgabe-Verzeichnis liegen.<\/p>\n<p>Diese Methode eignet sich gut f\u00fcr das schnelle Deployment von Anwendungen, jedoch wird im Allgemeinen nicht empfohlen, statische Inhalte auf diese Weise bereitzustellen. Da wir jedoch tats\u00e4chlich nur statische Inhalte bereitstellen, ist Node.js, das in unserem Image installiert ist, nicht notwendig \u2013 ein Web-Server reicht aus.<\/p>\n<p>Mit anderen Worten, beim Build ben\u00f6tigen wir etwas anderes als w\u00e4hrend der Ausf\u00fchrung. In dieser Situation sind verkn\u00fcpfte Builds (chained builds) n\u00fctzlich.<\/p>\n<h3>Verkn\u00fcpfte Builds (chained builds)<\/h3>\n<p>\nDas steht in der Dokumentation von <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/builds\/advanced_build_operations.html#dev-guide-chaining-builds\">chained builds<\/a><\/noindex> :<\/p>\n<blockquote><p>\u201eZwei Builds k\u00f6nnen miteinander verkn\u00fcpft werden, wobei einer von ihnen eine kompilierte Entit\u00e4t erzeugt und der andere diese Entit\u00e4t in einem separaten Image platziert, das verwendet wird, um diese Entit\u00e4t auszuf\u00fchren.\u201c\n<\/p><\/blockquote>\n<p>\nAnders ausgedr\u00fcckt, wir k\u00f6nnen das Image des Web App Builders verwenden, um unseren Build auszuf\u00fchren, und dann das Image eines Web-Servers, wie NGINX, um unsere Inhalte bereitzustellen.<\/p>\n<p>Auf diese Weise k\u00f6nnen wir das Image des Web App Builders als \u201ereinen\u201c Builder verwenden und gleichzeitig ein kleines Runtime-Image haben.<\/p>\n<p>Lassen Sie uns nun ein konkretes Beispiel betrachten.<\/p>\n<p>F\u00fcr die \u00dcbung verwenden wir <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">eine einfache React-Anwendung<\/a><\/noindex>, die mit dem Befehlszeilenwerkzeug create-react-app erstellt wurde.<\/p>\n<p>Um alles zusammenzufassen, hilft uns <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml\">die OpenShift-Vorlagendatei.<\/a><\/noindex>.<\/p>\n<p>Lassen Sie uns diese Datei genauer ansehen, und beginnen wir mit dem Abschnitt Parameter.<\/p>\n<pre><code class=\"plaintext\">parameter:\n  - name: SOURCE_REPOSITORY_URL\n    description: Die Quell-URL f\u00fcr die Anwendung\n    displayName: Quell-URL\n    required: true\n  - name: SOURCE_REPOSITORY_REF\n    description: Der Branch-Name f\u00fcr die Anwendung\n    displayName: Quell-Branch\n    value: master\n    required: true\n  - name: SOURCE_REPOSITORY_DIR\n    description: Der Speicherort innerhalb des Quell-Repositorys der Anwendung\n    displayName: Quellverzeichnis\n    value: .\n    required: true\n  - name: OUTPUT_DIR\n    description: Der Speicherort der kompilierten statischen Dateien von Ihrem Webanwendungs-Builder\n    displayName: Ausgabeverzeichnis\n    value: build\n    required: false\n<\/code><\/pre>\n<p>\nHier ist alles recht klar, aber man sollte auf den Parameter OUTPUT_DIR achten. F\u00fcr die React-Anwendung aus unserem Beispiel gibt es keinen Grund zur Sorge, da React den Standardwert f\u00fcr das Ausgabeverzeichnis verwendet. Im Fall von Angular oder etwas anderem muss dieser Parameter jedoch entsprechend ge\u00e4ndert werden.<\/p>\n<p>Jetzt schauen wir uns den Abschnitt der ImageStreams an.<\/p>\n<pre><code class=\"plaintext\">- apiVersion: v1\n  kind: ImageStream\n  metadata:\n    name: react-web-app-builder  \/\/\/ 1 \n  spec: {}\n- apiVersion: v1\n  kind: ImageStream\n  metadata:\n    name: react-web-app-runtime  \/\/\/ 2 \n  spec: {}\n- apiVersion: v1\n  kind: ImageStream\n  metadata:\n    name: web-app-builder-runtime \/\/\/ 3\n  spec:\n    tags:\n    - name: latest\n      from:\n        kind: DockerImage\n        name: nodeshift\/ubi8-s2i-web-app:10.x\n- apiVersion: v1\n  kind: ImageStream\n  metadata:\n    name: nginx-image-runtime \/\/\/ 4\n  spec:\n    tags:\n    - name: latest\n      from:\n        kind: DockerImage\n        name: 'centos\/nginx-112-centos7:latest'\n<\/code><\/pre>\n<p>\nSchauen Sie sich das dritte und vierte Bild an. Beide sind als Docker-Images definiert, und man sieht deutlich, woher sie stammen.<\/p>\n<p>Das dritte Bild ist das web-app-builder und es stammt von nodeshift\/ubi8-s2i-web-app mit dem Tag 10.x auf <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/nodeshift\/ubi8-s2i-web-app\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<p>Das vierte ist das NGINX-Image (Version 1.12) mit dem Tag latest auf <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/nginx-112-centos7\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<p>Jetzt sehen wir uns die ersten beiden Bilder an. Beide sind zu Beginn leer und werden nur w\u00e4hrend der Build-Phase erstellt. Das erste Bild \u2013 react-web-app-builder \u2013 wird das Ergebnis der Assemblierungsphase sein, die das Bild web-app-builder-runtime und unseren Quellcode kombiniert. Deshalb haben wir \u201e-builder\u201c im Namen dieses Bildes hinzugef\u00fcgt.<\/p>\n<p>Das zweite Bild \u2013 react-web-app-runtime \u2013 wird das Ergebnis der Kombination von nginx-image-runtime und einigen Dateien aus dem Bild react-web-app-builder sein. Dieses Bild wird ebenfalls beim Deployment verwendet und enth\u00e4lt nur den Webserver sowie das statische HTML, JavaScript und CSS unserer Anwendung.<\/p>\n<p>Verwirrend? Schauen wir uns jetzt die Build-Konfigurationen an, und es wird etwas klarer.<\/p>\n<p>In unserer Vorlage gibt es zwei Build-Konfigurationen. Hier ist die erste davon, und sie ist ziemlich standardm\u00e4\u00dfig:<\/p>\n<pre><code class=\"plaintext\">  apiVersion: v1\n  kind: BuildConfig\n  metadata:\n    name: react-web-app-builder\n  spec:\n    output:\n      to:\n        kind: ImageStreamTag\n        name: react-web-app-builder:latest \\\/\\\/ 1\n    source:   \\\/\\\/ 2 \n      git:\n        uri: ${SOURCE_REPOSITORY_URL}\n        ref: ${SOURCE_REPOSITORY_REF}\n      contextDir: ${SOURCE_REPOSITORY_DIR}\n      type: Git\n    strategy:\n      sourceStrategy:\n        env:\n          - name: OUTPUT_DIR \\\/\\\/ 3 \n            value: ${OUTPUT_DIR}\n        from:\n          kind: ImageStreamTag\n          name: web-app-builder-runtime:latest \\\/\\\/ 4\n        incremental: true \\\/\\\/ 5\n      type: Source\n    triggers: \\\/\\\/ 6\n    - github:\n        secret: ${GITHUB_WEBHOOK_SECRET}\n      type: GitHub\n    - type: ConfigChange\n    - imageChange: {}\n      type: ImageChange\n<\/code><\/pre>\n<p>\nWie wir sehen, besagt die Zeile mit dem Etikett 1, dass das Ergebnis dieses Builds in das Bild react-web-app-builder gelegt wird, das wir zuvor im Abschnitt \u00fcber die ImageStreams gesehen haben.<\/p>\n<p>Die Zeile mit dem Etikett 2 beschreibt, von wo der Code bezogen wird. In unserem Fall handelt es sich um ein Git-Repository, und der Standort, der Ref und das Kontextverzeichnis sind durch die Parameter definiert, die wir oben bereits gesehen haben.<\/p>\n<p>Die Zeile mit dem Etikett 3 \u2013 das haben wir bereits im Abschnitt \u00fcber die Parameter gesehen. Sie f\u00fcgt die Umgebungsvariable OUTPUT_DIR hinzu, die in unserem Beispiel build entspricht.<br \/>\nDie Zeile mit dem Etikett 4 sagt, dass das Bild web-app-builder-runtime verwendet werden soll, das wir bereits im Abschnitt \u00fcber die ImageStreams gesehen haben.<\/p>\n<p>Die Zeile mit dem Etikett 5 besagt, dass wir einen inkrementellen Build verwenden m\u00f6chten, sofern das S2I-Image dies unterst\u00fctzt, was beim Web App Builder der Fall ist. Bei der ersten Ausf\u00fchrung, nach Abschluss der Zusammenbauphase, speichert das Bild den Ordner node_modules in einer Archivdatei. Bei nachfolgenden Ausf\u00fchrungen wird das Bild einfach diesen Ordner entpacken, um die Build-Dauer zu verk\u00fcrzen.<\/p>\n<p>Und schlie\u00dflich dient die Zeile mit dem Etikett 6 lediglich dazu, einige Trigger bereitzustellen, damit der Build automatisch gestartet wird, ohne manuelles Eingreifen, wenn sich etwas \u00e4ndert.<\/p>\n<p>Insgesamt handelt es sich um eine recht Standard-Build-Konfiguration.<\/p>\n<p>Lassen Sie uns nun einen Blick auf die zweite Build-Konfiguration werfen. Diese \u00e4hnelt der ersten sehr, weist jedoch eine wichtige Abweichung auf.<\/p>\n<pre><code class=\"plaintext\">apiVersion: v1\n  kind: BuildConfig\n  metadata:\n    name: react-web-app-runtime\n  spec:\n    output:\n      to:\n        kind: ImageStreamTag\n        name: react-web-app-runtime:latest \\\/\\\/ 1\n    source: \\\/\\\/ 2\n      type: Image\n      images:                              \n        - from:\n            kind: ImageStreamTag\n            name: react-web-app-builder:latest \\\/\\\/ 3\n          paths:\n            - sourcePath: \\\/opt\\\/app-root\\\/output\\\/.  \\\/\\\/ 4\n              destinationDir: .  \\\/\\\/ 5\n             \n    strategy: \\\/\\\/ 6\n      sourceStrategy:\n        from:\n          kind: ImageStreamTag\n          name: nginx-image-runtime:latest\n        incremental: true\n      type: Source\n    triggers:\n    - github:\n        secret: ${GITHUB_WEBHOOK_SECRET}\n      type: GitHub\n    - type: ConfigChange\n    - type: ImageChange\n      imageChange: {}\n    - type: ImageChange\n      imageChange:\n        from:\n          kind: ImageStreamTag\n          name: react-web-app-builder:latest \\\/\\\/ 7\n<\/code><\/pre>\n<p>\nAlso, die zweite Build-Konfiguration \u2013 react-web-app-runtime, und sie beginnt ganz standardm\u00e4\u00dfig.<\/p>\n<p>In der Zeile mit dem Label 1 gibt es nichts Neues \u2013 sie besagt einfach, dass das Build-Ergebnis in das Image react-web-app-runtime gelegt wird.<\/p>\n<p>Die Zeile mit dem Label 2, wie in der vorherigen Konfiguration, gibt an, wo der Quellcode hergenommen wird. Aber beachten Sie, dass wir hier sagen, dass er aus dem Image kommt. Und zwar aus dem Image, das wir gerade erstellt haben \u2013 aus react-web-app-builder (in der Zeile mit dem Label 3 angegeben). Die Dateien, die wir verwenden m\u00f6chten, befinden sich im Image und ihr Speicherort dort wird in der Zeile mit dem Label 4 festgelegt, in unserem Fall ist es \/opt\/app-root\/output\/. Wenn Sie sich erinnern, genau dorthin werden die Dateien gelegt, die durch das Build unseres Programms generiert werden.<\/p>\n<p>Das Zielverzeichnis, das in der Zeile mit dem Label 5 angegeben ist \u2013 ist einfach das aktuelle Verzeichnis (das alles, erinnern wir uns, l\u00e4uft in einem magischen Ding namens OpenShift, nicht auf Ihrem lokalen Computer).<\/p>\n<p>Der Abschnitt strategy \u2013 die Zeile mit dem Label 6 \u2013 \u00e4hnelt ebenfalls der ersten Build-Konfiguration. Nur dieses Mal werden wir das nginx-image-runtime verwenden, das wir im Abschnitt ImageStream bereits gesehen haben.<\/p>\n<p>Schlie\u00dflich ist die Zeile mit dem Label 7 der Bereich der Trigger, der diesen Build jedes Mal aktiviert, wenn sich das Image react-web-app-builder \u00e4ndert.<\/p>\n<p>Abgesehen davon enth\u00e4lt diese Vorlage eine ganz standardm\u00e4\u00dfige Bereitstellungskonfiguration sowie Dinge, die mit den Diensten und Routen zu tun haben, aber darauf werden wir nicht n\u00e4her eingehen. Beachten Sie, dass das Image, das bereitgestellt wird \u2013 das Image react-web-app-runtime ist.<\/p>\n<h3>Anwendungsbereitstellung<\/h3>\n<p>\nAlso, nachdem wir einen Blick auf die Vorlage geworfen haben, lassen Sie uns sehen, wie wir sie zur Bereitstellung der Anwendung nutzen k\u00f6nnen.<\/p>\n<p>Wir k\u00f6nnen das OpenShift-Client-Tool namens oc verwenden, um unsere Vorlage bereitzustellen:<\/p>\n<pre><code class=\"plaintext\">$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f\n\n$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https:\/\/github.com\/lholmquist\/react-web-app\n<\/code><\/pre>\n<p>\nDer erste Befehl auf dem Screenshot oben ist eine absichtlich technische Art, die Vorlage \/openshiftio\/application.yaml zu finden.<\/p>\n<p>Der zweite Befehl erstellt einfach eine neue Anwendung basierend auf dieser Vorlage.<\/p>\n<p>Nachdem diese Befehle ausgef\u00fchrt wurden, werden wir sehen, dass wir zwei Builds haben:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: verbundene Builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/c6b2b2fcadfcd3e5a8a2adb4eff69bf2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Und wenn wir zum Bildschirm \u00dcbersicht zur\u00fcckkehren, sehen wir den laufenden Pod:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: verbundene Builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/983fab3029d222555dc13790d4a3e70f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Ein Klick auf den Link \u2013 und wir gelangen zu unserer Anwendung, die eine Standard-React-App-Seite darstellt:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: verbundene Builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/d5b658875e0e865bf456955aaac15464.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Erg\u00e4nzung 1<\/h3>\n<p>\nF\u00fcr Angular-Liebhaber haben wir auch <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/angular-web-app\">ein Anwendungsbeispiel<\/a><\/noindex>.<\/p>\n<p>Die Vorlage hier ist die gleiche, mit der Ausnahme der Variablen OUTPUT_DIR.<\/p>\n<h3>Erg\u00e4nzung 2<\/h3>\n<p>\nIn diesem Artikel haben wir NGINX als Webserver verwendet, aber es ist ganz einfach, ihn durch Apache zu ersetzen, indem Sie einfach die Vorlagendatei \u00e4ndern. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml#L66\">NGINX-Image<\/a><\/noindex> auf <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/httpd-24-centos7\/\">Apache-Image<\/a><\/noindex>.<\/p>\n<h3>Fazit<\/h3>\n<p>\nIm ersten Teil dieser Reihe haben wir gezeigt, wie moderne Webanwendungen schnell auf der OpenShift-Plattform bereitgestellt werden k\u00f6nnen. Heute haben wir betrachtet, was das Web App-Image tut und wie es mit einem reinen Webserver wie NGINX durch verkettete Builds kombiniert werden kann, um eine besser f\u00fcr Produktionsbedingungen geeignete Anwendungserstellung zu organisieren. Im n\u00e4chsten abschlie\u00dfenden Artikel dieser Reihe zeigen wir, wie Sie auf OpenShift einen Entwicklungsserver f\u00fcr Ihre Anwendung starten und die Synchronisierung zwischen lokalen und entfernten Dateien sicherstellen k\u00f6nnen.<\/p>\n<h3>Inhalt dieser Artikelreihe<\/h3>\n<p><\/p>\n<ul>\n<li>Teil 1: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">wie man moderne Webanwendungen in nur wenigen Schritten bereitstellt<\/a><\/noindex>;<\/li>\n<li>Teil 2: wie man das neue S2I-Image zusammen mit dem bereits vorhandenen HTTP-Server-Image, wie z.B. NGINX, anwendet, indem man OpenShift-verkettete Builds f\u00fcr die Organisation des Produktions-Deployments verwendet;<\/li>\n<li>Teil 3: wie man auf der OpenShift-Plattform einen Entwicklungsserver f\u00fcr seine Anwendung startet und ihn mit dem lokalen Dateisystem synchronisiert.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Zus\u00e4tzliche Ressourcen<\/h3>\n<p><\/p>\n<ul>\n<li>Kostenloses E-Book <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\">Deployment auf OpenShift<\/a><\/noindex>.<\/li>\n<li>Informationen zu <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift und Kubernetes<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/513948\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \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 \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0441\u043b\u0435\u0433\u043a\u0430 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u043e\u0432\u043e\u0433\u043e builder-\u043e\u0431\u0440\u0430\u0437\u0430 S2I (source-to-image), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 OpenShift. \u0422\u043e\u0433\u0434\u0430 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b\u0430 \u0442\u0435\u043c\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":90875,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-90874","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=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \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 \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" \/>\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-2-svyazannye-sborki-chained-builds\" \/>\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 2: \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 chained builds | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \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 \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds\" \/>\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-06T23:42:20+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-06T23:42:20+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 2: verkettete Builds | ProHoster","description":"Hallo zusammen! Hier ist der zweite Beitrag aus unserer Reihe, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift implementiert.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","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 2: \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 chained builds | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \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 \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","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-06T23:42:20+00:00","article:modified_time":"2020-08-06T23:42:20+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"90874","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:40:03","updated":"2022-10-04 00:42:31","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\/90874","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=90874"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90874\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/90875"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=90874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=90874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=90874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}