Përshëndetje të gjithë në këtë blog! Ky është postimi i tretë nga seria, ku ne shfaqim se si të zhvilloni aplikacione moderne në Red Hat OpenShift.

Në dy postimet e mëparshme ne treguam se si të zhvilloni aplikacione moderne me disa hapa të thjeshtë dhe si të përdorni imazhin e ri S2I së bashku me imazhin e gatshëm të serverit HTTP, si NGINX me ndihmën e ndërlidhjeve të ndërtimit për të organizuar një zhvillim prodhimi.
Sot ne do të tregojmë se si të nxjerrim në platformën OpenShift një server zhvillimi për aplikacionin tonë dhe ta sinkronizojmë atë me sistemin lokal të skedarëve, si dhe do të flasim për çfarë është OpenShift Pipelines dhe si mund të aplikohet si alternativë ndaj ndërlidhjeve të ndërtimit.
OpenShift si një mjedis zhvillimi
Procesi i punës për zhvillim
Siç u tha më parë në , procesi tipik i zhvillimit për aplikacione moderne është thjesht një 'server zhvillimi' që monitoron ndryshimet në skedarët lokalë. Kur ndodhin ato, niset ndarja e aplikacionit, dhe më pas ajo përditësohet në shfletues.
Në shumicën e kornizave moderne, një 'server zhvillimi' është i integruar në veglat përkatëse të komandës.
Shembulli lokal
Fillimisht, le të shikojmë se si funksionon kjo për sa i përket ekzekutimit lokal të aplikacioneve. Si shembull do të përdorim aplikacionin nga artikujt e mëparshëm, megjithëse konceptet e njëjta të procesit të punës janë të aplikueshme në të gjitha kornizat moderne.
Pra, për të nisur 'serverin e zhvillimit' në shembullin tonë me React, do të futim komandën e mëposhtme:
$ npm run start
Atëherë në dritaren e terminalit do të shohim diçka të tillë:

Dhe aplikacioni ynë do të hapet në shfletuesin tonë të paracaktuar:

Tani, nëse bëjmë ndryshime në skedar, aplikacioni duhet të përditësohet në shfletues.
OK, është e qartë për zhvillimin në modus lokal, por si të arrihet e njëjta gjë në OpenShift?
Serveri i zhvillimit në OpenShift
Nëse e mbani mend, në , ne diskutuam fazën e aktivizimit (run phase) të imazhit S2I dhe patëm mundësinë të shohim se për parazgjedhje, menaxhimi i aplikacionit tonë web bëhet nga moduli serve.
Megjithatë, nëse e shikojmë më me kujdes nga ai shembull, vëreni se ka një variabël ambienti $NPM_RUN, e cila lejon të ekzekutohet edhe komanda juaj.
Për shembull, mund të përdorim modulimin nodeshift për të zhvilluar aplikacionin tonë:
$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app
Vërejtje: shembulli më sipër është dhënë në një formë të përmbledhur për të ilustruar idenë e përgjithshme.
Këtu kemi shtuar në shpërndarjen tonë një variabël mjedisi NPM_RUN, e cila i thotë fazës së ekzekutimit që duhet të ekzekutojë komandën yarn start, e cila nis serverin e zhvillimit React brenda pod-it tonë OpenShift.
Nëse shikoni logun e pod-it në punë, do të duket përafërsisht kështu:

