Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Hej alla på denna blogg! Detta är det tredje inlägget i en serie där vi visar hur man distribuerar moderna webbapplikationer på Red Hat OpenShift.

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

I de två föregående inläggen visade vi hur man distribuerar moderna webbapplikationer i bara några få steg och hur man använder en ny S2I-avbildning tillsammans med en off-the-shelf HTTP-serverbild, såsom NGINX, med hjälp av kedjade builds för att orkestrera produktionsinstallationer .

Idag kommer vi att visa hur du kör en utvecklingsserver för din applikation på OpenShift-plattformen och synkroniserar den med det lokala filsystemet, samt pratar om vad OpenShift Pipelines är och hur de kan användas som ett alternativ till länkade sammansättningar.

OpenShift som utvecklingsmiljö

Utvecklingsarbetsflöde

Som redan nämnts i första inlägg, den typiska utvecklingsprocessen för moderna webbapplikationer är helt enkelt någon form av "utvecklingsserver" som spårar ändringar i lokala filer. När de inträffar utlöses applikationsbygget och sedan uppdateras det till webbläsaren.

I de flesta moderna ramverk är en sådan "utvecklingsserver" inbyggd i motsvarande kommandoradsverktyg.

Lokalt exempel

Låt oss först se hur detta fungerar när du kör applikationer lokalt. Låt oss ta applikationen som ett exempel Reagera från tidigare artiklar, även om nästan samma arbetsflödeskoncept gäller i alla andra moderna ramverk.
Så, för att starta "dev-servern" i vårt React-exempel, anger vi följande kommando:

$ npm run start

Sedan kommer vi att se något så här i terminalfönstret:

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Och vår applikation öppnas i standardwebbläsaren:

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Nu, om vi gör ändringar i filen, bör applikationen uppdateras i webbläsaren.

OK, allt är klart med utveckling i lokalt läge, men hur uppnår man samma sak på OpenShift?

Utvecklingsserver på OpenShift

Om du kommer ihåg, in tidigare inlägg, tittade vi på den så kallade körfasen av S2I-bilden och såg att servermodulen som standard är ansvarig för att serva vår webbapplikation.

Men om man tittar närmare kör skript från det exemplet innehåller den miljövariabeln $NPM_RUN, som låter dig utföra ditt kommando.

Till exempel kan vi använda nodeshift-modulen för att distribuera vår applikation:

$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app

Obs: Exemplet ovan är förkortat för att illustrera den allmänna idén.

Här har vi lagt till miljövariabeln NPM_RUN till vår distribution, som talar om för körningen att köra kommandot yarn start, som startar React-utvecklingsservern inuti vår OpenShift-pod.

Om du tittar på loggen för en löpande pod kommer den att se ut ungefär så här:

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Allt detta blir naturligtvis ingenting förrän vi kan synkronisera den lokala koden med koden, som också övervakas för förändringar, men bor på en fjärrserver.

Synkronisera fjärr- och lokalkod

Lyckligtvis kan nodeshift hjälpa till med synkronisering enkelt, och du kan använda watch-kommandot för att spåra ändringar.

Så efter att vi har kört kommandot för att distribuera utvecklingsservern för vår applikation, kan vi säkert använda följande kommando:

$ npx nodeshift watch

Som ett resultat kommer en anslutning att göras till den löpande podden som vi skapade lite tidigare, synkroniseringen av våra lokala filer med fjärrklustret kommer att aktiveras och filerna på vårt lokala system kommer att börja övervakas för ändringar.

Därför, om vi nu uppdaterar filen src/App.js, kommer systemet att reagera på dessa ändringar, kopiera dem till fjärrklustret och starta utvecklingsservern, som sedan uppdaterar vår applikation i webbläsaren.

För att slutföra bilden, låt oss visa hur hela dessa kommandon ser ut:

$ 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

Watch-kommandot är en abstraktion ovanpå kommandot oc rsync, du kan lära dig mer om hur det fungerar här.

Detta var ett exempel för React, men exakt samma metod kan användas med andra ramverk, ställ bara in miljövariabeln NPM_RUN efter behov.

Openshift Pipelines

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Härnäst ska vi prata om ett verktyg som OpenShift Pipelines och hur det kan användas som ett alternativ till kedjade builds.

Vad är OpenShift Pipelines

OpenShift Pipelines är ett molnbaserat CI/CD kontinuerligt integrations- och leveranssystem designat för att organisera pipelines med Tekton. Tekton är ett flexibelt Kubernetes-inbyggt CI/CD-ramverk med öppen källkod som låter dig automatisera distributionen på olika plattformar (Kubernetes, serverlösa, virtuella maskiner, etc.) genom att abstrahera från det underliggande lagret.

För att förstå den här artikeln krävs viss kunskap om Pipelines, så vi rekommenderar starkt att du läser den först officiella lärobok.

Inrätta din arbetsmiljö

