{"id":92048,"date":"2020-08-22T07:42:57","date_gmt":"2020-08-22T05:42:57","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines"},"modified":"2020-08-22T07:42:57","modified_gmt":"2020-08-22T05:42:57","slug":"sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","title":{"rendered":"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Salut tuturor pe acest blog! Asta este a treia postare dintr-o serie \u00een care ar\u0103t\u0103m cum s\u0103 implement\u0103m aplica\u021bii web moderne pe Red Hat OpenShift.<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/9c3337b13a3f045d36343308ce6154cc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen ultimele dou\u0103 post\u0103ri, am explicat cum s\u0103 implement\u0103m aplica\u021bii web moderne \u00een doar c\u00e2teva etape \u0219i cum s\u0103 folosim o nou\u0103 imagine S2I \u00eempreun\u0103 cu o imagine de server HTTP preg\u0103tit\u0103, cum ar fi NGINX, cu ajutorul construc\u021biilor legate pentru a organiza implement\u0103ri \u00een produc\u021bie.<\/p>\n<p>Ast\u0103zi vom ar\u0103ta cum s\u0103 lans\u0103m pe platforma OpenShift un server de dezvoltare pentru aplica\u021bia noastr\u0103 \u0219i s\u0103-l sincroniz\u0103m cu sistemul de fi\u0219iere local, precum \u0219i s\u0103 vorbim despre ce sunt OpenShift Pipelines \u0219i cum pot fi utilizate ca alternativ\u0103 la construc\u021biile legate.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>OpenShift ca mediu de dezvoltare<\/h3>\n<p><\/p>\n<h4>Flux de lucru de dezvoltare<\/h4>\n<p>\nDup\u0103 cum s-a men\u021bionat \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">prima postare<\/a><\/noindex>, procesul tipic de dezvoltare pentru aplica\u021biile web moderne este simplu un \"server de dezvoltare\" care monitorizeaz\u0103 modific\u0103rile din fi\u0219ierele locale. C\u00e2nd acestea au loc, se declan\u0219eaz\u0103 o construc\u021bie a aplica\u021biei, care este apoi actualizat\u0103 \u00een browser.<\/p>\n<p>\u00cen majoritatea cadrelor moderne, un astfel de \"server de dezvoltare\" este integrat \u00een instrumentele corespunz\u0103toare de linie de comand\u0103.<\/p>\n<h4>Exemplu local<\/h4>\n<p>\n\u00cencepem prin a vedea cum func\u021bioneaz\u0103 \u00een cazul unui launch local al aplica\u021biilor. Ca exemplu, vom lua aplica\u021bia <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">React<\/a><\/noindex> din articolele anterioare, de\u0219i practic acelea\u0219i concepte de lucru se aplic\u0103 \u0219i \u00een alte cadre moderne.<br \/>\nA\u0219adar, pentru a lansa \"serverul de dezvoltare\" \u00een exemplul nostru cu React, vom introduce urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ npm run start\n<\/code><\/pre>\n<p>\nAtunci, \u00een fereastra terminalului, vom vedea aproximativ urm\u0103toarele:<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/06f84ffb4c9a6a5868b8b47b8ad1d9ec.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\u0218i aplica\u021bia noastr\u0103 se va deschide \u00een browserul implicit:<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/72341bb0796352e7343bf31ceb8233cd.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Acum, dac\u0103 facem modific\u0103ri \u00een fi\u0219ier, aplica\u021bia ar trebui s\u0103 se actualizeze \u00een browser.<\/p>\n<p>OK, cu dezvoltarea \u00een modul local totul este clar, dar cum ob\u021binem acela\u0219i lucru pe OpenShift?<\/p>\n<h4>Server de dezvoltare pe OpenShift<\/h4>\n<p>\nDac\u0103 v\u0103 aminti\u021bi, \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/513948\/\">postarea anterioar\u0103<\/a><\/noindex>, am analizat a\u0219a numita etap\u0103 de lansare a imaginii S2I \u0219i am v\u0103zut c\u0103, \u00een mod implicit, \u00eentre\u021binerea aplica\u021biei noastre web este realizat\u0103 de modulul serve.<\/p>\n<p>Cu toate acestea, dac\u0103 ne uit\u0103m mai atent <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/ubi8-s2i-web-app\/blob\/master\/s2i\/run#L10\">scriptul de execu\u021bie<\/a><\/noindex> din acel exemplu, exist\u0103 o variabil\u0103 de mediu $NPM_RUN care permite s\u0103 execut\u0103m comanda noastr\u0103.<\/p>\n<p>De exemplu, putem folosi modulul nodeshift pentru a desf\u0103\u0219ura aplica\u021bia noastr\u0103:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift --deploy.env NPM_RUN=\"yarn start\" --dockerImage=nodeshift\/ubi8-s2i-web-app\n<\/code><\/pre>\n<p>\n<i>Not\u0103: exemplul de mai sus este prezentat \u00eentr-o form\u0103 scurt\u0103 pentru a ilustra ideea general\u0103.<\/i><\/p>\n<p>Aici am ad\u0103ugat \u00een desf\u0103\u0219urarea noastr\u0103 variabila de mediu NPM_RUN, care \u00eei spune etapelor de execu\u021bie s\u0103 ruleze comanda yarn start, care porne\u0219te serverul de dezvoltare React \u00een interiorul pod-ului nostru OpenShift.<\/p>\n<p>Dac\u0103 ne uit\u0103m \u00een log-ul pod-ului care ruleaz\u0103, acesta va ar\u0103ta aproximativ a\u0219a:<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/5b090223e08e32a3356608881068ce1a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Desigur, toate acestea nu vor conta p\u00e2n\u0103 nu putem sincroniza codul local cu codul, care este, de asemenea, monitorizat pentru modific\u0103ri, dar se afl\u0103 pe un server remote.<\/p>\n<h4>Sincronizarea codului remote \u0219i local<\/h4>\n<p>\nDin fericire, sincronizarea este simplificat\u0103 de nodeshift, iar pentru a urm\u0103ri modific\u0103rile, putem folosi comanda watch.<\/p>\n<p>A\u0219a c\u0103, dup\u0103 ce am executat comanda pentru desf\u0103\u0219urarea serverului de dezvoltare pentru aplica\u021bia noastr\u0103, putem s\u0103 folosim cu \u00eencredere aceast\u0103 comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift watch\n<\/code><\/pre>\n<p>\nCa rezultat, se va stabili o conexiune cu pod-ul care a fost creat anterior, se va activa sincronizarea fi\u0219ierelor noastre locale cu cluster-ul remote, iar fi\u0219ierele de pe sistemul nostru local vor \u00eencepe s\u0103 fie urm\u0103rite pentru modific\u0103ri.<\/p>\n<p>A\u0219adar, dac\u0103 acum actualiz\u0103m fi\u0219ierul src\/App.js, sistemul va reac\u021biona la aceste modific\u0103ri, le va copia pe cluster-ul remote \u0219i va porni serverul de dezvoltare, care va actualiza apoi aplica\u021bia noastr\u0103 \u00een browser.<\/p>\n<p>Pentru a completa imaginea, vom ar\u0103ta cum apar aceste comenzi \u00een \u00eentregime:<\/p>\n<pre><code class=\"plaintext\">$ 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\n\n$ npx nodeshift watch --strictSSL=false\n<\/code><\/pre>\n<p>\nComanda watch este o abstrac\u021bie deasupra comenzii oc rsync, po\u021bi afla mai multe despre cum func\u021bioneaz\u0103. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/copy_files_to_container.html\">aici<\/a><\/noindex>.<\/p>\n<p>Acesta a fost un exemplu pentru React, dar aceea\u0219i metod\u0103 poate fi utilizat\u0103 \u0219i cu alte framework-uri, doar specifica\u021bi corespunz\u0103tor variabila de mediu NPM_RUN.<br \/>\n\u2003<\/p>\n<h3>Pipelines OpenShift<\/h3>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/33b932d3591b22dd00d82509b352d489.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Mai departe, vom discuta despre un instrument numit OpenShift Pipelines \u0219i despre cum poate fi folosit ca o alternativ\u0103 la construc\u021bii legate de cha\u00eene.<\/p>\n<h4>Ce sunt OpenShift Pipelines<\/h4>\n<p>\nOpenShift Pipelines este un sistem CI\/CD orientat spre cloud pentru integrarea \u0219i livrarea continu\u0103, destinat organiz\u0103rii de conducte utiliz\u00e2nd Tekton. Tekton este un cadru CI\/CD flexibil \u0219i nativ Kubernetes, cu surs\u0103 deschis\u0103, care permite automatizarea desf\u0103\u0219ur\u0103rii pe diverse platforme (Kubernetes, serverless, ma\u0219ini virtuale etc.) prin abstractizarea nivelului de baz\u0103.<\/p>\n<p>Pentru a \u00een\u021belege acest articol, sunt necesare anumite cuno\u0219tin\u021be despre Pipelines, a\u0219adar v\u0103 recomand\u0103m cu t\u0103rie s\u0103 \u00eencepe\u021bi prin a citi <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\">manualul oficial<\/a><\/noindex>.<\/p>\n<h4>Configurarea mediului de lucru<\/h4>\n<p>\nPentru a experimenta cu exemplele din acest articol, trebuie mai \u00eent\u00e2i s\u0103 preg\u0103ti\u021bi mediul de lucru:<\/p>\n<ol>\n<li>Instala\u021bi \u0219i configura\u021bi un cluster OpenShift 4. \u00cen exemplele noastre, folosim CodeReady Containers (CRD), instruc\u021biunile de instalare pot fi g\u0103site <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.redhat.com\/openshift\/install\/crc\/installer-provisioned\">aici<\/a><\/noindex>.<\/li>\n<li>Dup\u0103 ce clusterul este gata, trebuie s\u0103 instala\u021bi Pipeline Operator. Nu v\u0103 face\u021bi griji, este simplu, instruc\u021biunile de instalare <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\/blob\/master\/install-operator.md\">aici<\/a><\/noindex>.<\/li>\n<li>Descarc\u0103 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">Tekton CLI<\/a><\/noindex> (tkn) <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">aici<\/a><\/noindex>.<\/li>\n<li>Rula\u021bi instrumentul de linie de comand\u0103 create-react-app pentru a crea o aplica\u021bie care va fi desf\u0103\u0219urat\u0103 ulterior (aceasta este o aplica\u021bie simpl\u0103 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\">React<\/a><\/noindex>).<\/li>\n<li>(Op\u021bional) Clonati repository-ul pentru a rula local exemplul aplica\u021biei cu comanda npm install \u0219i apoi npm start.<\/li>\n<\/ol>\n<p>\n\u00cen repository-ul aplica\u021biei va exista, de asemenea, un folder k8s, unde vor fi stocate YAML-urile Kubernetes\/OpenShift utilizate pentru desf\u0103\u0219urarea aplica\u021biei. Acolo vor fi Tasks, ClusterTasks, Resources \u0219i Pipelines pe care le vom crea \u00een acest <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">repository<\/a><\/noindex>.<\/p>\n<h4>S\u0103 \u00eencepem<\/h4>\n<p>\nMai \u00eent\u00e2i, pentru exemplul nostru, trebuie s\u0103 cre\u0103m un nou proiect \u00een clusterul OpenShift. Vom numi acest proiect webapp-pipeline \u0219i \u00eel vom crea cu urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ oc new-project webapp-pipeline\n<\/code><\/pre>\n<p>\nMai departe, acest nume de proiect va ap\u0103rea \u00een cod, a\u0219adar, dac\u0103 decide\u021bi s\u0103-l numi\u021bi altfel, nu uita\u021bi s\u0103 modifica\u021bi corespunz\u0103tor codul din exemple. \u00cencep\u00e2nd de aici, vom proceda de jos \u00een sus: mai \u00eent\u00e2i vom crea toate componentele conductei, iar apoi \u00eens\u0103\u0219i conducta.<\/p>\n<p>A\u0219a c\u0103, mai \u00eent\u00e2i\u2026<\/p>\n<h4>Tasks<\/h4>\n<p>\nVom crea dou\u0103 sarcini (tasks) care ne vor ajuta ulterior s\u0103 desf\u0103\u0219ur\u0103m aplica\u021bia \u00een cadrul pipeline-ului nostru. Prima sarcin\u0103 \u2013 apply_manifests_task \u2013 se ocup\u0103 cu aplicarea YAML-urilor resurselor Kubernetes (service, deployment \u0219i route) care se afl\u0103 \u00een folderul k8s al aplica\u021biei noastre. A doua sarcin\u0103 \u2013 update_deployment_task \u2013 se ocup\u0103 cu actualizarea imaginii deja desf\u0103\u0219urate la cea care este creat\u0103 de pipeline-ul nostru.<\/p>\n<p>Nu v\u0103 face\u021bi griji dac\u0103 nu este foarte clar pentru moment. De fapt, aceste sarcini sunt ceva de genul utilitare \u0219i le vom examina \u00een detaliu pu\u021bin mai t\u00e2rziu. Dar deocamdat\u0103 s\u0103 le cre\u0103m:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/update_deployment_task.yaml\n$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/apply_manifests_task.yaml\n<\/code><\/pre>\n<p>\nApoi, cu ajutorul comenzii tkn CLI, vom verifica dac\u0103 sarcinile au fost create:<\/p>\n<pre><code class=\"plaintext\">$ tkn task ls\n\nNAME                AGE\napply-manifests     1 minute ago\nupdate-deployment   1 minute ago\n<\/code><\/pre>\n<p>\n<i>Not\u0103: acestea sunt sarcini locale ale proiectului dumneavoastr\u0103 curent.<\/i><\/p>\n<h4>Sarcini de cluster Cluster tasks<\/h4>\n<p>\nSarcinile de cluster sunt, \u00een esen\u021b\u0103, acela\u0219i lucru cu sarcinile obi\u0219nuite. Adic\u0103, sunt o colec\u021bie reutilizabil\u0103 de pa\u0219i care sunt combina\u021bi \u00eentr-un fel sau altul la desf\u0103\u0219urarea unei sarcini specifice. Diferen\u021ba este c\u0103 sarcina de cluster este disponibil\u0103 oriunde \u00een cadrul clusterului. Pentru a vedea lista sarcinilor de cluster care sunt create automat la ad\u0103ugarea Operatorului Pipeline, vom folosi din nou comanda tkn CLI:<\/p>\n<pre><code class=\"plaintext\">$ tkn clustertask ls\n\nNAME                       AGE\nbuildah                    1 day ago\nbuildah-v0-10-0            1 day ago\njib-maven                  1 day ago\nkn                         1 day ago\nmaven                      1 day ago\nopenshift-client           1 day ago\nopenshift-client-v0-10-0   1 day ago\ns2i                        1 day ago\ns2i-go                     1 day ago\ns2i-go-v0-10-0             1 day ago\ns2i-java-11                1 day ago\ns2i-java-11-v0-10-0        1 day ago\ns2i-java-8                 1 day ago\ns2i-java-8-v0-10-0         1 day ago\ns2i-nodejs                 1 day ago\ns2i-nodejs-v0-10-0         1 day ago\ns2i-perl                   1 day ago\ns2i-perl-v0-10-0           1 day ago\ns2i-php                    1 day ago\ns2i-php-v0-10-0            1 day ago\ns2i-python-3               1 day ago\ns2i-python-3-v0-10-0       1 day ago\ns2i-ruby                   1 day ago\ns2i-ruby-v0-10-0           1 day ago\ns2i-v0-10-0                1 day ago\n<\/code><\/pre>\n<p>\nAcum s\u0103 cre\u0103m dou\u0103 sarcini de cluster. Prima va genera o imagine S2I \u0219i o va trimite \u00een registrul intern OpenShift; a doua va construi imaginea noastr\u0103 bazat\u0103 pe NGINX, folosind ca \u0219i con\u021binut aplica\u021bia pe care am construit-o anterior.<\/p>\n<h4>Cre\u0103m \u0219i trimitem imaginea<\/h4>\n<p>\nC\u00e2nd cre\u0103m prima sarcin\u0103, vom repeta ceea ce am f\u0103cut deja \u00een articolul anterior despre construirea legat\u0103. Reamintim c\u0103 am folosit imaginea S2I (ubi8-s2i-web-app) pentru a \u201econstrui\u201d aplica\u021bia noastr\u0103, iar \u00een cele din urm\u0103 am ob\u021binut o imagine stocat\u0103 \u00een registrul intern OpenShift. Acum vom folosi aceast\u0103 imagine S2I a aplica\u021biei web pentru a crea un DockerFile pentru aplica\u021bia noastr\u0103, iar apoi vom folosi Buildah pentru a efectua construc\u021bia real\u0103 \u0219i a trimite imaginea ob\u021binut\u0103 \u00een registrul intern OpenShift, deoarece aceasta este ceea ce face OpenShift atunci c\u00e2nd desf\u0103\u0219ura\u021bi aplica\u021biile folosind NodeShift.<\/p>\n<p>\u00centreba\u021bi de unde am aflat toate acestea? Din <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-catalog\/blob\/master\/s2i-nodejs\/s2i-nodejs-task.yaml\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 official Node.js<\/a><\/noindex>, am copiat-o pur \u0219i simplu \u0219i am adaptat-o pentru nevoile noastre.<\/p>\n<p>A\u0219a c\u0103, s\u0103 cre\u0103m acum sarcina cluster s2i-web-app:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/s2i-web-app-task.yaml\n<\/code><\/pre>\n<p>\nNu vom detalia acest lucru, ci ne vom opri doar asupra parametrului OUTPUT_DIR:<\/p>\n<pre><code class=\"plaintext\">params:\n      - name: OUTPUT_DIR\n        description: Locul directorului de ie\u0219ire al construc\u021biei\n        default: build\n<\/code><\/pre>\n<p>\n\u00cen mod implicit, acest parametru este setat pe build, exact acolo unde React salveaz\u0103 con\u021binutul construit. Alte cadre folosesc alte c\u0103i; de exemplu, \u00een Ember este dist. Iesirea primei noastre sarcini de cluster va consta \u00eentr-o imagine care con\u021bine HTML, JavaScript \u0219i CSS-urile construite de noi.<\/p>\n<h4>Construim o imagine pe baz\u0103 de NGINX<\/h4>\n<p>\n\u00cen ceea ce prive\u0219te a doua noastr\u0103 sarcin\u0103 de cluster, aceasta ar trebui s\u0103 construiasc\u0103 o imagine bazat\u0103 pe NGINX, folosind con\u021binutul deja construit de noi. Practic, aceasta este partea din sec\u021biunea anterioar\u0103 \u00een care am discutat despre construc\u021biile legate (chained builds).<\/p>\n<p>Pentru aceasta, vom crea, exact ca mai sus, o sarcin\u0103 de cluster webapp-build-runtime:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/webapp-build-runtime-task.yaml\n<\/code><\/pre>\n<p>\nDac\u0103 observ\u0103m codul acestor sarcini de cluster, se poate observa c\u0103 nu se specific\u0103 depozitul Git cu care lucr\u0103m sau numele imaginilor pe care le cre\u0103m. Noi doar stabilim ce anume transmitem \u00een Git sau o anumit\u0103 imagine \u00een care trebuie s\u0103 ie\u0219im cu imaginea final\u0103. De aceea, aceste sarcini de cluster pot fi reutilizate \u0219i pentru alte aplica\u021bii.<\/p>\n<p>\u0218i aici trecem elegant la urm\u0103torul punct...<\/p>\n<h4>Resurse<\/h4>\n<p>\nA\u0219adar, deoarece, dup\u0103 cum am spus, sarcinile de cluster trebuie s\u0103 fie c\u00e2t mai generalizate, trebuie s\u0103 cre\u0103m resurse care vor fi utilizate la intrare (repository Git) \u0219i la ie\u0219ire (imaginea final\u0103). Prima resurs\u0103 de care avem nevoie este Git, unde se afl\u0103 aplica\u021bia noastr\u0103, ceva de genul acesta:<\/p>\n<pre><code class=\"plaintext\"># This resource is the location of the git repo with the web application source\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: web-application-repo\nspec:\n  type: git\n  params:\n    - name: url\n      value: https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\n    - name: revision\n      value: master\n<\/code><\/pre>\n<p>\nAici, PipelineResource are tipul git. Cheia url din sec\u021biunea params indic\u0103 spre repository-ul specific \u0219i stabile\u0219te ramura master (aceasta este op\u021bional\u0103, dar o men\u021bion\u0103m pentru completitudine).<\/p>\n<p>Acum trebuie s\u0103 cre\u0103m o resurs\u0103 pentru imagine, unde vor fi salvate rezultatele execu\u021biei sarcinii s2i-web-app, acest lucru se face astfel:<\/p>\n<pre><code class=\"plaintext\"># This resource is the result of running &quot;npm run build&quot;,  the resulting built files will be located in \/opt\/app-root\/output\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: built-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/built-web-application:latest\n<\/code><\/pre>\n<p>\nAici, PipelineResource are tipul image, iar valoarea parametrului url indic\u0103 spre Registrul de Imagini OpenShift intern, mai exact cel care se afl\u0103 \u00een spa\u021biul de nume webapp-pipeline. Nu uita\u021bi s\u0103 schimba\u021bi acest parametru dac\u0103 utiliza\u021bi un alt spa\u021biu de nume.<\/p>\n<p>\u0218i, \u00een cele din urm\u0103, ultima resurs\u0103 de care vom avea nevoie va avea de asemenea tipul image \u0219i aceasta va fi imaginea final\u0103 NGINX, care va fi utilizat\u0103 ulterior la desf\u0103\u0219urare:<\/p>\n<pre><code class=\"plaintext\"># This resource is the image that will be just the static html, css, js files being run with nginx\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: runtime-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/runtime-web-application:latest\n<\/code><\/pre>\n<p>\nRe\u021bine\u021bi din nou c\u0103 aceast\u0103 resurs\u0103 salveaz\u0103 imaginea \u00een registrul intern OpenShift din spa\u021biul de nume webapp-pipeline.<\/p>\n<p>Pentru a crea toate aceste resurse deodat\u0103, vom folosi comanda create:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/resources\/resource.yaml\n<\/code><\/pre>\n<p>\nPentru a verifica dac\u0103 resursele au fost create, se poate face astfel:<\/p>\n<pre><code class=\"plaintext\">$ tkn resource ls\n<\/code><\/pre>\n<p><\/p>\n<h4>Conveyer pipeline<\/h4>\n<p>\nAcum, c\u00e2nd avem toate componentele necesare, s\u0103 construim conveyorul folosind urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/pipelines\/build-and-deploy-react.yaml\n<\/code><\/pre>\n<p>\nDar, \u00eenainte de a rula aceast\u0103 comand\u0103, s\u0103 detaliem aceste componente. Prima este numele:<\/p>\n<pre><code class=\"plaintext\">apiVersion: tekton.dev\/v1alpha1\nkind: Pipeline\nmetadata:\n  name: build-and-deploy-react\n<\/code><\/pre>\n<p>\nApoi, \u00een sec\u021biunea spec, vedem specificarea resurselor pe care le-am creat anterior:<\/p>\n<pre><code class=\"plaintext\">spec:\n  resources:\n    - name: web-application-repo\n      type: git\n    - name: built-web-application-image\n      type: image\n    - name: runtime-web-application-image\n      type: image\n<\/code><\/pre>\n<p>\nApoi cre\u0103m sarcinile pe care trebuie s\u0103 le execute conveyorul nostru. \u00cen primul r\u00e2nd, trebuie s\u0103 efectueze sarcina s2i-web-app pe care am creat-o anterior:<\/p>\n<pre><code class=\"plaintext\">tasks:\n    - name: build-web-application\n      taskRef:\n        name: s2i-web-app\n        kind: ClusterTask\n<\/code><\/pre>\n<p>\nAceast\u0103 sarcin\u0103 preia parametrii de intrare (resursa gir) \u0219i ie\u0219ire (resursa built-web-application-image). De asemenea, \u00eei transmitem un parametru special pentru a nu verifica TLS, deoarece folosim certificate auto-semnate:<\/p>\n<pre><code class=\"plaintext\">resources:\n        inputs:\n          - name: source\n            resource: web-application-repo\n        outputs:\n          - name: image\n            resource: built-web-application-image\n      params:\n        - name: TLSVERIFY\n          value: \"false\"\n<\/code><\/pre>\n<p>\nUrm\u0103toarea sarcin\u0103 este aproape identic\u0103, doar c\u0103 aici se apeleaz\u0103 sarcina cluster creat\u0103 de noi webapp-build-runtime:<\/p>\n<pre><code class=\"plaintext\">nume: build-runtime-image\n    taskRef:\n      nume: webapp-build-runtime\n      tip: ClusterTask\n<\/code><\/pre>\n<p>\nLa fel ca \u00een sarcina anterioar\u0103, transmitem resursa, dar acum aceasta este built-web-application-image (ie\u0219irea sarcinii noastre anterioare). \u0218i ca ie\u0219ire, iar\u0103\u0219i definim o imagine. Fiindc\u0103 aceast\u0103 sarcin\u0103 trebuie s\u0103 fie executat\u0103 dup\u0103 cea anterioar\u0103, ad\u0103ug\u0103m c\u00e2mpul runAfter:<\/p>\n<pre><code class=\"plaintext\">resources:\n        inputs:\n          - name: image\n            resource: built-web-application-image\n        outputs:\n          - name: image\n            resource: runtime-web-application-image\n        params:\n        - name: TLSVERIFY\n          value: \"false\"\n      runAfter:\n        - build-web-application\n<\/code><\/pre>\n<p>\nUrm\u0103toarele dou\u0103 sarcini se ocup\u0103 de aplicarea fi\u0219ierelor YAML pentru serviciu, rut\u0103 \u0219i desf\u0103\u0219urare, care se afl\u0103 \u00een directorul k8s al aplica\u021biei noastre web, precum \u0219i de actualizarea acestei desf\u0103\u0219ur\u0103ri atunci c\u00e2nd se creeaz\u0103 imagini noi. Aceste dou\u0103 sarcini cluster le-am definit la \u00eenceputul articolului.<\/p>\n<h4>Pornirea conductorului<\/h4>\n<p>\nA\u0219adar, toate p\u0103r\u021bile conductei noastre sunt create \u0219i o vom porni cu urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline start build-and-deploy-react\n<\/code><\/pre>\n<p>\n\u00cen aceast\u0103 etap\u0103, linia de comand\u0103 este utilizat\u0103 \u00een mod interactiv \u0219i trebuie s\u0103 select\u0103m resursele corespunz\u0103toare ca r\u0103spuns la fiecare solicitare: pentru resursa git alegem web-application-repo, apoi pentru resursa primei imagini \u2013 built-web-application-image, iar \u00een final, pentru resursa celei de-a doua imagini \u2013 runtime-web-application-image:<\/p>\n<pre><code class=\"plaintext\">? Choose the git resource to use for web-application-repo: web-application-repo (https:\/\/github.com\/nodeshift-starters\/react-pipeline-example)\n? 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-\napplication:latest)\n? 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\ne-web-application:latest)\nPipelinerun started: build-and-deploy-react-run-4xwsr\n<\/code><\/pre>\n<p>\nAcum s\u0103 verific\u0103m starea conductei folosind urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline logs -f\n<\/code><\/pre>\n<p>\nDup\u0103 ce conducta a fost pornit\u0103 \u0219i aplica\u021bia a fost desf\u0103\u0219urat\u0103, vom solicita ruta publicat\u0103 cu urm\u0103toarea comand\u0103:<\/p>\n<pre><code class=\"plaintext\">$ oc get route react-pipeline-example --template='http:\/\/{{.spec.host}}'\n<\/code><\/pre>\n<p>\nPentru o vizualizare mai bun\u0103, putem vedea conducta noastr\u0103 \u00een modul Developer al consolei web \u00een sec\u021biunea <b>Pipeline-uri<\/b>, a\u0219a cum este ar\u0103tat \u00een Fig. 1.<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/ede9b076414e389c2cd212adeda08956.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig.1. O privire de ansamblu asupra conductelor \u00een execu\u021bie.<\/i><\/p>\n<p>Un clic pe conducta \u00een execu\u021bie afi\u0219eaz\u0103 informa\u021bii suplimentare, a\u0219a cum se arat\u0103 \u00een Fig. 2.<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/64581b1f6d8ff91aedd963019ef29be5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig. 2. Informa\u021bii suplimentare despre conducta.<\/i><\/p>\n<p>Dup\u0103 informa\u021biile suplimentare, putem vizualiza aplica\u021biile \u00een execu\u021bie \u00een cadrul <b>Topologie<\/b>, a\u0219a cum este ar\u0103tat \u00een Fig.3.<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/d23f723e14514ff60ecfddd8eb9bf752.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig 3. Pod \u00een execu\u021bie.<\/i><\/p>\n<p>Un clic pe cercule\u021bul din col\u021bul din dreapta sus al pictogramei deschide aplica\u021bia noastr\u0103, a\u0219a cum este ar\u0103tat \u00een Fig.4.<\/p>\n<p><img decoding=\"async\" alt=\"Aplica\u021bii moderne \u00een OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i canale OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/aa8e09d9fd9f33d5faffc7f661d84ca4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig. 4. Aplica\u021bia React \u00een execu\u021bie.<\/i><\/p>\n<h3>Concluzie<\/h3>\n<p>\nA\u0219adar, am ar\u0103tat cum s\u0103 lansezi un server de dezvoltare pentru aplica\u021bia ta pe OpenShift \u0219i cum s\u0103-l sincronizezi cu sistemul de fi\u0219iere local. De asemenea, am discutat despre cum s\u0103 simulezi un template de tip chained-build folosind OpenShift Pipelines. Tot codul exemplelor din acest articol poate fi g\u0103sit <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">aici<\/a><\/noindex>.<\/p>\n<h3>Resurse suplimentare (EN)<\/h3>\n<p><\/p>\n<ul>\n<li>Carte electronic\u0103 gratuit\u0103 <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\/\">\u201eDezvoltare pe OpenShift: un ghid pentru ner\u0103bd\u0103tori\u201d<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/06\/11\/container-native-nodejs-istio-rhoar\/\">Construirea aplica\u021biilor containerizate Node.js utiliz\u00e2nd Red Hat OpenShift Application Runtimes \u0219i Istio<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/05\/15\/debug-your-node-js-application-on-openshift-with-chrome-devtools\/\">Debugging aplica\u021biilor Node.js pe OpenShift cu Chrome DevTools<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/04\/16\/zero-express-openshift-3-commands\/\">Trei comenzi pentru a st\u0103p\u00e2ni Express pe OpenShift de la zero<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/03\/12\/rhoar-nodejs-annoucement\/\">Anun\u021bul versiunii publice Node.js ca parte a Red Hat OpenShift Application Runtimes<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/12\/21\/monitoring-node-js-applications-on-openshift-with-prometheus\/\">Monitorizarea aplica\u021biilor Node.js pe OpenShift cu Prometheus<\/a><\/noindex><\/li>\n<li>Alte articole despre <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift \u0219i Kubernetes<\/a><\/noindex> pe site-ul Red Hat<\/li>\n<\/ul>\n<h3>Anun\u021buri pentru webinarii viitoare<\/h3>\n<p>\n\u00cencepem o serie de webinare de vineri despre experien\u021ba nativ\u0103 cu Red Hat OpenShift Container Platform \u0219i Kubernetes:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232599abcd&amp;sc_cid=7013a000002gwqQAAQ\"><b>28 august, webinar \u00cemp\u0103ratul \u201eOperator\u201d: Operatori \u00een OpenShift \u0219i Kubernetes<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232694abcd&amp;sc_cid=7013a000002gwrdAAA\"><b>11 septembrie, DeploymentConfig vs Deployment \u2013 lucruri magice specifice OpenShift pentru construirea \u0219i desf\u0103\u0219urarea aplica\u021biilor<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232789abcd&amp;sc_cid=7013a000002gws7AAA\"><b>25 septembrie, Red Hat OpenShift \u0219i Machine API<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232884abcd&amp;sc_cid=7013a000002gwsqAAA\"><b>9 octombrie, Cum s\u0103 faci fa\u021b\u0103 unei cre\u0219teri bru\u0219te a \u00eenc\u0103rc\u0103rii<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232979abcd&amp;sc_cid=7013a000002gwumAAA\"><b>23 octombrie, Jenkins \u00eencorporat, Pipeline-builds, Tekton \u00een Red Hat OpenShift Container Platform<\/b><\/a><\/noindex><\/li>\n<\/ul>\n<p>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/515988\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435! \u0421 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Red Hat OpenShift. \u0412 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0433\u043e\u0432 \u0438 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 S2I \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c HTTP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, NGINX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043e\u043a chained [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92049,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92048","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-22T05:42:57+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-22T05:42:57+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Aplica\u021bii moderne pe OpenShift, partea 3: OpenShift ca mediu de dezvoltare \u0219i conveioare OpenShift Pipelines | ProHoster","description":"Salutare tuturor \u00een acest blog!","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-22T05:42:57+00:00","article:modified_time":"2020-08-22T05:42:57+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92048","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:16:43","updated":"2022-10-02 02:53:55","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/92048","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=92048"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/92048\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/92049"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=92048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=92048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=92048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}