Sigurisht, kjo do të mos ketë kuptim derisa të mund të sinkronizojmë kodin lokal me kodin, i cili gjithashtu kontrollohet për ndryshime, por jeton në një server të largët.
Sinkronizimi i kodit të largët dhe atij lokal
Fatmirësisht, nodeshift ndihmon lehtësisht me sinkronizimin, dhe për të ndjekur ndryshimet mund të përdorim komandën watch.
Kështu që pasi të kemi ekzekutuar komandën për shpërndarjen e serverit të zhvillimit për aplikacionin tonë, mund të përdorim me besim këtë komandë:
$ npx nodeshift watch
Si rezultat, do të lidhemi me pod-in e aktivizuar që krijuam pak më parë, aktivizohet sinkronizimi i skedarëve tanë lokalë me klusterin e largët, dhe skedarët në sistemin tonë lokal do të fillojnë të ndjekin ndryshimet.
Prandaj, nëse tani përditësojmë skedarin src/App.js, sistemi do të reagojë ndaj këtyre ndryshimeve, do t'i kopjojë ato në klusterin e largët dhe do të niste serverin e zhvillimit, i cili më pas do ta përditësojë aplikacionin tonë në shfletues.
Për të plotësuar pamjen, le të shohim si duken këto komanda në tërësi:
$ 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
Komanda watch është një abstraksion mbi komandën oc rsync, për detaje më të thella mbi funksionimin e saj mund të mësoni .
Ky ishte një shembull për React, por e njëjta metodë mund të përdoret edhe me framework-e të tjera, thjesht shkruani siç duhet variablin mjedisor NPM_RUN.
â
Tuba të Openshift Pipelines

