Hallo zusammen! Willkommen zum zweiten Beitrag unserer Reihe, die zeigt, wie Sie moderne Webanwendungen auf Red Hat OpenShift bereitstellen.

Im vorherigen Beitrag haben wir kurz die Funktionen des neuen S2I-Builder-Images (Source-to-Image) angesprochen, das zum Erstellen und Bereitstellen moderner Webanwendungen auf der OpenShift-Plattform entwickelt wurde. Damals interessierte uns das Thema Rapid Application Deployment und heute schauen wir uns an, wie man das S2I-Image als „sauberes“ Builder-Image nutzt und mit verwandten OpenShift-Builds kombiniert.
Sauberes Builder-Bild
Wie wir im ersten Teil erwähnt haben, verfügen die meisten modernen Webanwendungen über eine sogenannte Build-Phase, in der normalerweise Vorgänge wie Code-Transpilierung, Verkettung mehrerer Dateien und Minimierung durchgeführt werden. Die resultierenden Dateien – statisches HTML, JavaScript und CSS – werden im Ausgabeordner abgelegt. Der Speicherort dieses Ordners hängt normalerweise davon ab, welche Build-Tools Sie verwenden. Bei React ist dies der Ordner ./build (wir werden weiter unten näher darauf eingehen).
Quelle-zu-Bild (S2I)
In diesem Beitrag gehen wir nicht auf das Thema „Was ist S2I und wie wird es verwendet?“ ein (mehr dazu können Sie hier lesen). ), aber es ist wichtig, die beiden Phasen dieses Prozesses klar zu verstehen, um zu verstehen, was das Web App Builder-Image macht.
Montagephase
Der Assemblierungsschritt ist im Wesentlichen dem sehr ähnlich, was passiert, wenn Sie Docker Build ausführen und am Ende ein neues Docker-Image erhalten. Dementsprechend tritt diese Phase beim Ausführen eines Builds auf der OpenShift-Plattform auf.
Im Fall eines Web App Builder-Images ist es für die Installation der Abhängigkeiten Ihrer Anwendung und die Ausführung des Builds verantwortlich. . Standardmäßig verwendet das Builder-Image die Konstrukt „npm run build“, dies kann jedoch über die Umgebungsvariable NPM_BUILD überschrieben werden.
Wie bereits erwähnt, hängt der Speicherort der fertigen, bereits zusammengestellten Anwendung davon ab, welche Tools Sie verwenden. Im Fall von React wäre dies beispielsweise der Ordner ./build und bei Angular-Anwendungen der Ordner project_name/dist. Und wie bereits im vorherigen Beitrag gezeigt, kann der Speicherort des Ausgabeverzeichnisses, das standardmäßig auf „Build“ eingestellt ist, über die Umgebungsvariable OUTPUT_DIR überschrieben werden. Da der Speicherort des Ausgabeordners von Framework zu Framework unterschiedlich ist, kopieren Sie die generierte Ausgabe einfach in den Standardordner im Image, nämlich /opt/apt-root/output. Dies ist wichtig für das Verständnis des restlichen Artikels, aber schauen wir uns zunächst schnell die nächste Phase an – die Laufphase.
Ausführungsphase
Diese Phase tritt ein, wenn ein Aufruf von Docker Run an das in der Assemblierungsphase erstellte neue Image erfolgt. Dasselbe passiert beim Bereitstellen auf der OpenShift-Plattform. Standardmäßig verwendet um statische Inhalte bereitzustellen, die sich im oben angegebenen Standardausgabeverzeichnis befinden.
Diese Methode eignet sich gut für die schnelle Bereitstellung von Anwendungen, es wird jedoch im Allgemeinen nicht empfohlen, statische Inhalte auf diese Weise bereitzustellen. Da wir eigentlich nur statische Inhalte bereitstellen, muss Node.js nicht in unserem Image installiert sein – ein Webserver reicht aus.
Mit anderen Worten: Wir benötigen das eine während der Montage und das andere während der Ausführung. In einer solchen Situation sind verkettete Builds praktisch.
Verkettete Builds
Darüber schreiben sie in der OpenShift-Dokumentation:
„Zwei Assemblys können miteinander verknüpft werden, wobei eine eine kompilierte Entität generiert und die andere diese Entität in ein separates Image einfügt, das zum Ausführen dieser Entität verwendet wird.“
Mit anderen Worten: Wir können das Web App Builder-Image verwenden, um unseren Build auszuführen, und dann ein Webserver-Image (dasselbe NGINX) verwenden, um unsere Inhalte bereitzustellen.
Auf diese Weise können wir das Web App Builder-Image als „reinen“ Builder verwenden und haben trotzdem ein kleines Laufzeit-Image.
Schauen wir uns dies nun anhand eines konkreten Beispiels an.
Für das Training verwenden wir , erstellt mit dem Befehlszeilentool „create-react-app“.
Um alles zusammenzubringen, werden wir unterstützt von .
Schauen wir uns diese Datei genauer an, beginnend mit dem Parameterabschnitt.
parameters:
- name: SOURCE_REPOSITORY_URL
description: The source URL for the application
displayName: Source URL
required: true
- name: SOURCE_REPOSITORY_REF
description: The branch name for the application
displayName: Source Branch
value: master
required: true
- name: SOURCE_REPOSITORY_DIR
description: The location within the source repo of the application
displayName: Source Directory
value: .
required: true
- name: OUTPUT_DIR
description: The location of the compiled static files from your web apps builder
displayName: Output Directory
value: build
required: false
Hier ist alles ziemlich klar, aber es lohnt sich, auf den Parameter OUTPUT_DIR zu achten. Bei der React-Anwendung in unserem Beispiel besteht kein Grund zur Sorge, da React den Standardwert als Ausgabeordner verwendet, bei Angular oder etwas anderem muss dieser Parameter jedoch nach Bedarf geändert werden.
Schauen wir uns nun den Abschnitt „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. Sie sind beide als Docker-Images definiert und es ist klar, woher sie kommen.
Das dritte Bild ist web-app-builder und stammt von nodeshift/ubi8-s2i-web-app mit dem 10.x-Tag auf .
Das vierte ist ein NGINX-Image (Version 1.12) mit dem neuesten Tag auf .
Schauen wir uns nun die ersten beiden Bilder an. Sie sind beide zu Beginn leer und werden erst während der Build-Phase erstellt. Das erste Image, react-web-app-builder, ist das Ergebnis eines Assemblierungsschritts, der das web-app-builder-runtime-Image und unseren Quellcode kombiniert. Aus diesem Grund haben wir „-builder“ in den Namen dieses Bildes aufgenommen.
Das zweite Image, react-web-app-runtime, ist das Ergebnis der Zusammenführung von nginx-image-runtime und einigen Dateien aus dem Image react-web-app-builder. Dieses Image wird auch während der Bereitstellung verwendet und enthält nur den Webserver und das statische HTML, JavaScript und CSS unserer Anwendung.
Verwirrend? Werfen wir nun einen Blick auf die Build-Konfigurationen, dann wird es etwas klarer.
Unsere Vorlage hat zwei Build-Konfigurationen. Hier ist das erste, und es ist ziemlich normal:
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 können, besagt die Zeile mit der Bezeichnung 1, dass das Ergebnis dieses Builds in dasselbe React-Web-App-Builder-Image eingefügt wird, das wir etwas zuvor im Abschnitt „ImageStreams“ gesehen haben.
Die mit 2 gekennzeichnete Zeile gibt an, woher der Code stammt. In unserem Fall handelt es sich um ein Git-Repository, und der Speicherort, der Verweis und der Kontextordner werden durch die Parameter definiert, die wir oben bereits gesehen haben.
Die Zeile mit der Bezeichnung 3 ist das, was wir bereits im Parameterabschnitt gesehen haben. Es fügt die Umgebungsvariable OUTPUT_DIR hinzu, die in unserem Beispiel „build“ ist.
Die Zeile mit der Bezeichnung 4 weist uns an, das Web-App-Builder-Runtime-Image zu verwenden, das wir bereits im Abschnitt „ImageStream“ gesehen haben.
Zeile 5 besagt, dass wir einen inkrementellen Build verwenden möchten, wenn das S2I-Image dies unterstützt und das Web App Builder-Image dies tut. Beim ersten Ausführen, nachdem die Assemblierungsphase abgeschlossen ist, speichert das Image den Ordner node_modules in einer Archivdatei. Bei nachfolgenden Ausführungen entpackt das Image dann einfach diesen Ordner, um die Erstellungszeit zu verkürzen.
Und schließlich handelt es sich bei Zeilenbezeichnung 6 nur um einige Auslöser, um den Build automatisch und ohne manuelles Eingreifen auszuführen, wenn sich etwas ändert.
Insgesamt handelt es sich hierbei um eine ziemlich standardmäßige Build-Konfiguration.
Schauen wir uns nun die zweite Build-Konfiguration an. Es ist dem ersten sehr ähnlich, aber es gibt einen wichtigen Unterschied.
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
Die zweite Build-Konfiguration ist „react-web-app-runtime“ und beginnt ziemlich standardmäßig.
In der Zeile mit der Bezeichnung 1 gibt es nichts Neues – sie besagt lediglich, dass die Build-Ausgabe in das React-Web-App-Runtime-Image eingefügt wird.
Die mit 2 gekennzeichnete Zeile gibt wie in der vorherigen Konfiguration an, woher der Quellcode bezogen werden soll. Beachten Sie jedoch, dass wir hier sagen, dass es aus dem Bild übernommen wurde. Außerdem aus dem Bild, das wir gerade erstellt haben – aus react-web-app-builder (angegeben in Zeile 3 mit Label 4). Die Dateien, die wir verwenden möchten, befinden sich im Image und ihr Speicherort dort ist in der Zeile mit der Bezeichnung XNUMX angegeben, in unserem Fall ist es /opt/app-root/output/. Wenn Sie sich erinnern, werden hier die Dateien gespeichert, die beim Erstellen unserer Anwendung generiert werden.
Der in der Zeile mit der Bezeichnung 5 angegebene Zielordner ist einfach das aktuelle Verzeichnis (denken Sie daran, dass sich all dies in einem magischen Ding namens OpenShift dreht und nicht auf Ihrem lokalen Computer).
Der Strategieabschnitt – Zeile mit der Bezeichnung 6 – ähnelt ebenfalls der ersten Build-Konfiguration. Nur dieses Mal verwenden wir nginx-image-runtime, das wir bereits im Abschnitt ImageStream gesehen haben.
Schließlich ist die Zeile mit der Bezeichnung 7 der Triggerabschnitt, der diesen Build jedes Mal auslöst, wenn sich das React-Web-App-Builder-Image ändert.
Ansonsten enthält diese Vorlage eine ziemlich standardmäßige Bereitstellungskonfiguration sowie Dinge im Zusammenhang mit Diensten und Routen, aber darauf gehen wir nicht näher ein. Bitte beachten Sie, dass es sich bei dem bereitgestellten Image um das React-Web-App-Runtime-Image handelt.
Anwendungsbereitstellung
Nachdem wir uns nun die Vorlage angesehen haben, wollen wir sehen, wie sie zum Bereitstellen der Anwendung verwendet wird.
Wir können das OpenShift-Clienttool 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 im Screenshot oben ist eine bewusst konstruierte Methode, um die Datei template./openshiftio/application.yaml zu finden.
Der zweite Befehl erstellt einfach eine neue Anwendung basierend auf dieser Vorlage.
Nachdem diese Befehle ausgeführt wurden, sehen wir, dass wir zwei Assemblys haben:

Und wenn wir zum Übersichtsbildschirm zurückkehren, sehen wir die gestartete Kapsel:

Wenn wir auf den Link klicken, gelangen wir zu unserer Anwendung, der Standardseite der React-App:

1-Nachtrag
Für Angular-Liebhaber haben wir auch .
Die Vorlage ist hier dieselbe, mit Ausnahme der Variable OUTPUT_DIR.
2-Nachtrag
In diesem Artikel haben wir NGINX als Webserver verwendet, aber es ist ganz einfach, es durch Apache zu ersetzen, ändern Sie einfach die Vorlage in der Datei auf .
Fazit
Im ersten Teil dieser Serie haben wir gezeigt, wie man moderne Webanwendungen schnell auf der OpenShift-Plattform bereitstellt. Heute haben wir uns angesehen, was ein Web-App-Image macht und wie es mithilfe verketteter Builds mit einem reinen Webserver wie NGINX kombiniert werden kann, um einen produktionsreiferen Anwendungsbuild zu erstellen. Im nächsten und letzten Artikel dieser Reihe zeigen wir Ihnen, wie Sie einen Entwicklungsserver für Ihre Anwendung auf OpenShift ausführen und lokale und Remote-Dateien synchron halten.
Inhalte dieser Artikelserie
- Teil 1: ;
- Teil 2: So verwenden Sie das neue S2I-Image zusammen mit einem vorhandenen HTTP-Server-Image, z. B. NGINX, mithilfe verknüpfter OpenShift-Builds, um eine Produktionsbereitstellung einzurichten;
- Teil 3: So führen Sie einen Entwicklungsserver für Ihre Anwendung auf der OpenShift-Plattform aus und synchronisieren ihn mit dem lokalen Dateisystem.
Zusätzliche Ressourcen
- Kostenloses E-Book .
- Informationen zu .
Source: habr.com
