Aplicații moderne pe OpenShift, partea 2: versiuni înlănțuite

Salutare tuturor! Aceasta este a doua postare din seria noastră în care arătăm cum să implementăm aplicații web moderne pe Red Hat OpenShift.

Aplicații moderne pe OpenShift, partea 2: versiuni înlănțuite

În postarea anterioară, am atins ușor capacitățile noii imagini de constructor S2I (sursă la imagine), care este concepută pentru construirea și implementarea aplicațiilor web moderne pe platforma OpenShift. Atunci ne-a interesat subiectul implementării rapide a unei aplicații, iar astăzi vom analiza cum să folosim o imagine S2I ca imagine de constructor „pură” și să o combinăm cu ansamblurile OpenShift aferente.

Imagine curată a constructorului

După cum am menționat în partea XNUMX, cele mai multe aplicații web moderne au o așa-numită etapă de construcție, care efectuează de obicei operațiuni precum transpilarea codului, concatenarea mai multor fișiere și minificarea. Fișierele obținute în urma acestor operațiuni - și acesta este HTML static, JavaScript și CSS - sunt stocate în folderul de ieșire. Locația acestui folder depinde de obicei de ce instrumente de compilare sunt utilizate, iar pentru React acesta va fi folderul ./build (vom reveni la asta mai detaliat mai jos).

De la sursă la imagine (S2I)

În această postare nu atingem subiectul „ce este S2I și cum să-l folosești” (puteți citi mai multe despre aceasta aici), dar este important să fie clar cei doi pași din acest proces pentru a înțelege ce face o imagine Web App Builder.

Faza de asamblare

Faza de asamblare este foarte similară ca natură cu ceea ce se întâmplă atunci când rulați docker build și ajungeți la o nouă imagine Docker. În consecință, această etapă are loc atunci când începeți o construcție pe platforma OpenShift.

În cazul unei imagini Web App Builder, acesta este responsabil pentru instalarea dependențelor aplicației dvs. și pentru rularea versiunii. asambla scriptul. În mod implicit, imaginea constructorului folosește construcția npm run build, dar aceasta poate fi suprascrisă prin variabila de mediu NPM_BUILD.

După cum am spus mai devreme, locația aplicației terminate, deja construite, depinde de ce instrumente utilizați. De exemplu, în cazul lui React acesta va fi folderul ./build, iar pentru aplicațiile Angular va fi folderul project_name/dist. Și, așa cum s-a arătat deja în postarea anterioară, locația directorului de ieșire, care este setată să fie construită implicit, poate fi suprascrisă prin variabila de mediu OUTPUT_DIR. Ei bine, deoarece locația folderului de ieșire diferă de la cadru la cadru, pur și simplu copiați rezultatul generat în folderul standard din imagine, și anume /opt/apt-root/output. Acest lucru este important pentru înțelegerea restului acestui articol, dar deocamdată să ne uităm rapid la următoarea etapă - faza de rulare.

faza de rulare

Această etapă are loc atunci când se efectuează un apel către rularea docker pe noua imagine creată în timpul etapei de asamblare. Același lucru se întâmplă și la implementarea pe platforma OpenShift. Mod implicit rulați scriptul utilizări modul de servire pentru a servi conținut static situat în directorul de ieșire standard de mai sus.

Această metodă este bună pentru implementarea rapidă a aplicațiilor, dar, în general, nu este recomandat să difuzați conținut static în acest fel. Ei bine, deoarece în realitate servim doar conținut static, nu avem nevoie de Node.js instalat în imaginea noastră - un server web va fi suficient.

Cu alte cuvinte, la asamblare avem nevoie de un lucru, la execuție avem nevoie de altul. În această situație, construcțiile înlănțuite sunt utile.

Construcții înlănțuite

Despre asta scriu ei construcții înlănțuite în documentația OpenShift:

„Două ansambluri pot fi legate împreună, unul generând o entitate compilată, iar celălalt găzduind acea entitate într-o imagine separată care este utilizată pentru a rula acea entitate.”

Cu alte cuvinte, putem folosi imaginea Web App Builder pentru a rula construcția noastră și apoi folosim imaginea serverului web, același NGINX, pentru a ne difuza conținutul.

Astfel, putem folosi imaginea Web App Builder ca un constructor „pur” și, în același timp, avem o imagine mică de rulare.

Acum să ne uităm la asta cu un exemplu specific.

Pentru antrenament vom folosi aplicație simplă React, creat folosind instrumentul de linie de comandă create-react-app.

Ne va ajuta să punem totul împreună Fișier șablon OpenShift.

Să ne uităm la acest fișier mai detaliat și să începem cu secțiunea de parametri.