Më pas do të flasim për një mjet, siç është OpenShift Pipelines, dhe se si mund të përdoret si një alternativë për ndërtimet e lidhura chained build.
ĂfarĂ« janĂ« OpenShift Pipelines
OpenShift Pipelines është një sistem CI/CD i orientuar nga reja për integrimin dhe shpërndarjen e vazhdueshme, i destinuar për organizimin e konvejereve duke përdorur Tekton. Tekton është një kornizë CI/CD me burim të hapur, e cila është e natyrshme për Kubernetes, duke lejuar automatizimin e shpërndarjes në platforma të ndryshme (Kubernetes, serverless, makina virtuale, etj.) duke abstraktuar nivelin e poshtëm.
Për të kuptuar këtë artikull janë të nevojshme disa njohuri mbi Pipelines, prandaj ju sugjerojmë të njiheni fillimisht me .
Konfigurimi i mjedisit të punës
Për të provuar shembujt nga ky artikull, së pari duhet të përgatitni mjedisin e punës:
- Instaloni dhe konfiguroni një klaster OpenShift 4. Në shembujt tanë, për këtë përdoren CodeReady Containers (CRD), udhëzimet për instalimin e të cilëve mund të gjenden .
- Pas përfundimit të klasterit, duhet të instaloni Pipeline Operator. Mos u frikësoni, është e lehtë; udhëzimet për instalimin e tij .
- Shkarko (tkn) .
- Ekzekutoni mjetin e komandës create-react-app për të krijuar një aplikacion që më pas do të shpërndahet (ky është një aplikacion i thjeshtë ).
- (Opsionale) Kloni repositorin për të drejtuar lokalisht shembullin e aplikacionit me komandën npm install dhe pastaj npm start.
Në repositorin e aplikacionit gjithashtu do të ketë një dosje k8s, ku do të jenë YAML-të e Kubernetes/OpenShift që përdoren për shpërndarjen e aplikacionit. Aty do të jenë Tasks, ClusterTasks, Resources dhe Pipelines që ne do të krijojmë në këtë .
Të fillojmë
Së pari, për shembullin tonë duhet të krijojmë një projekt të ri në klasterin OpenShift. Ta quajmë këtë projekt webapp-pipeline dhe ta krijojmë me komandën e mëposhtme:
$ oc new-project webapp-pipeline
Më pas, kjo emër projekti do të figurojë në kod, kështu që, nëse vendosni ta quani ndryshe, mos harroni të rregulloni përkatësisht kodin nga shembujt. Duke filluar nga ky moment, ne do të shkojmë nga poshtë lart: do të krijojmë së pari të gjitha komponentët e konvejereve dhe pastaj konvejerin vetë.
Pra, së pari...
Detyrat Tasks
Ne do qojmĂ« disa detyra (tasks) qĂ« do tĂ« ndihmojnĂ« mĂ« pas nĂ« implementimin e aplikacionit nĂ« kuadĂ«r tĂ« konvejerit tonĂ« pipeline. Detyra e parĂ« â apply_manifests_task â Ă«shtĂ« pĂ«rgjegjĂ«se pĂ«r aplikimin e burimeve Kubernetes (service, deployment dhe route) qĂ« ndodhen nĂ« dosjen k8s tĂ« aplikacionit tonĂ«. Detyra e dytĂ« â update_deployment_task â Ă«shtĂ« pĂ«rgjegjĂ«se pĂ«r pĂ«rditĂ«simin e imazhit tashmĂ« tĂ« implementuar me atĂ« qĂ« krijohet nga konvejeri ynĂ«.
Mos u shqetësoni nëse nuk është shumë e qartë për momentin. Në të vërtetë, këto detyra janë si lloji i mjeteve, dhe ne do t'i shqyrtojmë ato më vonë. Ndërsa për tani, le të krijojmë ato:
$ 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
Më pas, me ndihmën e komandës tkn CLI, do të verifikojmë që detyrat janë krijuar:
$ tkn task ls
NAME AGE
apply-manifests 1 minute ago
update-deployment 1 minute ago
Shënim: këto janë detyra lokale të projektit tuaj aktual.
Detyrat e klasit Cluster tasks
Detyrat e klasit Cluster tasks janë në thelb të njëjtat si detyrat e zakonshme. Kështu, ato janë një koleksion i ripërdorshëm hapash, të cilët kombinohen në mënyra të ndryshme gjatë ekzekutimit të një detyre të caktuar. Dallimi është se detyra e klasit është e disponueshme në të gjithë klastrin. Për të parë listën e detyrave të klasit që krijohen automatikisht kur shtohet Pipeline Operator, le të përdorim përsëri komandën tkn CLI:
$ 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
Tani le të krijojmë dy detyra të klasit. E para do të gjenerojë një imazh S2I dhe do ta dërgojë në regjistrin e brendshëm OpenShift; e dyta do të kryejë ndërtimin e imazhit tonë mbi bazën e NGINX, duke përdorur si përmbajtje aplikacionin që e kemi ndërtuar tashmë.
Krijojmë dhe dërgojmë imazhin
Kur krijojnë detyrën e parë, ne do të përsërisim atë që kemi bërë në artikullin e mëparshëm për ndërtimet e lidhura. Kujtojmë se ne përdorëm imazhin S2I (ubi8-s2i-web-app) për të "ndërtuar" aplikacionin tonë dhe përfundimisht morëm një imazh që ruhej në registrin e brendshëm OpenShift. Tani do të përdorim këtë imazh S2I të aplikacionit web për të krijuar DockerFile për aplikacionin tonë dhe pastaj do të përdorim Buildah për të kryer ndërtimin real dhe duke dërguar imazhin e fituar në registrin e brendshëm OpenShift, sepse kjo është ajo që OpenShift bën kur ju vendosni aplikacionet tuaja duke përdorur NodeShift.
Po pyesni, nga kemi mësuar të gjitha këto? Nga , ne thjesht e kopjuam atë dhe e adaptuam sipas nevojave tona.
Tani, le të krijojmë detyrën e grupit s2i-web-app:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml
Nuk do ta shqyrtojmë këtë në detaje, por do të ndalemi te parametri OUTPUT_DIR:
params:
- name: OUTPUT_DIR
description: Vendndodhja e direktorisë së daljes së ndërtimit
default: build
Në mënyrë të paracaktuar, ky parametër është i barabartë me build, aty React vendos përmbajtjen e mbledhur. Në frameworke të tjera përdoren rrugë të ndryshme, për shembull, në Ember është dist. Dalja e detyrës sonë të parë të grupit do të përbëjë një imazh që përmban HTML, JavaScript dhe CSS të mbledhura nga ne.
Ndërtojmë një imazh mbi NGINX
Sa i përket detyrës sonë të dytë të grupit, ajo duhet të ndihmojë në ndërtimin e një imazhi mbi NGINX, duke përdorur përmbajtjen e aplikacionit tanë tashmë të mbledhur. Në thelb, kjo është ajo pjesë e seksionit të mëparshëm ku shikuam ndërtimet e lidhura.
PĂ«r kĂ«tĂ«, ne â ashtu si mĂ« sipĂ«r â do tĂ« krijojmĂ« detyrĂ«n e grupit webapp-build-runtime:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml
Nëse shikoni kodin e këtyre detyrave të grupit, do të shihni se nuk specifikohet asnjë repo Git me të cilin punojmë, ose emrat e imazheve që krijojmë. Ne vetëm përcaktojmë atë që ne kalojmë në Git, ose një imazh, ku duhet të dërgohet imazhi përfundimtar. Pikërisht për këtë arsye, këto detyra grupi mund të përdoreshin përsëri dhe kur punon me aplikacione të tjera.
Dhe këtu kalojmë elegante në pikën e ardhshme...
Burime
Pra ndaj, pasi siç thamë, detyrat në klaster duhet të jenë sa më të përgjithshme, na nevojitet të krijojmë burime që do të përdoren në hyrje (repo Git) dhe në dalje (imazhe përfundimtare). Burimi i parë që na nevojitet është Git, ku ndodhet aplikacioni ynë, diçka si kjo:
# 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
KĂ«tu PipelineResource ka llojin git. ĂelĂ«si url nĂ« seksionin params tregon pĂ«r repo specific dhe vendos degĂ«n master (kjo Ă«shtĂ« opsionale, por e shkruajmĂ« pĂ«r plotĂ«si).
Tani, na nevojitet të krijojmë një burim për imazhin ku do të ruajmë rezultatet e ekzekutimit të detyrës s2i-web-app, kjo bëhet kështu:
# 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
Këtu PipelineResource ka llojin image, dhe vlera e parametrave url tregon për OpenShift Image Registry brendshëm, specifikisht atë që ndodhet në hapësirën e emërtesës webapp-pipeline. Mos harroni të ndryshoni këtë parameter nëse përdorni një hapësirë tjetër emërtesë.
Dhe, përfundimisht, burimi i fundit që do të na nevojitet, gjithashtu do të ketë llojin image dhe do të jetë imazhi përfundimtar NGINX, i cili do të përdoret më vonë gjatë implementimit:
# 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
Dhe përsëri, mos harroni që ky burim ruan imazhin në registrin e brendshëm të OpenShift në hapësirën e emërtesës webapp-pipeline.
Për të krijuar të gjitha këto burime njëherësh, do të përdorim komandën create:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml
Për të verifikuar që burimet janë krijuar, mund ta bëni kështu:
$ tkn resource ls
Pipeline-i
Tani që kemi të gjitha komponentët e nevojshëm, do t'i grumbullojmë ato duke krijuar pipeline-in me komandën e mëposhtme:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml
Por, para se ta ekzekutojmë këtë komandë, le të shohim këta komponentë. I pari është emri:
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: build-and-deploy-react
Pastaj në seksionin spec shohim tregimin e burimeve që krijuam më parë:
spec:
resources:
- name: web-application-repo
type: git
- name: built-web-application-image
type: image
- name: runtime-web-application-image
type: image
Pastaj krijojmë detyrat që duhet të kryejë pipeline-i ynë. E para që duhet të ekzekutojë është detyra s2i-web-app që kemi krijuar më parë:
tasks:
- name: build-web-application
taskRef:
name: s2i-web-app
kind: ClusterTask
Kjo detyrë merr parametrat hyrës (burimi git) dhe dalës (burimi built-web-application-image). Ne gjithashtu i përcjellim një parameter të veçantë që nuk verifikon TLS, pasi përdorim certifikata të vetë-nënshkruara:
burimet:
hyrje:
- emri: burim
resurs: web-application-repo
daljet:
- emri: imazh
resurs: built-web-application-image
parametër:
- emri: TLSVERIFY
vlera: "false"
Detyra e ardhshme është pothuajse e njëjtë, vetëm se këtu thirret detyra e klasterizuar e krijuar prej nesh webapp-build-runtime:
emri: build-runtime-image
referencë e detyrës:
emri: webapp-build-runtime
lloji: ClusterTask
Si me detyrën e mëparshme, ne kalojmë burimin, por tani është built-web-application-image (dalja e detyrës sonë të mëparshme). Dhe si dalje përsëri përcaktojmë imazhin. Duke qenë se kjo detyrë duhet të ekzekutohet pas asaj të mëparshme, shtojmë fushën runAfter:
burimet:
hyrje:
- emri: imazh
resurs: built-web-application-image
daljet:
- emri: imazh
resurs: runtime-web-application-image
parametër:
- emri: TLSVERIFY
vlera: "false"
runAfter:
- build-web-application
Dy detyrat e ardhshme janë përgjegjëse për aplikimin e skedarëve YAML të shërbimit, rrugës dhe implementimit, të cilat jetojnë në katalogun k8s të aplikacionit tonë të uebit, si dhe për të përditësuar këtë implementim kur krijohen imazhe të reja. Këto dy detyra klasterizuar i kemi caktuar që herët gjatë artikullit.
Fillimi i konvejrit
Pra, të gjitha pjesët e konvejrit tonë janë krijuar, dhe ne do ta fillojmë atë me komandën e mëposhtme:
$ tkn pipeline start build-and-deploy-react
NĂ« kĂ«tĂ« pikĂ«, struktura komandĂ« pĂ«rdoret nĂ« modin interaktiv dhe duhet tĂ« zgjidhen burimet pĂ«rkatĂ«se nĂ« pĂ«rgjigje tĂ« çdo kĂ«rkese tĂ« saj: pĂ«r burimin git zgjidhim web-application-repo, pastaj pĂ«r burimin e imazhit tĂ« parĂ« â built-web-application-image, dhe, pĂ«rfundimisht, pĂ«r burimin e imazhit tĂ« dytĂ« â 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
Tani do të kontrollojmë statusin e konvejrit me komandën e mëposhtme:
$ tkn pipeline logs -f
Pas niste si konvejeri dhe aplikacioni është implementuar, do të kërkojmë rrugën e publikuar me komandën e mëposhtme:
$ oc get route react-pipeline-example --template='http://{{.spec.host}}'
Për më shumë vizibilitet, mund të shohim konvejerin tonë në modin Developer të konsolës në internet në seksionin Pipeline, siç është treguar në Figurën 1.

