Hej alle sammen i denne blog! Her er det tredje indlæg i serien, hvor vi viser, hvordan man implementerer moderne webapplikationer på Red Hat OpenShift.

I de to foregående indlæg har vi forklaret, hvordan man implementerer moderne webapplikationer på få trin, og hvordan man bruger det nye S2I-billede sammen med et færdigt HTTP-serverbillede, som NGINX, ved hjælp af kædede builds til at organisere produktionsimplementeringen.
I dag viser vi, hvordan man starter en udviklingsserver for sin applikation på OpenShift-platformen og synkroniserer den med det lokale filsystem, samt taler om, hvad OpenShift Pipelines er, og hvordan de kan anvendes som et alternativ til kædede builds.
OpenShift som udviklingsmiljø
Udviklingsarbejdsgang
Som nævnt i , er den typiske udviklingsproces for moderne webapplikationer blot en slags "udviklingsserver", der overvåger ændringer i de lokale filer. Når de opstår, starter applikationen en bygning, og derefter opdateres den i browseren.
I de fleste moderne rammer er en sådan "udviklingsserver" indbygget i de relevante kommandolinjeværktøjer.
Lokalt eksempel
For at begynde, lad os se, hvordan det fungerer i tilfælde af lokal kørsel af applikationer. Som eksempel vil vi tage applikationen fra de tidligere artikler, selvom næsten de samme arbejdsgangskoncept bruges i alle andre moderne rammer.
Så for at starte "udviklingsserveren" i vores eksempel med React, indtaster vi følgende kommando:
$ npm run start
Så vil vi se noget lignende i terminalvinduet:

Og vores applikation åbner i standardbrowseren:

Nu, hvis vi foretager ændringer i filen, skal applikationen opdateres i browseren.
OK, udviklingen i lokal tilstand er klar, men hvordan får vi det til at fungere på OpenShift?
Udviklingsserver på OpenShift
Hvis du kan huske, i , gennemgik vi den såkaldte kørselfase (run phase) af S2I-billedet og så, at standardmæssigt bliver vores webapplikation betjent af modulet serve.
Men hvis vi ser nærmere på fra det eksempel, så er der en miljøvariabel $NPM_RUN, der giver mulighed for at køre sin egen kommando.
For example, you can use the nodeshift module to deploy our application:
$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app
Note: the example above is presented in a shortened form to illustrate the general idea.
Here we added the environment variable NPM_RUN to our deployment, which tells the execution phase to run the command yarn start, which starts the React development server inside our OpenShift pod.
If you look at the logs of the running pod, it will look something like this:

Of course, this will be meaningless until we can synchronize our local code with the code that is also monitored for changes but lives on a remote server.
Synchronization of remote and local code
Fortunately, nodeshift makes synchronization easy, and to track changes, you can use the watch command.
So after we execute the command to deploy the development server for our application, we can confidently use this command:
$ npx nodeshift watch
As a result, it will connect to the running pod we created earlier, activate the synchronization of our local files with the remote cluster, and local system files will start to be monitored for changes.
Therefore, if you now update the file src/App.js, the system will react to these changes, copy them to the remote cluster, and start the development server, which will then update our application in the browser.
To complete the picture, let’s show how these commands look in full:
$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000
$ npx nodeshift watch --strictSSL=false
The watch command is an abstraction over the oc rsync command, you can learn more about how it works. .
This was an example for React, but the same method can be used with other frameworks; just write the environment variable NPM_RUN appropriately.
OpenShift Pipelines

