Hallo zusammen! Hier ist der zweite Beitrag aus unserer Reihe, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift implementiert.

Im vorherigen Beitrag haben wir die Möglichkeiten des neuen Builder-Images S2I (Source-to-Image) etwas angerissen, das fĂŒr 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örigen Builds von OpenShift kombiniert.
Reines Builder-Image
Wie wir im ersten Teil erwĂ€hnt haben, haben die meisten modernen Webanwendungen eine sogenannte Build-Phase, in der normalerweise Operationen wie Code-Transpilierung, ZusammenfĂŒhren mehrerer Dateien und Minimierung durchgefĂŒhrt werden. Die Resultate dieser Operationen - also statisches HTML, JavaScript und CSS - werden in einen Output-Ordner abgelegt. Der Standort dieses Ordners hĂ€ngt normalerweise von den verwendeten Build-Tools ab, und fĂŒr React wird dies der Ordner .\/build sein (darauf werden wir spĂ€ter noch ausfĂŒhrlicher eingehen).
Source-to-Image (S2I)
In diesem Beitrag werden wir das Thema "Was ist S2I und wie verwendet man es" nicht behandeln (darĂŒber kann man mehr lesen ), aber es ist wichtig, sich die beiden Phasen dieses Prozesses klar vor Augen zu fĂŒhren, um zu verstehen, was das Web App Builder-Image tatsĂ€chlich macht.
Assemble-Phase
Die Assemble-Phase Ă€hnelt im Wesentlichen dem, was passiert, wenn Sie docker build ausfĂŒhren und im Ergebnis ein neues Docker-Image erhalten. Infolgedessen tritt diese Phase auf, wenn der Build auf der OpenShift-Plattform gestartet wird.
Im Fall des Web App Builder-Images ist das Skript zum Installieren der AbhĂ€ngigkeiten fĂŒr Ihre Anwendung und zum Starten des Builds verantwortlich . StandardmĂ€Ăig verwendet das Builder-Image den Befehl npm run build, aber dieser kann ĂŒber die Umgebungsvariable NPM_BUILD ĂŒberschrieben werden.
Wie bereits erwĂ€hnt, hĂ€ngt der Speicherort der fertigen, bereits erstellten Anwendung davon ab, welche Werkzeuge verwendet werden. Bei React wĂ€re dies zum Beispiel der Ordner /build, wĂ€hrend 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Ă€Ăig als build festgelegt ist, ĂŒber die Umgebungsvariable OUTPUT_DIR ĂŒberschrieben werden. Da der Speicherort des Output-Ordners von Framework zu Framework variiert, kopieren Sie einfach das generierte Output in den Standardordner im Image, nĂ€mlich /opt/apt-root/output. Das ist wichtig fĂŒr das VerstĂ€ndnis des nĂ€chsten Teils dieses Artikels; lassen Sie uns nun schnell den nĂ€chsten Schritt â die AusfĂŒhrungsphase (run phase) â betrachten.
AusfĂŒhrungsphase (run phase)
Diese Phase tritt auf, wenn das neu erstellte Image aus der Assembly-Phase mit docker run aufgerufen wird. Sie tritt auch bei der DurchfĂŒhrung von Deployments auf der OpenShift-Plattform auf. StandardmĂ€Ăig verwendet um statische Inhalte bereitzustellen, die im oben genannten Standardausgabe-Verzeichnis liegen.
Diese Methode eignet sich gut fĂŒr das schnelle Deployment von Anwendungen, jedoch wird im Allgemeinen nicht empfohlen, statische Inhalte auf diese Weise bereitzustellen. Da wir jedoch tatsĂ€chlich nur statische Inhalte bereitstellen, ist Node.js, das in unserem Image installiert ist, nicht notwendig â ein Web-Server reicht aus.
Mit anderen Worten, beim Build benötigen wir etwas anderes als wĂ€hrend der AusfĂŒhrung. In dieser Situation sind verknĂŒpfte Builds (chained builds) nĂŒtzlich.
VerknĂŒpfte Builds (chained builds)
Das steht in der Dokumentation von :
âZwei Builds können miteinander verknĂŒpft werden, wobei einer von ihnen eine kompilierte EntitĂ€t erzeugt und der andere diese EntitĂ€t in einem separaten Image platziert, das verwendet wird, um diese EntitĂ€t auszufĂŒhren.â
Anders ausgedrĂŒckt, wir können das Image des Web App Builders verwenden, um unseren Build auszufĂŒhren, und dann das Image eines Web-Servers, wie NGINX, um unsere Inhalte bereitzustellen.
Auf diese Weise können wir das Image des Web App Builders als âreinenâ Builder verwenden und gleichzeitig ein kleines Runtime-Image haben.
Lassen Sie uns nun ein konkretes Beispiel betrachten.
FĂŒr die Ăbung verwenden wir , die mit dem Befehlszeilenwerkzeug create-react-app erstellt wurde.
Um alles zusammenzufassen, hilft uns .
Lassen Sie uns diese Datei genauer ansehen, und beginnen wir mit dem Abschnitt Parameter.
parameter:
- name: SOURCE_REPOSITORY_URL
description: Die Quell-URL fĂŒr die Anwendung
displayName: Quell-URL
required: true
- name: SOURCE_REPOSITORY_REF
description: Der Branch-Name fĂŒr die Anwendung
displayName: Quell-Branch
value: master
required: true
- name: SOURCE_REPOSITORY_DIR
description: Der Speicherort innerhalb des Quell-Repositorys der Anwendung
displayName: Quellverzeichnis
value: .
required: true
- name: OUTPUT_DIR
description: Der Speicherort der kompilierten statischen Dateien von Ihrem Webanwendungs-Builder
displayName: Ausgabeverzeichnis
value: build
required: false
Hier ist alles recht klar, aber man sollte auf den Parameter OUTPUT_DIR achten. FĂŒr die React-Anwendung aus unserem Beispiel gibt es keinen Grund zur Sorge, da React den Standardwert fĂŒr das Ausgabeverzeichnis verwendet. Im Fall von Angular oder etwas anderem muss dieser Parameter jedoch entsprechend geĂ€ndert werden.
Jetzt schauen wir uns den Abschnitt der ImageStreams an.
- apiVersion: v1
kind: ImageStream
metadata:
name: react-web-app-builder /// 1
spec: {}
- apiVersion: v1
kind: ImageStream
metadata:
name: react-web-app-runtime /// 2
spec: {}
- apiVersion: v1
kind: ImageStream
metadata:
name: web-app-builder-runtime /// 3
spec:
tags:
- name: latest
from:
kind: DockerImage
name: nodeshift/ubi8-s2i-web-app:10.x
- apiVersion: v1
kind: ImageStream
metadata:
name: nginx-image-runtime /// 4
spec:
tags:
- name: latest
from:
kind: DockerImage
name: 'centos/nginx-112-centos7:latest'
Schauen Sie sich das dritte und vierte Bild an. Beide sind als Docker-Images definiert, und man sieht deutlich, woher sie stammen.
Das dritte Bild ist das web-app-builder und es stammt von nodeshift/ubi8-s2i-web-app mit dem Tag 10.x auf .
Das vierte ist das NGINX-Image (Version 1.12) mit dem Tag latest auf .
Jetzt sehen wir uns die ersten beiden Bilder an. Beide sind zu Beginn leer und werden nur wĂ€hrend der Build-Phase erstellt. Das erste Bild â react-web-app-builder â wird das Ergebnis der Assemblierungsphase sein, die das Bild web-app-builder-runtime und unseren Quellcode kombiniert. Deshalb haben wir â-builderâ im Namen dieses Bildes hinzugefĂŒgt.
Das zweite Bild â react-web-app-runtime â 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Ă€lt nur den Webserver sowie das statische HTML, JavaScript und CSS unserer Anwendung.
Verwirrend? Schauen wir uns jetzt die Build-Konfigurationen an, und es wird etwas klarer.
In unserer Vorlage gibt es zwei Build-Konfigurationen. Hier ist die erste davon, und sie ist ziemlich standardmĂ€Ăig:
apiVersion: v1
kind: BuildConfig
metadata:
name: react-web-app-builder
spec:
output:
to:
kind: ImageStreamTag
name: react-web-app-builder:latest \/\/ 1
source: \/\/ 2
git:
uri: ${SOURCE_REPOSITORY_URL}
ref: ${SOURCE_REPOSITORY_REF}
contextDir: ${SOURCE_REPOSITORY_DIR}
type: Git
strategy:
sourceStrategy:
env:
- name: OUTPUT_DIR \/\/ 3
value: ${OUTPUT_DIR}
from:
kind: ImageStreamTag
name: web-app-builder-runtime:latest \/\/ 4
incremental: true \/\/ 5
type: Source
triggers: \/\/ 6
- github:
secret: ${GITHUB_WEBHOOK_SECRET}
type: GitHub
- type: ConfigChange
- imageChange: {}
type: ImageChange
Wie 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 ĂŒber die ImageStreams gesehen haben.
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.
Die Zeile mit dem Etikett 3 â das haben wir bereits im Abschnitt ĂŒber die Parameter gesehen. Sie fĂŒgt die Umgebungsvariable OUTPUT_DIR hinzu, die in unserem Beispiel build entspricht.
Die Zeile mit dem Etikett 4 sagt, dass das Bild web-app-builder-runtime verwendet werden soll, das wir bereits im Abschnitt ĂŒber die ImageStreams gesehen haben.
Die Zeile mit dem Etikett 5 besagt, dass wir einen inkrementellen Build verwenden möchten, sofern das S2I-Image dies unterstĂŒtzt, was beim Web App Builder der Fall ist. Bei der ersten AusfĂŒhrung, nach Abschluss der Zusammenbauphase, speichert das Bild den Ordner node_modules in einer Archivdatei. Bei nachfolgenden AusfĂŒhrungen wird das Bild einfach diesen Ordner entpacken, um die Build-Dauer zu verkĂŒrzen.
Und schlieĂlich dient die Zeile mit dem Etikett 6 lediglich dazu, einige Trigger bereitzustellen, damit der Build automatisch gestartet wird, ohne manuelles Eingreifen, wenn sich etwas Ă€ndert.
Insgesamt handelt es sich um eine recht Standard-Build-Konfiguration.
Lassen Sie uns nun einen Blick auf die zweite Build-Konfiguration werfen. Diese Àhnelt der ersten sehr, weist jedoch eine wichtige Abweichung auf.
apiVersion: v1
kind: BuildConfig
metadata:
name: react-web-app-runtime
spec:
output:
to:
kind: ImageStreamTag
name: react-web-app-runtime:latest \/\/ 1
source: \/\/ 2
type: Image
images:
- from:
kind: ImageStreamTag
name: react-web-app-builder:latest \/\/ 3
paths:
- sourcePath: \/opt\/app-root\/output\/. \/\/ 4
destinationDir: . \/\/ 5
strategy: \/\/ 6
sourceStrategy:
from:
kind: ImageStreamTag
name: nginx-image-runtime:latest
incremental: true
type: Source
triggers:
- github:
secret: ${GITHUB_WEBHOOK_SECRET}
type: GitHub
- type: ConfigChange
- type: ImageChange
imageChange: {}
- type: ImageChange
imageChange:
from:
kind: ImageStreamTag
name: react-web-app-builder:latest \/\/ 7
Also, die zweite Build-Konfiguration â react-web-app-runtime, und sie beginnt ganz standardmĂ€Ăig.
In der Zeile mit dem Label 1 gibt es nichts Neues â sie besagt einfach, dass das Build-Ergebnis in das Image react-web-app-runtime gelegt wird.
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 â aus react-web-app-builder (in der Zeile mit dem Label 3 angegeben). Die Dateien, die wir verwenden möchten, 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.
Das Zielverzeichnis, das in der Zeile mit dem Label 5 angegeben ist â ist einfach das aktuelle Verzeichnis (das alles, erinnern wir uns, lĂ€uft in einem magischen Ding namens OpenShift, nicht auf Ihrem lokalen Computer).
Der Abschnitt strategy â die Zeile mit dem Label 6 â Ă€hnelt ebenfalls der ersten Build-Konfiguration. Nur dieses Mal werden wir das nginx-image-runtime verwenden, das wir im Abschnitt ImageStream bereits gesehen haben.
SchlieĂlich 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 Ă€ndert.
Abgesehen davon enthĂ€lt diese Vorlage eine ganz standardmĂ€Ăige Bereitstellungskonfiguration sowie Dinge, die mit den Diensten und Routen zu tun haben, aber darauf werden wir nicht nĂ€her eingehen. Beachten Sie, dass das Image, das bereitgestellt wird â das Image react-web-app-runtime ist.
Anwendungsbereitstellung
Also, nachdem wir einen Blick auf die Vorlage geworfen haben, lassen Sie uns sehen, wie wir sie zur Bereitstellung der Anwendung nutzen können.
Wir können das OpenShift-Client-Tool namens oc verwenden, um unsere Vorlage bereitzustellen:
$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f
$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https://github.com/lholmquist/react-web-app
Der erste Befehl auf dem Screenshot oben ist eine absichtlich technische Art, die Vorlage /openshiftio/application.yaml zu finden.
Der zweite Befehl erstellt einfach eine neue Anwendung basierend auf dieser Vorlage.
Nachdem diese Befehle ausgefĂŒhrt wurden, werden wir sehen, dass wir zwei Builds haben:

Und wenn wir zum Bildschirm Ăbersicht zurĂŒckkehren, sehen wir den laufenden Pod:

Ein Klick auf den Link â und wir gelangen zu unserer Anwendung, die eine Standard-React-App-Seite darstellt:

ErgÀnzung 1
FĂŒr Angular-Liebhaber haben wir auch .
Die Vorlage hier ist die gleiche, mit der Ausnahme der Variablen OUTPUT_DIR.
ErgÀnzung 2
In diesem Artikel haben wir NGINX als Webserver verwendet, aber es ist ganz einfach, ihn durch Apache zu ersetzen, indem Sie einfach die Vorlagendatei Àndern. auf .
Fazit
Im ersten Teil dieser Reihe haben wir gezeigt, wie moderne Webanwendungen schnell auf der OpenShift-Plattform bereitgestellt werden können. 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ĂŒr Produktionsbedingungen geeignete Anwendungserstellung zu organisieren. Im nĂ€chsten abschlieĂenden Artikel dieser Reihe zeigen wir, wie Sie auf OpenShift einen Entwicklungsserver fĂŒr Ihre Anwendung starten und die Synchronisierung zwischen lokalen und entfernten Dateien sicherstellen können.
Inhalt dieser Artikelreihe
- Teil 1: ;
- 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ĂŒr die Organisation des Produktions-Deployments verwendet;
- Teil 3: wie man auf der OpenShift-Plattform einen Entwicklungsserver fĂŒr seine Anwendung startet und ihn mit dem lokalen Dateisystem synchronisiert.
ZusÀtzliche Ressourcen
- Kostenloses E-Book .
- Informationen zu .
Quelle: habr.com