parameters:
  - name: SOURCE_REPOSITORY_URL
    description: The source URL for the application
    displayName: Source URL
    required: true
  - name: SOURCE_REPOSITORY_REF
    description: The branch name for the application
    displayName: Source Branch
    value: master
    required: true
  - name: SOURCE_REPOSITORY_DIR
    description: The location within the source repo of the application
    displayName: Source Directory
    value: .
    required: true
  - name: OUTPUT_DIR
    description: The location of the compiled static files from your web apps builder
    displayName: Output Directory
    value: build
    required: false

Totul aici este destul de clar, dar merită să acordați atenție parametrului OUTPUT_DIR. Pentru aplicația React din exemplul nostru, nu este nimic de care să vă faceți griji, deoarece React folosește valoarea implicită ca folder de ieșire, dar în cazul Angular sau altceva, acest parametru va trebui modificat după cum este necesar.

Acum să aruncăm o privire la secțiunea ImageStreams.

- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-builder  // 1 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-runtime  // 2 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: web-app-builder-runtime // 3
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: nodeshift/ubi8-s2i-web-app:10.x
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: nginx-image-runtime // 4
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: 'centos/nginx-112-centos7:latest'

Aruncă o privire la a treia și a patra imagine. Ambele sunt definite ca imagini Docker și puteți vedea clar de unde provin.

A treia imagine este web-app-builder și vine de la nodeshift/ubi8-s2i-web-app etichetat 10.x pe Hub Docker.

A patra este o imagine NGINX (versiunea 1.12) cu cea mai recentă etichetă activată Hub Docker.

Acum să ne uităm la primele două imagini. Ambele sunt goale la început și sunt create numai în faza de construire. Prima imagine, react-web-app-builder, va fi rezultatul unui pas de asamblare care va combina imaginea web-app-builder-runtime și codul nostru sursă. De aceea am adăugat „-builder” la numele acestei imagini.

A doua imagine - react-web-app-runtime - va fi rezultatul combinării nginx-image-runtime și a unor fișiere din imaginea react-web-app-builder. Această imagine va fi folosită și în timpul implementării și va conține doar serverul web și HTML static, JavaScript, CSS al aplicației noastre.

Confuz? Acum să aruncăm o privire la configurațiile de construcție și va deveni puțin mai clar.

Șablonul nostru are două configurații de construcție. Iată primul și este destul de standard:

  apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-builder
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-builder:latest // 1
    source:   // 2 
      git:
        uri: ${SOURCE_REPOSITORY_URL}
        ref: ${SOURCE_REPOSITORY_REF}
      contextDir: ${SOURCE_REPOSITORY_DIR}
      type: Git
    strategy:
      sourceStrategy:
        env:
          - name: OUTPUT_DIR // 3 
            value: ${OUTPUT_DIR}
        from:
          kind: ImageStreamTag
          name: web-app-builder-runtime:latest // 4
        incremental: true // 5
      type: Source
    triggers: // 6
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - imageChange: {}
      type: ImageChange

După cum puteți vedea, linia cu eticheta 1 spune că rezultatul acestei build va fi plasat în aceeași imagine react-web-app-builder pe care am văzut-o puțin mai devreme în secțiunea ImageStreams.

Linia etichetată 2 vă spune de unde să obțineți codul. În cazul nostru, acesta este un depozit git, iar locația, ref și folderul context sunt determinate de parametrii pe care i-am văzut deja mai sus.

Linia etichetată 3 este ceea ce am văzut deja în secțiunea de parametri. Se adaugă variabila de mediu OUTPUT_DIR, care în exemplul nostru este build.
Linia etichetată 4 spune să folosiți imaginea web-app-builder-runtime, pe care am văzut-o deja în secțiunea ImageStream.

Linia etichetată 5 spune că vrem să folosim o construcție incrementală dacă imaginea S2I o acceptă, iar imaginea Web App Builder o acceptă. La prima lansare, după finalizarea etapei de asamblare, imaginea va salva folderul node_modules într-un fișier de arhivă. Apoi, la rulările ulterioare, imaginea va dezarhiva pur și simplu acest folder pentru a reduce timpul de construire.

Și, în sfârșit, linia etichetată 6 este doar câteva declanșatoare pentru a face construirea să ruleze automat, fără intervenție manuală, atunci când ceva se schimbă.

În general, aceasta este o configurație de construcție destul de standard.

Acum să aruncăm o privire la a doua configurație de construcție. Este foarte asemănător cu primul, dar există o diferență importantă.

apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-runtime
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-runtime:latest // 1
    source: // 2
      type: Image
      images:                              
        - from:
            kind: ImageStreamTag
            name: react-web-app-builder:latest // 3
          paths:
            - sourcePath: /opt/app-root/output/.  // 4
              destinationDir: .  // 5
             
    strategy: // 6
      sourceStrategy:
        from:
          kind: ImageStreamTag
          name: nginx-image-runtime:latest
        incremental: true
      type: Source
    triggers:
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - type: ImageChange
      imageChange: {}
    - type: ImageChange
      imageChange:
        from:
          kind: ImageStreamTag
          name: react-web-app-builder:latest // 7

Deci, a doua configurație de compilare este react-web-app-runtime și începe destul de standard.

Linia etichetată 1 nu este nimic nou - spune pur și simplu că rezultatul construcției este pus în imaginea react-web-app-runtime.

Linia etichetată 2, ca în configurația anterioară, indică de unde să obțineți codul sursă. Dar observați că aici spunem că este luat din imagine. Mai mult, din imaginea pe care tocmai am creat-o - din react-web-app-builder (indicată în rândul etichetat 3). Fișierele pe care vrem să le folosim sunt în interiorul imaginii și locația lor acolo este setată în linia etichetată 4, în cazul nostru este /opt/app-root/output/. Dacă vă amintiți, aici sunt stocate fișierele generate pe baza rezultatelor construirii aplicației noastre.

Dosarul de destinație specificat în termenul cu eticheta 5 este pur și simplu directorul curent (acesta este tot, amintiți-vă, rulează în interiorul unui lucru magic numit OpenShift, și nu pe computerul dvs. local).

Secțiunea de strategie – linia etichetată 6 – este, de asemenea, similară cu prima configurație de construcție. Doar că de data aceasta vom folosi nginx-image-runtime, pe care l-am văzut deja în secțiunea ImageStream.

În cele din urmă, linia etichetată 7 este o secțiune de declanșatoare care va activa această construcție de fiecare dată când imaginea react-web-app-builder se schimbă.

În caz contrar, acest șablon conține o configurație de implementare destul de standard, precum și lucruri care se referă la servicii și rute, dar nu vom intra în prea multe detalii. Vă rugăm să rețineți că imaginea care va fi implementată este imaginea react-web-app-runtime.

Implementarea aplicației

Deci, acum că ne-am uitat la șablon, să vedem cum să-l folosim pentru a implementa o aplicație.

Putem folosi instrumentul client OpenShift numit oc pentru a implementa șablonul nostru:

$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f

$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https://github.com/lholmquist/react-web-app

Prima comandă din captura de ecran de mai sus este o modalitate deliberată de inginerie de a găsi un șablon./openshiftio/application.yaml.

A doua comandă creează pur și simplu o nouă aplicație bazată pe acest șablon.

După ce aceste comenzi funcționează, vom vedea că avem două ansambluri:

Aplicații moderne pe OpenShift, partea 2: versiuni înlănțuite

Și revenind la ecranul Prezentare generală, vom vedea podul lansat:

Aplicații moderne pe OpenShift, partea 2: versiuni înlănțuite

Faceți clic pe link și vom fi direcționați la aplicația noastră, care este pagina implicită a aplicației React:

Aplicații moderne pe OpenShift, partea 2: versiuni înlănțuite

Supliment 1

Pentru iubitorii de Angular avem și exemplu de aplicație.

Modelul de aici este același, cu excepția variabilei OUTPUT_DIR.

Supliment 2

În acest articol am folosit NGINX ca server web, dar este destul de ușor să îl înlocuim cu Apache, doar schimbați șablonul din fișier Imagine NGINX pe Imagine Apache.

Concluzie

În prima parte a acestei serii, am arătat cum să implementăm rapid aplicații web moderne pe platforma OpenShift. Astăzi ne-am uitat la ce face o imagine de aplicație web și cum poate fi combinată cu un server web pur precum NGINX folosind versiuni înlănțuite pentru a crea o versiune de aplicație mai pregătită pentru producție. În următorul și ultimul articol din această serie, vom arăta cum să rulezi un server de dezvoltare pentru aplicația ta pe OpenShift și să asigurăm sincronizarea fișierelor locale și la distanță.

Conținutul acestei serii de articole

  • Partea 1: cum să implementați aplicații web moderne în doar câțiva pași;
  • Partea 2: Cum să utilizați o nouă imagine S2I cu o imagine de server HTTP existentă, cum ar fi NGINX, folosind ansambluri OpenShift asociate pentru implementarea în producție;
  • Partea 3: cum să rulați un server de dezvoltare pentru aplicația dvs. pe platforma OpenShift și să îl sincronizați cu sistemul de fișiere local.

Resurse aditionale

Sursa: www.habr.com

Adauga un comentariu