För att leka med exemplen i den här artikeln måste du först förbereda din arbetsmiljö:

  1. Installera och konfigurera ett OpenShift 4-kluster. Våra exempel använder CodeReady Containers (CRD) för detta, installationsinstruktioner för vilka kan hittas här.
  2. När klustret är klart måste du installera Pipeline Operator på det. Var inte rädd, det är enkelt, installationsinstruktioner här.
  3. Ladda ner Tekton CLI (tkn) här.
  4. Kör kommandoradsverktyget create-react-app för att skapa en applikation som du sedan kommer att distribuera (detta är en enkel applikation Reagera).
  5. (Valfritt) Klona arkivet för att köra exempelapplikationen lokalt med npm install och sedan npm start.

Programförrådet kommer också att ha en k8s-mapp, som kommer att innehålla Kubernetes/OpenShift YAMLs som används för att distribuera programmet. Det kommer att finnas Tasks, ClusterTasks, Resources och Pipelines som vi kommer att skapa i detta förråd.

Komma igång

Det första steget för vårt exempel är att skapa ett nytt projekt i OpenShift-klustret. Låt oss kalla det här projektet webapp-pipeline och skapa det med följande kommando:

$ oc new-project webapp-pipeline

Detta projektnamn kommer att dyka upp i koden senare, så om du bestämmer dig för att döpa det till något annat, glöm inte att redigera exempelkoden därefter. Med utgångspunkt från denna punkt kommer vi inte att gå uppifrån och ner, utan nedifrån och upp: det vill säga, vi kommer först att skapa alla komponenter i transportören, och först sedan själva transportören.

Så, först och främst...

Uppgifter

Låt oss skapa ett par uppgifter, som sedan hjälper till att distribuera applikationen inom vår pipeline. Den första uppgiften - application_manifests_task - är ansvarig för att tillämpa YAML för de Kubernetes-resurser (tjänst, driftsättning och rutt) som finns i k8s-mappen i vår applikation. Den andra uppgiften – update_deployment_task – är ansvarig för att uppdatera en redan distribuerad image till den som skapats av vår pipeline.

Oroa dig inte om det inte är särskilt tydligt ännu. Faktum är att dessa uppgifter är ungefär som verktyg, och vi kommer att titta på dem mer i detalj lite senare. För nu, låt oss bara skapa 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

Sedan, med hjälp av tkn CLI-kommandot, kommer vi att kontrollera att uppgifterna har skapats:

$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago

Obs: Dessa är lokala uppgifter för ditt nuvarande projekt.

Klusteruppgifter

Klusteruppgifter är i grunden detsamma som enkla uppgifter. Det vill säga att det är en återanvändbar samling av steg som kombineras på ett eller annat sätt när man kör en specifik uppgift. Skillnaden är att en klusteruppgift är tillgänglig överallt inom klustret. För att se listan över klusteruppgifter som skapas automatiskt när Pipeline Operator läggs till kommer vi återigen att använda tkn CLI-kommandot:

$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago

Låt oss nu skapa två klusteruppgifter. Den första kommer att generera S2I-bilden och skicka den till det interna OpenShift-registret; det andra är att bygga vår bild baserad på NGINX, med hjälp av applikationen vi redan har byggt som innehåll.

Skapa och skicka bilden

När vi skapar den första uppgiften kommer vi att upprepa vad vi redan gjorde i den tidigare artikeln om länkade sammansättningar. Kom ihåg att vi använde S2I-avbildningen (ubi8-s2i-web-app) för att "bygga" vår applikation och slutade med en bild lagrad i OpenShifts interna register. Nu kommer vi att använda den här S2I webbappbilden för att skapa en DockerFile för vår app och sedan använda Buildah för att göra själva byggandet och skicka den resulterande bilden till det interna registret i OpenShift, eftersom det är precis vad OpenShift gör när du distribuerar dina applikationer med NodeShift .

Hur visste vi allt detta, frågar du? Från officiella versionen av officiella Node.js, vi bara kopierade det och modifierade det för oss själva.

Så låt oss nu skapa klusteruppgiften s2i-web-app:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml

Vi kommer inte att analysera detta i detalj, utan fokuserar bara på parametern OUTPUT_DIR:

params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build

Som standard är denna parameter lika med build, vilket är där React lägger det sammansatta innehållet. Andra ramverk använder olika vägar, till exempel i Ember är det dist. Utdata från vår första klusteruppgift kommer att vara en bild som innehåller HTML, JavaScript och CSS vi samlade in.

Bygg en bild baserad på NGINX

När det gäller vår andra klusteruppgift bör den bygga en NGINX-baserad bild åt oss, med hjälp av innehållet i den applikation vi redan har byggt. I huvudsak är detta den del av föregående avsnitt där vi tittade på kedjade konstruktioner.

För att göra detta kommer vi - exakt samma som precis ovan - att skapa en klusteruppgift webapp-build-runtime:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml

Om du tittar på koden för dessa klusteruppgifter kan du se att den inte specificerar Git-förrådet vi arbetar med eller namnen på bilderna vi skapar. Vi anger bara exakt vad vi överför till Git, eller en viss bild där den slutliga bilden ska matas ut. Det är därför dessa klusteruppgifter kan återanvändas när man arbetar med andra applikationer.