Fig.1. Përmbledhje e konvejrëve të nisur.
Klikimi mbi konvejerin e nisur shfaq detaje të tjera, siç është treguar në Figurën 2.

Fig. 2. Detaje të tjera mbi konvejerin.
Pas detajeve të tjera, mund të shohim aplikacionet e nisura në pamjen Topology, siç është treguar në Figurën 3.

Fig 3. Pod-i i nisur.
Klikimi në rrethin në këndin e sipërm të djathtë të ikonës hap aplikacionin tonë, siç është treguar në Figurën 4.

Fig. 4. Aplikacioni React i nisur.
Përfundim
Pra të arritje, ne treguam se si të ndizni një server zhvillimi për aplikacionin tuaj në OpenShift dhe ta sinkronizoni atë me sistemin tuaj të skedarëve lokal. Gjithashtu, ne shqyrtuam se si të simulojmë një template të ndërlidhur të ndërtimit përmes OpenShift Pipelines. Të gjithë kodet e shembujve nga ky artikull mund të gjenden .
Burime të tjera (EN)
- Libri elektronik falas
- Artikuj të tjerë rreth në faqen e Red Hat
Njoftime për webinarët e ardhshëm
Ne po fillojmë një seri webinarësh të premten për përvojën native të përdorimit të Red Hat OpenShift Container Platform dhe Kubernetes:
Burimi: habr.com