Next, we will discuss a tool called OpenShift Pipelines and how it can be used as an alternative to related chained builds.
What are OpenShift Pipelines?
OpenShift Pipelines er et cloudbaseret CI/CD-system til kontinuerlig integration og levering, designet til at organisere pipelines ved hjælp af Tekton. Tekton er et fleksibelt Kubernetes-nativt CI/CD-rammeværk med åbent kildekode, der gør det muligt at automatisere implementering på forskellige platforme (Kubernetes, serverless, virtuelle maskiner osv.) ved at abstrahere fra det underliggende niveau.
For at forstå denne artikel kræves der visse kendskaber til Pipelines, så vi anbefaler stærkt at begynde med at gøre dig bekendt med .
Opsætning af arbejdsområde
For at lege med eksemplerne fra denne artikel skal du først forberede dit arbejdsområde:
- Installere og konfigurere et OpenShift 4-klynge. I vores eksempler bruger vi CodeReady Containers (CRD), installationsvejledningen til hvilket kan findes .
- Når klyngen er klar, skal du installere Pipeline Operator. Frygt ikke, det er let, installationsvejledningen findes .
- Download (tkn) .
- Starte kommandolinjeværktøjet create-react-app for at oprette en applikation, som derefter skal implementeres (det er en simpel applikation ).
- (Valgfrit) Klon repositoryet for lokalt at køre applikationseksemplet ved hjælp af npm install og derefter npm start.
I applikationsrepositoryet vil der også være en mappe k8s, hvor YAML-filerne til Kubernetes/OpenShift, der bruges til implementeringen af applikationen, vil være. Der vil være Tasks, ClusterTasks, Resources og Pipelines, som vi vil oprette i dette .
Lad os komme i gang
Først skal vi for vores eksempel oprette et nyt projekt i OpenShift-klyngen. Vi kalder dette projekt webapp-pipeline og opretter det med følgende kommando:
$ oc new-project webapp-pipeline
Derefter vil dette projektnavn optræde i koden, så husk at ændre koden i eksemplerne, hvis du vælger at kalde det noget andet. Fra dette punkt vil vi gå oppefra og ned, men begynde med at oprette alle elementerne i pipelinen og derefter selve pipelinen.
Så, først og fremmest…
Opgaver Tasks
Lad os oprette et par opgaver (tasks), som derefter vil hjælpe med at implementere applikationen i vores pipeline. Den første opgave – apply_manifests_task – er ansvarlig for anvendelsen af YAML for de Kubernetes-ressourcer (service, deployment og route), som findes i k8s-mappen i vores applikation. Den anden opgave – update_deployment_task – er ansvarlig for at opdatere det allerede implementerede billede til det, som vores pipeline skaber.
Bare rolig, hvis det ikke er helt klart endnu. Faktisk er disse opgaver noget som værktøjer, og vi vil se nærmere på dem lidt senere. Men lad os først oprette dem:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml
Derefter vil vi ved hjælp af tkn CLI kommandoen kontrollere, at opgaverne blev oprettet:
$ tkn task ls
NAVN ALDER
apply-manifests 1 minut siden
update-deployment 1 minut siden
Bemærk: dette er lokale opgaver i dit nuværende projekt.
Klyngeopgaver Cluster tasks
Klyngeopgaver er i bund og grund det samme som blot opgaver. Det vil sige, det er en genanvendelig samling af trin, der kombineres på forskellige måder ved udførelsen af en bestemt opgave. Forskellen er, at klyngeopgaven er tilgængelig overalt i klyngen. For at se listen over klyngeopgaver, der automatisk oprettes ved tilføjelse af Pipeline Operator, vil vi igen bruge tkn CLI kommandoen:
$ tkn clustertask ls
NAVN ALDER
buildah 1 dag siden
buildah-v0-10-0 1 dag siden
jib-maven 1 dag siden
kn 1 dag siden
maven 1 dag siden
openshift-client 1 dag siden
openshift-client-v0-10-0 1 dag siden
s2i 1 dag siden
s2i-go 1 dag siden
s2i-go-v0-10-0 1 dag siden
s2i-java-11 1 dag siden
s2i-java-11-v0-10-0 1 dag siden
s2i-java-8 1 dag siden
s2i-java-8-v0-10-0 1 dag siden
s2i-nodejs 1 dag siden
s2i-nodejs-v0-10-0 1 dag siden
s2i-perl 1 dag siden
s2i-perl-v0-10-0 1 dag siden
s2i-php 1 dag siden
s2i-php-v0-10-0 1 dag siden
s2i-python-3 1 dag siden
s2i-python-3-v0-10-0 1 dag siden
s2i-ruby 1 dag siden
s2i-ruby-v0-10-0 1 dag siden
s2i-v0-10-0 1 dag siden
Lad os nu oprette to klyngeopgaver. Den første vil generere et S2I-billede og uploade det til den interne OpenShift-register; den anden vil bygge vores billede baseret på NGINX, ved at bruge det applikation, som vi allerede har samlet, som indhold.
Opretter og sender billede
Når vi opretter den første opgave, gentager vi det, vi allerede har gjort i den tidligere artikel om sammenkoblede builds. Vi minder om, at vi brugte S2I-imaget (ubi8-s2i-web-app) til at 'bygge' vores applikation, og resultatet var et image, der gemmes i den interne OpenShift-registre. Nu vil vi bruge dette S2I-image af webapplikationen til at oprette et DockerFile til vores applikation, og derefter anvende Buildah til at udføre den faktiske bygning og sende det genererede image til den interne OpenShift-registre, da det netop er det, OpenShift gør, når du implementerer dine applikationer ved hjælp af NodeShift.
Spørger du, hvor vi har fået det hele fra? Fra , vi har blot kopieret det og tilpasset det til vores behov.
Så, lad os nu oprette en klyngeopgave s2i-web-app:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml
Vi vil ikke gennemgå dette i detaljer, men blot stoppe ved parameteren OUTPUT_DIR:
params:
- name: OUTPUT_DIR
description: Placeringen af byggets output-mappe
default: build
Som standard er denne parameter lig med build, og det er her, React gemmer det samlede indhold. I andre rammer anvendes der andre stier, for eksempel i Ember er det dist. Outputtet fra vores første klyngeopgave vil være et image, der indeholder den HTML, JavaScript og CSS, vi har samlet.
Vi bygger et image baseret på NGINX
Når det gælder vores anden klyngeopgave, skal den samle et image baseret på NGINX ved hjælp af indholdet fra vores allerede samlede applikation. Grundlæggende set er dette den del af det forrige afsnit, hvor vi betragtede sammenkoblede builds.
Til dette formål – præcis som før – opretter vi en klyngeopgave webapp-build-runtime:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml
Hvis vi ser koden for disse klyngeopgaver, kan vi se, at der ikke specificeres noget Git-repositorium, som vi arbejder med, eller navne på de images, vi skaber. Vi angiver kun, hvad vi sender til Git, eller et image, hvortil det endelige image skal exporteres. Det er derfor, disse klyngeopgaver kan genbruges, også når vi arbejder med andre applikationer.
Og her går vi elegant videre til næste punkt…
Ressourcer
Så, som vi lige har sagt, skal klyngeopgaver være så generelle som muligt, vi skal oprette ressourcer, der skal bruges til indgangen (Git-arkiv) og udgangen (de endelige billeder). Den første ressource, vi har brug for, er Git, hvor vores ansøgning befinder sig, noget i stil med dette:
# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: web-application-repo
spec:
type: git
params:
- name: url
value: https://github.com/nodeshift-starters/react-pipeline-example
- name: revision
value: master
Her har PipelineResource typen git. Nøglen url i sektionen params angiver det specifikke arkiv og sætter master-grenen (dette er valgfrit, men vi skriver det for fuldstændighedens skyld).
Nu skal vi oprette en ressource til billedet, hvor resultaterne af opgaven s2i-web-app skal gemmes, det gøres således:
# This resource is the result of running "npm run build", the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: built-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest
Her har PipelineResource typen image, og værdien af parameteren url henviser til den interne OpenShift Image Registry, specifikt den, der findes i navnerummet webapp-pipeline. Glem ikke at ændre denne parameter, hvis du bruger et andet navnerum.
Og endelig, den sidste ressource, vi får brug for, vil også have typen image, og det vil være det endelige NGINX-billede, som derefter vil blive brugt ved implementeringen:
# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: runtime-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest
Og bemærk igen, at denne ressource gemmer billedet i den interne OpenShift registry i navnerummet webapp-pipeline.
For at oprette alle disse ressourcer på én gang, bruger vi kommandoen create:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml
For at bekræfte, at ressourcerne er oprettet, kan du gøre det sådan:
$ tkn resource ls
Pipeline-kæden
Nu hvor vi har alle de nødvendige komponenter, samler vi dem i en pipeline ved at køre følgende kommando:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml
Men før vi kører denne kommando, lad os gennemgå disse komponenter. Den første er navnet:
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: build-and-deploy-react
Derefter ser vi i sektionen spec angivelsen af de ressourcer, vi tidligere har oprettet:
spec:
resources:
- name: web-application-repo
type: git
- name: built-web-application-image
type: image
- name: runtime-web-application-image
type: image
Derefter opretter vi de opgaver, som vores pipeline skal udføre. Først skal den udføre den opgave, vi allerede har oprettet, s2i-web-app:
tasks:
- name: build-web-application
taskRef:
name: s2i-web-app
kind: ClusterTask
Denne opgave tager indgangs (git-ressource) og udgangs (ressource built-web-application-image) parametre. Vi sender også et specielt parameter til den, så den ikke validerer TLS, da vi bruger selvsignerede certifikater:
ressourcer:
indgange:
- navn: kilde
ressource: web-application-repo
udgange:
- navn: billede
ressource: built-web-application-image
parametre:
- navn: TLSVERIFY
værdi: "false"
Den næste opgave er næsten den samme, men her kaldes allerede den klyngopgave, vi har oprettet, webapp-build-runtime:
navn: build-runtime-image
taskRef:
navn: webapp-build-runtime
type: ClusterTask
Som med den forrige opgave, sender vi ressourcen, men nu er det built-web-application-image (udgangen fra vores forrige opgave). Og som udgang angiver vi igen billedet. Da denne opgave skal udføres efter den forrige, tilføjer vi feltet runAfter:
ressourcer:
indgange:
- navn: billede
ressource: built-web-application-image
udgange:
- navn: billede
ressource: runtime-web-application-image
parametre:
- navn: TLSVERIFY
værdi: "false"
runAfter:
- build-web-application
De næste to opgaver er ansvarlige for anvendelse af YAML-filerne til tjenesten, ruten og udrulningen, som findes i mappen k8s i vores webapplikation, samt for at opdatere denne udrulning, når der oprettes nye billeder. Disse to klyngopgaver blev vi enige om i starten af artiklen.
Kør pipeline
Så alle dele af vores pipeline er skabt, og vi vil starte den med følgende kommando:
$ tkn pipeline start build-and-deploy-react
På dette tidspunkt bruges kommandoprompten i interaktiv tilstand, og man skal vælge de relevante ressourcer som svar på hver anmodning: for git-resourcen vælger vi web-application-repo, derefter for den første billedressource – built-web-application-image, og til sidst for den anden billedressource – runtime-web-application-image:
? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr
Nu vil vi kontrollere status for pipeline med følgende kommando:
$ tkn pipeline logs -f
Når pipeline er startet, og applikationen er blevet udrullet, kan vi anmode om den offentliggjorte rute med følgende kommando:
$ oc get route react-pipeline-example --template='http://{{.spec.host}}'
For bedre visualisering kan vi se vores pipeline i udvikler-tilstand i webkonsollen i sektionen Pipelines, som vist på Figur 1.

Figur 1. Oversigt over kørende pipelines.
Et klik på den kørende pipeline viser yderligere oplysninger, som vist på Figur 2.

Figur 2. Yderligere oplysninger om pipeline.
Efter de yderligere oplysninger kan man se kørende applikationer i visningen Topologi, som vist på Figur 3.

Figur 3. Kørende pod.
Et klik på cirklen i øverste højre hjørne af ikonet åbner vores applikation, som vist på Figur 4.

Figur 4. Kørende React-applikation.
Konklusion
Sådan kører du en udviklingsserver for din applikation på OpenShift og synkroniserer den med dit lokale filsystem. Vi har også set på, hvordan man simulerer en chained-build skabelon ved hjælp af OpenShift Pipelines. Alle koderne fra denne artikel kan findes .
Yderligere ressourcer (EN)
- Gratis e-bog
- Andre artikler om på Red Hat-sitet
Annonceringer af kommende webinars
Vi starter en serie af fredagswebinars om den native oplevelse af at bruge Red Hat OpenShift Container Platform og Kubernetes:
Kilde: habr.com