Och här går vi graciöst vidare till nästa punkt...

Ресурсы

Så eftersom, som vi nyss sa, klusteruppgifter bör vara så generella som möjligt, måste vi skapa resurser som kommer att användas som indata (Git-förvaret) och som utdata (de slutliga bilderna). Den första resursen vi behöver är Git, där vår applikation finns, ungefär så här:

# 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

Här är PipelineResource av typen git. Url-nyckeln i params-sektionen pekar på ett specifikt arkiv och specificerar huvudgrenen (detta är valfritt, men vi skriver det för fullständighetens skull).

Nu måste vi skapa en resurs för bilden där resultaten av s2i-web-app-uppgiften kommer att sparas, detta görs så här:

# 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

Här är PipelineResource av typen image, och värdet på url-parametern pekar på det interna OpenShift Image Registry, specifikt det som finns i webapp-pipeline-namnutrymmet. Glöm inte att ändra den här inställningen om du använder ett annat namnområde.

Och slutligen, den sista resursen vi behöver kommer också att vara av typen image och detta kommer att vara den sista NGINX-avbildningen som sedan kommer att användas under distributionen:

# 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

Återigen, observera att den här resursen lagrar bilden i det interna OpenShift-registret i webapp-pipeline-namnområdet.

För att skapa alla dessa resurser på en gång använder vi kommandot create:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml

Du kan se till att resurserna har skapats så här:

$ tkn resource ls

Transportör rörledning

Nu när vi har alla nödvändiga komponenter, låt oss sammanställa en pipeline från dem genom att skapa den med följande kommando:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml

Men innan vi kör det här kommandot, låt oss titta på dessa komponenter. Det första är namnet:

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react

Sedan ser vi i spec-avsnittet en indikation på de resurser vi skapade tidigare:

spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image

Vi skapar sedan de uppgifter som vår pipeline behöver slutföra. Först och främst måste den utföra s2i-web-app-uppgiften som vi redan har skapat:

tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask

Denna uppgift tar indata (gir-resurs) och output (built-web-application-image resurs) parametrar. Vi skickar också en speciell parameter till den så att den inte verifierar TLS eftersom vi använder självsignerade certifikat:

resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"

Nästa uppgift är nästan densamma, bara här kallas webbapp-build-runtime-klusteruppgiften som vi redan har skapat:

name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask

Precis som med den tidigare uppgiften skickar vi in ​​en resurs, men nu är den inbyggd webbapplikationsbild (utgången av vår tidigare uppgift). Och som en utgång ställer vi in ​​bilden igen. Eftersom denna uppgift måste utföras efter den föregående, lägger vi till fältet runAfter:

resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application

De följande två uppgifterna är ansvariga för att använda tjänsten, rutten och distributionen YAML-filer som finns i k8s-katalogen i vår webbapplikation, och även för att uppdatera denna distribution när nya bilder skapas. Vi definierade dessa två klusteruppgifter i början av artikeln.

Startar transportören

Så alla delar av vår pipeline skapas, och vi kör den med följande kommando:

$ tkn pipeline start build-and-deploy-react

I detta skede används kommandoraden interaktivt och du måste välja lämpliga resurser som svar på var och en av dess förfrågningar: för git-resursen, välj web-application-repo, sedan för den första bildresursen, inbyggd webbapplikation -image, och slutligen för den andra bildresursen -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

Låt oss nu kontrollera statusen för pipelinen med följande kommando:

$ tkn pipeline logs -f

När pipelinen har startat och applikationen har distribuerats kan vi begära den publicerade rutten med följande kommando:

$ oc get route react-pipeline-example --template='http://{{.spec.host}}'

För bättre visualisering kan du se vår pipeline i webbkonsolens utvecklarläge i avsnittet Rörledningar, som visas i fig. 1.

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Figur 1. Granskning av löpande rörledningar.

Genom att klicka på en löpande pipeline visas ytterligare detaljer, som visas i figur 2.

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Ris. 2. Ytterligare information om pipeline.

Efter mer information kan du se program som körs i vyn topologi, såsom visas i fig. 3.

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Fig 3. Lanserad pod.

Genom att klicka på cirkeln i det övre högra hörnet av ikonen öppnas vår applikation, som visas i Fig. 4.

Moderna applikationer på OpenShift, del 3: OpenShift som utvecklingsmiljö och OpenShift Pipelines

Ris. 4. Kör React-applikationen.

Slutsats

Så vi visade hur man kör en utvecklingsserver för din applikation på OpenShift och synkroniserar den med det lokala filsystemet. Vi tittade också på hur man simulerar en kedjad mall med OpenShift Pipelines. Alla exempelkoder från den här artikeln kan hittas här.

Ytterligare resurser (EN)

Meddelanden om kommande webbseminarier

Vi startar en serie webbseminarier på fredag ​​om inhemska erfarenheter av Red Hat OpenShift Container Platform och Kubernetes:

Källa: will.com

Lägg en kommentar